Sound Byte Libs 1ee2ca6
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
method_detection.hpp
Go to the documentation of this file.
1/**
2 * @file method_detection.hpp
3 * @brief Method and interface detection for driver validation
4 * @ingroup validation
5 *
6 * Uses C++17 SFINAE (Substitution Failure Is Not An Error) to detect what methods
7 * drivers provide at compile-time. This enables comprehensive driver contract
8 * validation with clear error messages.
9 *
10 * ## SFINAE Pattern
11 *
12 * All detection uses the consistent std::void_t pattern:
13 * ```cpp
14 * template<typename T, typename = void>
15 * struct has_method : std::false_type {};
16 *
17 * template<typename T>
18 * struct has_method<T, std::void_t<decltype(T::method(...))>>
19 * : std::true_type {};
20 * ```
21 *
22 * @see gpio_requirements.hpp
23 */
24
25#ifndef SBL_VALIDATION_METHOD_DETECTION_HPP_
26#define SBL_VALIDATION_METHOD_DETECTION_HPP_
27
28#include <type_traits>
29#include <cstdint>
30#include <cstddef>
31
32// Include canonical HAL types
36#include <sbl/hal/adc/types.hpp>
38
39namespace sbl {
40namespace validation {
41
42/**
43 * @brief GPIO Driver Method Detection (Handle-First API)
44 *
45 * Detects presence of required methods in GPIO driver implementations.
46 * All GPIO drivers must implement:
47 * - set_mode(const GpioHandle&, PinMode)
48 * - write(const GpioHandle&, bool)
49 * - read(const GpioHandle&) -> bool
50 * - toggle(const GpioHandle&)
51 */
52
53// Detect: static void set_mode(const GpioHandle&, PinMode)
54template<typename T, typename = void>
55struct has_gpio_set_mode : std::false_type {};
56
57template<typename T>
58struct has_gpio_set_mode<T, std::void_t<decltype(
59 T::set_mode(std::declval<const sbl::GpioHandle&>(),
60 std::declval<sbl::core::hal::gpio::PinMode>()))>>
61 : std::true_type {};
62
63// Detect: static void write(const GpioHandle&, bool)
64template<typename T, typename = void>
65struct has_gpio_write : std::false_type {};
66
67template<typename T>
68struct has_gpio_write<T, std::void_t<decltype(
69 T::write(std::declval<const sbl::GpioHandle&>(),
70 std::declval<bool>()))>>
71 : std::true_type {};
72
73// Detect: static bool read(const GpioHandle&)
74template<typename T, typename = void>
75struct has_gpio_read : std::false_type {};
76
77template<typename T>
78struct has_gpio_read<T, std::void_t<decltype(
79 T::read(std::declval<const sbl::GpioHandle&>()))>>
80 : std::true_type {};
81
82// Detect: static void toggle(const GpioHandle&)
83template<typename T, typename = void>
84struct has_gpio_toggle : std::false_type {};
85
86template<typename T>
87struct has_gpio_toggle<T, std::void_t<decltype(
88 T::toggle(std::declval<const sbl::GpioHandle&>()))>>
89 : std::true_type {};
90
91/**
92 * @brief Combined GPIO driver interface check
93 *
94 * True if driver implements all required handle-first GPIO methods.
95 */
96template<typename GpioDriver>
104
105/**
106 * @brief Timer Driver Method Detection
107 *
108 * Detects presence of required methods in Timer driver implementations.
109 */
110
111// Detect: static void delay_ms(uint32_t)
112template<typename T, typename = void>
113struct has_timer_delay_ms : std::false_type {};
114
115template<typename T>
116struct has_timer_delay_ms<T, std::void_t<decltype(
117 T::delay_ms(std::declval<uint32_t>()))>>
118 : std::true_type {};
119
120// Detect: static uint32_t millis()
121template<typename T, typename = void>
122struct has_timer_millis : std::false_type {};
123
124template<typename T>
125struct has_timer_millis<T, std::void_t<decltype(T::millis())>>
126 : std::true_type {};
127
128/**
129 * @brief UART Driver Method Detection
130 *
131 * Detects presence of required methods in UART driver implementations.
132 * UART drivers must implement:
133 * - init(const UartHandle&)
134 * - write_byte(uint8_t byte)
135 * - write(const uint8_t* data, size_t len)
136 */
137
138// Detect: static void init(const UartHandle&)
139template<typename T, typename = void>
140struct has_uart_init : std::false_type {};
141
142template<typename T>
143struct has_uart_init<T, std::void_t<decltype(
144 T::init(std::declval<const sbl::UartHandle&>()))>>
145 : std::true_type {};
146
147// Detect: static void write_byte(uint8_t)
148template<typename T, typename = void>
149struct has_uart_write_byte : std::false_type {};
150
151template<typename T>
152struct has_uart_write_byte<T, std::void_t<decltype(
153 T::write_byte(std::declval<uint8_t>()))>>
154 : std::true_type {};
155
156// Detect: static void write(const uint8_t*, std::size_t)
157template<typename T, typename = void>
158struct has_uart_write : std::false_type {};
159
160template<typename T>
161struct has_uart_write<T, std::void_t<decltype(
162 T::write(std::declval<const uint8_t*>(),
163 std::declval<std::size_t>()))>>
164 : std::true_type {};
165
166/**
167 * @brief ADC Driver Method Detection
168 *
169 * Detects presence of required methods in ADC driver implementations.
170 * ADC drivers must implement:
171 * - init()
172 * - configure_channel(const AdcHandle&, SampleTime)
173 * - start_conversion(const AdcHandle&)
174 * - is_conversion_complete() -> bool
175 * - read_raw() -> uint16_t
176 * - resolution_bits() -> uint8_t (constexpr)
177 */
178
179// Detect: static void init()
180template<typename T, typename = void>
181struct has_adc_init : std::false_type {};
182
183template<typename T>
184struct has_adc_init<T, std::void_t<decltype(T::init())>>
185 : std::true_type {};
186
187// Detect: static void configure_channel(const AdcHandle&, SampleTime)
188template<typename T, typename = void>
189struct has_adc_configure_channel : std::false_type {};
190
191template<typename T>
192struct has_adc_configure_channel<T, std::void_t<decltype(
193 T::configure_channel(std::declval<const sbl::AdcHandle&>(),
194 std::declval<sbl::core::hal::adc::SampleTime>()))>>
195 : std::true_type {};
196
197// Detect: static void start_conversion(const AdcHandle&)
198template<typename T, typename = void>
199struct has_adc_start_conversion : std::false_type {};
200
201template<typename T>
202struct has_adc_start_conversion<T, std::void_t<decltype(
203 T::start_conversion(std::declval<const sbl::AdcHandle&>()))>>
204 : std::true_type {};
205
206// Detect: static bool is_conversion_complete()
207template<typename T, typename = void>
208struct has_adc_is_conversion_complete : std::false_type {};
209
210template<typename T>
211struct has_adc_is_conversion_complete<T, std::void_t<decltype(T::is_conversion_complete())>>
212 : std::true_type {};
213
214// Detect: static uint16_t read_raw()
215template<typename T, typename = void>
216struct has_adc_read_raw : std::false_type {};
217
218template<typename T>
219struct has_adc_read_raw<T, std::void_t<decltype(T::read_raw())>>
220 : std::true_type {};
221
222// Detect: static constexpr uint8_t resolution_bits()
223template<typename T, typename = void>
224struct has_adc_resolution_bits : std::false_type {};
225
226template<typename T>
227struct has_adc_resolution_bits<T, std::void_t<decltype(T::resolution_bits())>>
228 : std::true_type {};
229
230/**
231 * @brief Combined ADC driver interface check
232 *
233 * True if driver implements all required ADC methods.
234 */
235template<typename AdcDriver>
245
246} // namespace validation
247} // namespace sbl
248
249#endif // SBL_VALIDATION_METHOD_DETECTION_HPP_
ADC handle type for hardware abstraction.
GPIO handle type for hardware abstraction.
ADC common types and enumerations.
GPIO common types and enumerations.
Root namespace for all Sound Byte Libs functionality.
Definition aliases.hpp:24
Combined ADC driver interface check.
Combined GPIO driver interface check.
ADC Driver Method Detection.
GPIO Driver Method Detection (Handle-First API)
Timer Driver Method Detection.
UART Driver Method Detection.
UART handle type for hardware abstraction.