Zserio C++17 runtime library  1.1.0
Built for Zserio 2.18.1
Traits.h
Go to the documentation of this file.
1 #ifndef ZSERIO_TRAITS_H_INC
2 #define ZSERIO_TRAITS_H_INC
3 
4 #include <cstddef>
5 #include <type_traits>
6 
7 namespace zserio
8 {
9 
10 // forward declarations
11 template <typename, std::size_t>
12 class Span;
13 
14 template <typename T>
15 class View;
16 
17 template <typename T, typename ARRAY_TRAITS>
18 class ArrayView;
19 
20 template <typename ALLOC, typename T>
21 class BasicOptional;
22 
23 template <typename T>
24 class Extended;
25 
26 class ArrayPreallocation;
27 
28 namespace detail
29 {
30 
31 // Useful as a false-substitute in static_assert(false) which is buggy in gcc.
32 // At the same time it should print the type name if static_assert is triggered.
33 template <typename T>
34 struct always_false : std::false_type
35 {};
36 
37 template <typename VALUE_TYPE>
38 class NumericTypeWrapper;
39 
40 template <typename VALUE_TYPE>
41 class DynIntWrapper;
42 
43 template <typename T, typename = void>
44 struct is_allocator_impl : std::false_type
45 {};
46 
47 template <typename T>
48 struct is_allocator_impl<T,
49  std::void_t<typename T::value_type, decltype(std::declval<T>().allocate(0)),
50  decltype(std::declval<T>().deallocate(std::declval<typename T::value_type*>(), 0))>>
51  : std::true_type
52 {};
53 
54 template <typename T>
55 struct is_array_view : std::false_type
56 {};
57 
58 template <typename T, typename ARRAY_TRAITS>
59 struct is_array_view<ArrayView<T, ARRAY_TRAITS>> : std::true_type
60 {};
61 
62 template <typename T>
63 constexpr bool is_array_view_v = is_array_view<T>::value;
64 
65 template <typename T>
66 struct is_view : std::false_type
67 {};
68 
69 template <typename T>
70 struct is_view<View<T>> : std::true_type
71 {};
72 
73 template <typename T>
74 constexpr bool is_view_v = is_view<T>::value;
75 
76 template <typename T>
77 struct needs_offset_reference : std::negation<is_view<T>>
78 {};
79 
80 template <typename T>
81 struct needs_offset_reference<Extended<T>>
82 {
83  static constexpr bool value = needs_offset_reference<T>::value;
84 };
85 
86 template <typename ALLOC, typename T>
87 struct needs_offset_reference<BasicOptional<ALLOC, T>>
88 {
89  static constexpr bool value = needs_offset_reference<T>::value;
90 };
91 
92 template <typename T>
93 constexpr bool needs_offset_reference_v = needs_offset_reference<T>::value;
94 
95 } // namespace detail
96 
101 template <typename T>
102 struct is_allocator : detail::is_allocator_impl<std::decay_t<T>>
103 {};
104 
105 template <typename T>
106 inline constexpr bool is_allocator_v = is_allocator<T>::value;
113 template <typename... ARGS>
114 struct is_first_allocator : std::false_type
115 {};
116 
117 template <typename T, typename... ARGS>
118 struct is_first_allocator<T, ARGS...> : is_allocator<T>
119 {};
120 
121 template <typename... ARGS>
122 inline constexpr bool is_first_allocator_v = is_first_allocator<ARGS...>::value;
129 template <typename T, typename = void>
130 struct has_allocator : std::false_type
131 {};
132 
133 template <typename T>
134 struct has_allocator<T, std::void_t<typename T::allocator_type>> : std::true_type
135 {};
136 
137 template <typename T, typename V = void>
145 template <typename... ARGS>
146 struct is_first_array_preallocation : std::false_type
147 {};
148 
149 template <typename T, typename... ARGS>
150 struct is_first_array_preallocation<T, ARGS...> : std::is_same<std::decay_t<T>, ArrayPreallocation>
151 {};
152 
153 template <typename... ARGS>
154 inline constexpr bool is_first_array_preallocation_v = is_first_array_preallocation<ARGS...>::value;
161 template <typename T, typename = void>
162 struct is_bitmask : std::false_type
163 {};
164 
165 template <typename T>
166 struct is_bitmask<T, std::void_t<decltype(std::declval<T>().getValue()), typename T::ZserioType>>
167  : std::true_type
168 {};
169 
170 template <typename T, typename V = void>
171 inline constexpr bool is_bitmask_v = is_bitmask<T, V>::value;
180 template <typename>
181 struct is_span : std::false_type
182 {};
183 
184 template <typename T, size_t Extent>
185 struct is_span<Span<T, Extent>> : std::true_type
186 {};
187 
188 template <typename T>
189 inline constexpr bool is_span_v = is_span<T>::value;
197 template <typename T, typename = void>
198 struct is_numeric_wrapper : std::false_type
199 {};
200 
201 template <typename T>
202 struct is_numeric_wrapper<T,
203  std::enable_if_t<std::is_base_of_v<detail::NumericTypeWrapper<typename T::ValueType>, T>>>
204  : std::true_type
205 {};
206 
207 template <typename T, typename V = void>
209 
213 template <typename T, typename = void>
214 struct is_dyn_int_wrapper : std::false_type
215 {};
216 
217 template <typename T>
218 struct is_dyn_int_wrapper<T,
219  std::enable_if_t<std::is_base_of_v<detail::DynIntWrapper<typename T::ValueType>, T>>> : std::true_type
220 {};
221 
222 template <typename T, typename V = void>
224 
229 template <typename T, typename = void>
230 struct is_complete : std::false_type
231 {};
232 
233 template <typename T>
234 struct is_complete<T, std::void_t<decltype(sizeof(T))>> : std::true_type
235 {};
236 
237 template <typename T>
246 template <typename T, typename = void>
247 struct view_type
248 {
249  using type = T;
250 };
251 
252 template <typename T>
253 struct view_type<T, std::enable_if_t<is_complete_v<View<T>>>>
254 {
255  using type = View<T>;
256 };
257 
258 template <typename T, typename V = void>
267 template <typename T, typename = void>
269 {
270  using type = T;
271 };
272 
273 template <typename T>
274 struct offset_field_reference<T, std::enable_if_t<detail::needs_offset_reference_v<T>>>
275 {
276  using type = T&;
277 };
278 
279 template <typename T, typename V = void>
290 template <typename T, typename ALLOC, typename... ARGS>
291 constexpr T constructWithAllocator(const ALLOC& allocator, ARGS&&... args)
292 {
293  if constexpr (std::is_constructible_v<T, ARGS..., ALLOC>)
294  {
295  return T(std::forward<ARGS>(args)..., allocator);
296  }
297  else
298  {
299  return T(std::forward<ARGS>(args)...);
300  }
301 }
302 
309 template <typename T, typename ALLOC, typename U, std::enable_if_t<is_numeric_wrapper_v<T>, int> = 0>
310 constexpr T constructWithAllocator(const ALLOC&, U value)
311 {
312  return T(static_cast<typename T::ValueType>(value));
313 }
314 
315 } // namespace zserio
316 
317 #endif // ifndef ZSERIO_TRAITS_H_INC
Definition: BitBuffer.h:602
constexpr bool is_complete_v
Definition: Traits.h:238
typename offset_field_reference< T, V >::type offset_field_reference_t
Definition: Traits.h:280
constexpr bool is_allocator_v
Definition: Traits.h:106
constexpr bool is_dyn_int_wrapper_v
Definition: Traits.h:223
constexpr bool is_span_v
Definition: Traits.h:189
constexpr T constructWithAllocator(const ALLOC &allocator, ARGS &&... args)
Definition: Traits.h:291
constexpr bool is_numeric_wrapper_v
Definition: Traits.h:208
constexpr bool is_bitmask_v
Definition: Traits.h:171
View(T, ARGS &&...) -> View< T >
constexpr bool has_allocator_v
Definition: Traits.h:138
typename view_type< T, V >::type view_type_t
Definition: Traits.h:259
constexpr bool is_first_allocator_v
Definition: Traits.h:122
constexpr bool is_first_array_preallocation_v
Definition: Traits.h:154