emlabcpp
modern opinionated embedded C++ library
traits.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "../experimental/decompose.h"
27 #include "../quantity.h"
28 #include "../static_vector.h"
29 #include "../types.h"
30 #include "./base.h"
31 #include "./error.h"
32 #include "./message.h"
33 
34 #include <chrono>
35 #include <optional>
36 #include <variant>
37 
38 namespace emlabcpp::protocol
39 {
40 
43 template < typename D >
44 struct proto_traits;
45 
46 template < typename D >
48 
49 template < typename D >
50 consteval auto traits_for_impl()
51 {
52  if constexpr ( with_value_type< proto_traits< D > > )
53  return proto_traits< D >{};
54  else
55  return backup_proto_traits< D >{};
56 }
57 
58 template < typename D >
59 using traits_for = decltype( traits_for_impl< D >() );
60 
66 template < typename D >
67 concept convertible = requires( D val ) {
68  { traits_for< D >::max_size } -> std::convertible_to< std::size_t >;
69  { traits_for< D >::min_size } -> std::convertible_to< std::size_t >;
71 };
72 
73 template < typename T >
75 
76 template < base_type D >
77 struct proto_traits< D >
78 {
79  using value_type = D;
80  static constexpr std::size_t max_size = sizeof( D );
81  static constexpr std::size_t min_size = max_size;
82 };
83 
84 template < convertible D, std::size_t N >
85 struct proto_traits< std::array< D, N > >
86 {
87  using value_type = std::array< D, N >;
88  static constexpr std::size_t max_size = traits_for< D >::max_size * N;
89  static constexpr std::size_t min_size = traits_for< D >::min_size * N;
90 };
91 
92 template < convertible... Ds >
93 struct proto_traits< std::tuple< Ds... > >
94 {
96  static constexpr std::size_t max_size = ( traits_for< Ds >::max_size + ... + 0 );
97  static constexpr std::size_t min_size = ( traits_for< Ds >::min_size + ... + 0 );
98 };
99 
100 template < convertible... Ds >
101 struct proto_traits< std::variant< Ds... > >
102 {
103  using id_type = uint8_t;
106 
107  static constexpr std::size_t max_size =
108  id_traits::max_size + std::max< std::size_t >( { traits_for< Ds >::max_size... } );
109  static constexpr std::size_t min_size =
110  id_traits::min_size + std::min< std::size_t >( { traits_for< Ds >::min_size... } );
111 };
112 
113 template <>
114 struct proto_traits< std::monostate >
115 {
116  using value_type = std::monostate;
117  static constexpr std::size_t max_size = 0;
118  static constexpr std::size_t min_size = 0;
119 };
120 
121 template < std::size_t N >
122 struct proto_traits< std::bitset< N > >
123 {
124  using value_type = std::bitset< N >;
125 
126  static constexpr std::size_t max_size = ( N + 7 ) / 8;
127  static constexpr std::size_t min_size = max_size;
128 };
129 
130 template < std::size_t N >
132 {
134 
135  static constexpr std::size_t max_size = N;
136  static constexpr std::size_t min_size = 0;
137 };
138 
139 template < std::size_t N >
140 struct proto_traits< message< N > >
141 {
142  using msg_size_type = uint16_t;
143  static_assert( N <= std::numeric_limits< msg_size_type >::max() );
144 
146 
148 
149  static constexpr std::size_t max_size = msg_size_traits::max_size + N;
150  static constexpr std::size_t min_size = msg_size_traits::min_size + 0;
151 };
152 
153 template < convertible D, auto Offset >
154 struct proto_traits< value_offset< D, Offset > >
155 {
159 
160  static constexpr std::size_t max_size = def_traits::max_size;
161  static constexpr std::size_t min_size = def_traits::min_size;
162 };
163 
164 template < quantity_derived D >
165 struct proto_traits< D >
166 {
167  using value_type = D;
168 
169  static constexpr std::size_t max_size = traits_for< typename D::value_type >::max_size;
170  static constexpr std::size_t min_size = traits_for< typename D::value_type >::min_size;
171 };
172 
173 template < convertible D, D Min, D Max >
174 struct proto_traits< bounded< D, Min, Max > >
175 {
177 
178  static constexpr std::size_t max_size = traits_for< D >::max_size;
179  static constexpr std::size_t min_size = traits_for< D >::min_size;
180 };
181 
182 template < convertible CounterType, convertible D >
183 struct proto_traits< sized_buffer< CounterType, D > >
184 {
188 
189  static constexpr std::size_t max_size = counter_traits::max_size + sub_traits::max_size;
190  static constexpr std::size_t min_size = counter_traits::min_size + sub_traits::min_size;
191 };
192 
193 template < auto V >
194 struct proto_traits< tag< V > >
195 {
196  using sub_traits = traits_for< decltype( V ) >;
198 
199  static constexpr std::size_t max_size = sub_traits::max_size;
200  static constexpr std::size_t min_size = sub_traits::min_size;
201 };
202 
203 template < convertible... Ds >
204 struct proto_traits< group< Ds... > >
205 {
207 
208  static constexpr std::size_t max_size =
209  std::max< std::size_t >( { traits_for< Ds >::max_size..., 0 } );
210  static constexpr std::size_t min_size = std::min< std::size_t >(
212  sizeof...( Ds ) == 0 ? 0 : std::numeric_limits< std::size_t >::max() } );
213 };
214 
215 template < convertible... Ds >
216 struct proto_traits< tag_group< Ds... > >
217 {
219 
220  template < typename D >
221  using to_tuple = std::tuple< tag< D::id >, D >;
222 
225 
226  static constexpr std::size_t max_size = sub_traits::max_size;
227  static constexpr std::size_t min_size = sub_traits::min_size;
228 };
229 
230 template < std::endian Endianess, convertible D >
232 {
233 };
234 
235 template < std::derived_from< converter_def_type_base > D >
236 struct proto_traits< D > : traits_for< typename D::def_type >
237 {
238 };
239 
240 template < std::size_t N >
242 {
243  using counter_type = uint16_t;
246  static constexpr std::size_t max_size = N + counter_traits::max_size;
247  static constexpr std::size_t min_size = 0 + counter_traits::min_size;
248 };
249 
250 template < typename Rep, typename Ratio >
251 struct proto_traits< std::chrono::duration< Rep, Ratio > >
252 {
254  using value_type = std::chrono::duration< Rep, Ratio >;
255  static constexpr std::size_t max_size = rep_traits::max_size;
256  static constexpr std::size_t min_size = rep_traits::min_size;
257 };
258 
259 template <>
261 {
263 
264  using mark_type = mark;
265  using offset_type = std::size_t;
266 
269 
270  static constexpr std::size_t max_size = mark_traits::max_size + offset_traits::max_size;
271  static constexpr std::size_t min_size = mark_traits::min_size + offset_traits::min_size;
272 };
273 
274 template < convertible T, std::size_t N >
275 struct proto_traits< static_vector< T, N > >
276 {
278  using counter_type = uint16_t;
279  static constexpr std::size_t max_size =
281  static constexpr std::size_t min_size = traits_for< counter_type >::min_size;
282 };
283 
284 template < convertible T >
285 struct proto_traits< std::optional< T > >
286 {
287  using value_type = std::optional< T >;
290  static constexpr std::size_t max_size =
292  static constexpr std::size_t min_size = presence_traits::min_size;
293 };
294 
295 template < decomposable T >
297 {
298  using value_type = T;
299  using tuple_type = decomposed_type< T >;
301  static constexpr std::size_t max_size = tuple_traits::max_size;
302  static constexpr std::size_t min_size = tuple_traits::min_size;
303 };
304 
305 } // namespace emlabcpp::protocol
The bounded class represents a wrapper over type T constrained between MinVal and MaxVal as compile-t...
Definition: bounded.h:44
Protocol library has custom type that represents message, however this is just simple overaly over st...
Definition: message.h:40
Sizeless message is class that behaves in a same way as normal message, however it is serialized diff...
Definition: message.h:183
Data container for up to N elements.
Definition: static_vector.h:36
MIT License.
Definition: multiplexer.h:33
requires(std::is_enum_v< T >) struct serializer< T
decltype(traits_for_impl< D >()) traits_for
Definition: traits.h:59
Endianess
Definition: serializer.h:70
consteval auto traits_for_impl()
Definition: traits.h:50
string_buffer< mark_size > mark
Definition: error.h:36
static constexpr std::size_t max_size
Definition: serializer.h:73
concept convertible
This concepts limits types to types that can be declared, that is the overload of 'traits_for' is ful...
Definition: traits.h:67
concept fixedly_sized
Definition: traits.h:74
Definition: error.h:39
Serializes values from definitions Ds to std::variant.
Definition: base.h:89
Each definition of item provided to protocol library should have specialization of 'proto_traits' str...
Definition: traits.h:44
Creates a segment starting with counter defined by CounterDef, this counter limits how many bytes are...
Definition: base.h:104
Definition: base.h:95
std::variant< int64_t, float, bool, string_buffer > value_type
Definition: base.h:51
constexpr Derived max(vec_point_base< Derived, N > const &a, vec_point_base< Derived, N > const &b)
Definition: vec_point_base.h:229
N
Definition: static_storage.h:97
concept with_value_type
Definition: concepts.h:182
decomposed_type< T > tuple_type
Definition: traits.h:299
traits_for< tuple_type > tuple_traits
Definition: traits.h:300
Follows a set of special data types used for definition of protocol.
Definition: base.h:79
D value_type
Definition: traits.h:79
std::size_t offset_type
Definition: traits.h:265
traits_for< offset_type > offset_traits
Definition: traits.h:268
traits_for< mark_type > mark_traits
Definition: traits.h:267
std::variant< typename traits_for< Ds >::value_type... > value_type
Definition: traits.h:206
uint16_t msg_size_type
Definition: traits.h:142
traits_for< msg_size_type > msg_size_traits
Definition: traits.h:145
typename sub_traits::value_type value_type
Definition: traits.h:187
traits_for< CounterType > counter_traits
Definition: traits.h:185
std::array< D, N > value_type
Definition: traits.h:87
std::bitset< N > value_type
Definition: traits.h:124
std::chrono::duration< Rep, Ratio > value_type
Definition: traits.h:254
std::monostate value_type
Definition: traits.h:116
traits_for< presence_type > presence_traits
Definition: traits.h:289
std::optional< T > value_type
Definition: traits.h:287
std::tuple< typename traits_for< Ds >::value_type... > value_type
Definition: traits.h:95
traits_for< id_type > id_traits
Definition: traits.h:104
std::variant< typename traits_for< Ds >::value_type... > value_type
Definition: traits.h:105
traits_for< counter_type > counter_traits
Definition: traits.h:244
traits_for< decltype(V) > sub_traits
Definition: traits.h:196
traits_for< sub_type > sub_traits
Definition: traits.h:224
std::variant< typename traits_for< Ds >::value_type... > value_type
Definition: traits.h:218
std::tuple< tag< D::id >, D > to_tuple
Definition: traits.h:221
traits_for< def_type > def_traits
Definition: traits.h:157
typename def_traits::value_type value_type
Definition: traits.h:158
typename value_offset< D, Offset >::def_type def_type
Definition: traits.h:156
tuple is high levle alternative to use just 'std::tuple' that is more friendly for standalone protoco...
Definition: tuple.h:43
The value defined by D present in the message is offseted by Offset.
Definition: base.h:113
D def_type
Definition: base.h:115
Definition: string_buffer.h:38
Definition: types.h:73