CommRaT 2.0.0
C++20 Real-Time Messaging Framework
Loading...
Searching...
No Matches
io_spec.hpp
Go to the documentation of this file.
1
13#pragma once
14
15#include <cstddef>
16#include <tuple>
17#include <type_traits>
18#include <concepts>
19
20namespace commrat {
21
22// ============================================================================
23// Forward Declarations
24// ============================================================================
25
26struct PeriodicInput;
27struct LoopInput;
28
29// ============================================================================
30// Output Specifications
31// ============================================================================
32
67template<typename T>
68struct Output {
69 using PayloadType = T;
70 static constexpr size_t count = 1;
71};
72
93template<typename... Ts>
94struct Outputs {
95 using PayloadTypes = std::tuple<Ts...>;
96 static constexpr size_t count = sizeof...(Ts);
97
98 static_assert(count > 0, "Outputs<> requires at least one type");
99};
100
117struct NoOutput {
118 static constexpr size_t count = 0;
119};
120
121// ============================================================================
122// Input Specifications
123// ============================================================================
124
142template<typename T>
143struct Input {
144 using PayloadType = T;
145 static constexpr size_t count = 1;
146};
147
204template<typename... Ts>
205struct Inputs {
206 using PayloadTypes = std::tuple<Ts...>;
207 static constexpr size_t count = sizeof...(Ts);
208
209 static_assert(count > 0, "Inputs<> requires at least one type");
210};
211
239template<typename T>
241 using PayloadType = T;
242};
243
244// ============================================================================
245// Type Traits and Concepts
246// ============================================================================
247
248// --- Output Type Detection ---
249
250template<typename T>
251struct is_single_output : std::false_type {};
252
253template<typename T>
254struct is_single_output<Output<T>> : std::true_type {};
255
256template<typename T>
258
259template<typename T>
260struct is_multi_output : std::false_type {};
261
262template<typename... Ts>
263struct is_multi_output<Outputs<Ts...>> : std::true_type {};
264
265template<typename T>
267
268template<typename T>
269struct is_no_output : std::false_type {};
270
271template<>
272struct is_no_output<NoOutput> : std::true_type {};
273
274template<typename T>
276
277template<typename T>
278concept ValidOutputSpec = is_single_output_v<T> ||
279 is_multi_output_v<T> ||
280 is_no_output_v<T>;
281
282// --- Input Type Detection ---
283
284template<typename T>
285struct is_periodic_input : std::false_type {};
286
287template<>
288struct is_periodic_input<PeriodicInput> : std::true_type {};
289
290template<typename T>
292
293template<typename T>
294struct is_loop_input : std::false_type {};
295
296template<>
297struct is_loop_input<LoopInput> : std::true_type {};
298
299template<typename T>
301
302template<typename T>
303struct is_single_input : std::false_type {};
304
305template<typename T>
306struct is_single_input<Input<T>> : std::true_type {};
307
308template<typename T>
310
311template<typename T>
312struct is_multi_input : std::false_type {};
313
314template<typename... Ts>
315struct is_multi_input<Inputs<Ts...>> : std::true_type {};
316
317template<typename T>
319
320template<typename T>
321struct is_primary_input : std::false_type {};
322
323template<typename T>
324struct is_primary_input<PrimaryInput<T>> : std::true_type {};
325
326template<typename T>
328
329template<typename T>
330concept ValidInputSpec = is_periodic_input_v<T> ||
331 is_loop_input_v<T> ||
332 is_single_input_v<T> ||
333 is_multi_input_v<T>;
334
335// --- Combined Concepts ---
336
337template<typename T>
338concept PeriodicOrLoop = is_periodic_input_v<T> || is_loop_input_v<T>;
339
340template<typename T>
341concept HasContinuousInput = is_single_input_v<T> ||
342 is_multi_input_v<T>;
343
344// --- Count Helpers ---
345
349template<typename T>
351 static constexpr size_t value = 1; // Raw type = single output
352};
353
354template<typename T>
355struct OutputCount<Output<T>> {
356 static constexpr size_t value = 1;
357};
358
359template<typename... Ts>
360struct OutputCount<Outputs<Ts...>> {
361 static constexpr size_t value = sizeof...(Ts);
362};
363
364template<>
366 static constexpr size_t value = 0;
367};
368
369template<typename T>
370inline constexpr size_t OutputCount_v = OutputCount<T>::value;
371
375template<typename T>
377 static constexpr size_t value = 0; // PeriodicInput, LoopInput = no input
378};
379
380template<typename T>
381struct InputCount<Input<T>> {
382 static constexpr size_t value = 1;
383};
384
385template<typename... Ts>
386struct InputCount<Inputs<Ts...>> {
387 static constexpr size_t value = sizeof...(Ts);
388};
389
390template<typename T>
391inline constexpr size_t InputCount_v = InputCount<T>::value;
392
393// ============================================================================
394// Input/Output Normalization
395// ============================================================================
396
400template<typename T>
402 using Type = T; // Default: pass through
403};
404
405template<typename T>
407
413template<typename T>
415 // If T is already an output spec, use it as-is
416 // Otherwise, wrap it in Output<T>
417 using Type = std::conditional_t<
419 T,
421 >;
422};
423
424template<typename T>
426
427// ============================================================================
428// Parameter Pack Expansion Helpers
429// ============================================================================
430
434template<typename InputSpec>
436 using Type = std::tuple<>; // Default: no inputs
437};
438
439template<typename T>
441 using Type = std::tuple<T>;
442};
443
444template<typename... Ts>
445struct InputPayloadTypes<Inputs<Ts...>> {
446 using Type = std::tuple<Ts...>;
447};
448
449template<typename InputSpec>
451
455template<typename OutputSpec>
457 using Type = std::tuple<>; // Default: no outputs
458};
459
460template<typename T>
462 using Type = std::tuple<T>;
463};
464
465template<typename... Ts>
467 using Type = std::tuple<Ts...>;
468};
469
470template<typename OutputSpec>
472
476template<typename OutputSpec>
478 using Type = OutputSpec; // Legacy: raw type is the output
479};
480
481template<typename T>
483 using Type = T;
484};
485
486template<typename OutputSpec>
488
492template<typename InputSpec>
494 using Type = void; // No input type for PeriodicInput/LoopInput
495};
496
497template<typename T>
499 using Type = T;
500};
501
502template<typename InputSpec>
504
505// ============================================================================
506// Primary Input Index Extraction (Phase 6)
507// ============================================================================
508
529template<typename PrimaryT, typename InputsTuple>
531
532// Base case: Primary type not found - compile error
533template<typename PrimaryT>
534struct PrimaryInputIndex<PrimaryT, std::tuple<>> {
535 static_assert(sizeof(PrimaryT) == 0,
536 "PrimaryInput type not found in Inputs<...> list. "
537 "Ensure PrimaryInput<T> specifies a type T that exists in Inputs<Ts...>.");
538};
539
540// Recursive case: Primary type matches first type in tuple
541template<typename PrimaryT, typename... Rest>
542struct PrimaryInputIndex<PrimaryT, std::tuple<PrimaryT, Rest...>> {
543 static constexpr size_t value = 0;
544};
545
546// Recursive case: Primary type doesn't match, continue searching
547template<typename PrimaryT, typename First, typename... Rest>
548struct PrimaryInputIndex<PrimaryT, std::tuple<First, Rest...>> {
549 static constexpr size_t value = 1 + PrimaryInputIndex<PrimaryT, std::tuple<Rest...>>::value;
550};
551
552template<typename PrimaryT, typename InputsTuple>
554
564template<typename PrimaryInputSpec, typename InputSpec>
566 static_assert(is_primary_input_v<PrimaryInputSpec>,
567 "PrimaryInputSpec must be PrimaryInput<T>");
568
569 static_assert(is_multi_input_v<InputSpec>,
570 "InputSpec must be Inputs<Ts...> when using PrimaryInput<T>");
571
572 using PrimaryPayload = typename PrimaryInputSpec::PayloadType;
573 using InputsPayloadTypes = typename InputSpec::PayloadTypes;
574
575 // This will trigger compile error if PrimaryPayload not in InputsPayloadTypes
576 static constexpr size_t primary_index =
577 PrimaryInputIndex_v<PrimaryPayload, InputsPayloadTypes>;
578
579 static constexpr bool value = true;
580};
581
582template<typename PrimaryInputSpec, typename InputSpec>
583inline constexpr bool ValidatePrimaryInput_v =
585
586} // namespace commrat
CommRaT - Modern C++ Real-Time Communication Framework.
constexpr bool is_periodic_input_v
Definition io_spec.hpp:291
constexpr bool is_single_input_v
Definition io_spec.hpp:309
typename SingleInputType< InputSpec >::Type SingleInputType_t
Definition io_spec.hpp:503
typename NormalizeInput< T >::Type NormalizeInput_t
Definition io_spec.hpp:406
constexpr bool is_no_output_v
Definition io_spec.hpp:275
typename OutputPayloadTypes< OutputSpec >::Type OutputPayloadTypes_t
Definition io_spec.hpp:471
typename NormalizeOutput< T >::Type NormalizeOutput_t
Definition io_spec.hpp:425
constexpr bool is_loop_input_v
Definition io_spec.hpp:300
constexpr bool ValidatePrimaryInput_v
Definition io_spec.hpp:583
constexpr size_t OutputCount_v
Definition io_spec.hpp:370
constexpr bool is_primary_input_v
Definition io_spec.hpp:327
constexpr bool is_single_output_v
Definition io_spec.hpp:257
typename InputPayloadTypes< InputSpec >::Type InputPayloadTypes_t
Definition io_spec.hpp:450
constexpr size_t InputCount_v
Definition io_spec.hpp:391
typename SingleOutputType< OutputSpec >::Type SingleOutputType_t
Definition io_spec.hpp:487
constexpr bool is_multi_output_v
Definition io_spec.hpp:266
constexpr bool is_multi_input_v
Definition io_spec.hpp:318
constexpr size_t PrimaryInputIndex_v
Definition io_spec.hpp:553
Get the number of inputs in an InputSpec.
Definition io_spec.hpp:376
static constexpr size_t value
Definition io_spec.hpp:377
Extract payload types from Inputs<Ts...> as a tuple.
Definition io_spec.hpp:435
Single continuous input specification.
Definition io_spec.hpp:143
static constexpr size_t count
Definition io_spec.hpp:145
Multiple continuous inputs specification.
Definition io_spec.hpp:205
static constexpr size_t count
Definition io_spec.hpp:207
std::tuple< Ts... > PayloadTypes
Definition io_spec.hpp:206
Free-running loop - module runs as fast as possible, no input data.
No output specification (sink module)
Definition io_spec.hpp:117
static constexpr size_t count
Definition io_spec.hpp:118
Pass-through for input specifications (no normalization needed)
Definition io_spec.hpp:401
Maps raw output types to Output<T> format.
Definition io_spec.hpp:414
std::conditional_t< ValidOutputSpec< T >, T, Output< T > > Type
Definition io_spec.hpp:421
Get the number of outputs in an OutputSpec.
Definition io_spec.hpp:350
static constexpr size_t value
Definition io_spec.hpp:351
Extract payload types from Outputs<Ts...> as a tuple.
Definition io_spec.hpp:456
Single output specification.
Definition io_spec.hpp:68
static constexpr size_t count
Definition io_spec.hpp:70
Multiple outputs specification.
Definition io_spec.hpp:94
std::tuple< Ts... > PayloadTypes
Definition io_spec.hpp:95
static constexpr size_t count
Definition io_spec.hpp:96
Periodic execution - module runs on a timer, no input data.
Extract the index of the primary input type within Inputs<Ts...>
Definition io_spec.hpp:530
Primary input designation for multi-input synchronization (Phase 6)
Definition io_spec.hpp:240
Get the single payload type from Input<T>
Definition io_spec.hpp:493
Get the single payload type from Output<T> or legacy OutputDataT.
Definition io_spec.hpp:477
Validate that PrimaryInput<T> is compatible with Inputs<Ts...>
Definition io_spec.hpp:565
static constexpr bool value
Definition io_spec.hpp:579
typename InputSpec::PayloadTypes InputsPayloadTypes
Definition io_spec.hpp:573
typename PrimaryInputSpec::PayloadType PrimaryPayload
Definition io_spec.hpp:572
static constexpr size_t primary_index
Definition io_spec.hpp:576