The Sparta Modeling Framework
Loading...
Searching...
No Matches
MetaStructs.hpp
Go to the documentation of this file.
1// <MetaStructs.hpp> -*- C++ -*-
2
3
11#pragma once
12
13#include <vector>
14#include <array>
15#include <functional>
16#include <queue>
17#include <stack>
18#include <list>
19#include <deque>
20#include <forward_list>
21#include <set>
22#include <unordered_set>
23#include <map>
24#include <unordered_map>
25#include <type_traits>
26
27#include "sparta/utils/Enum.hpp"
28
29namespace MetaStruct {
30 // If compiler is C++11 compliant, then use explicit aliases.
31 #if __cplusplus == 201103L
32
40 template<typename...>
41 struct all_unsigned;
42
46 template<>
47 struct all_unsigned<> : public std::true_type {};
48
53 template<typename Head, typename... Tail>
54 struct all_unsigned<Head, Tail...> {
55 static constexpr bool value {std::is_unsigned<typename std::decay<Head>::type>::value and
56 all_unsigned<Tail...>::value};
57 };
58
66 template<typename...>
67 struct all_signed;
68
72 template<>
73 struct all_signed<> : public std::true_type {};
74
79 template<typename Head, typename... Tail>
80 struct all_signed<Head, Tail...> {
81 static constexpr bool value {std::is_signed<typename std::decay<Head>::type>::value and
82 all_signed<Tail...>::value};
83 };
84
90 template<typename... Args>
91 struct all_same_sign {
92 static constexpr bool value {all_signed<Args...>::value or all_unsigned<Args...>::value};
93 };
94
102 template<typename...>
103 struct all_are_integral;
104
108 template<>
109 struct all_are_integral<> : public std::true_type {};
110
115 template<typename Head, typename... Tail>
116 struct all_are_integral<Head, Tail...> {
117 static constexpr bool value {std::is_integral<typename std::decay<Head>::type>::value and
118 all_are_integral<Tail...>::value};
119 };
120
123 template<bool B, typename T = void>
124 using enable_if_t = typename std::enable_if<B, T>::type;
125
128 template<typename T>
129 using decay_t = typename std::decay<T>::type;
130
133 template<typename T>
134 using underlying_type_t = typename std::underlying_type<T>::type;
135
136 // If compiler is C++14/17 compliant, then use standard aliases.
137 #elif __cplusplus > 201103L
140 template<bool B, typename T = void>
141 using enable_if_t = typename std::enable_if_t<B, T>;
142
145 template<typename T>
146 using decay_t = typename std::decay_t<T>;
147
150 template<typename T>
151 using underlying_type_t = typename std::underlying_type_t<T>;
152 #endif
153
160 template<typename...>
162
172 template<typename T>
173 struct matches_any<T> : public std::true_type {};
174
184 template<typename T, typename Head, typename... Tail>
185 struct matches_any<T, Head, Tail...> {
186 static constexpr bool value {std::is_same<T, Head>::value or matches_any<T, Tail...>::value};
187 };
188
193 template<typename T>
194 struct add_pointer { using type = T *; };
195
196 template<typename T>
197 struct add_pointer<T *> { using type = T; };
198
199 template<typename T>
200 struct add_pointer<const T *> { using type = T; };
201
202 template<typename T>
203 struct add_pointer<T * const> { using type = T; };
204
205 template<typename T>
206 struct add_pointer<const T * const> { using type = T; };
207
210 template<typename T>
211 using add_pointer_t = typename add_pointer<T>::type;
212
219 template<typename>
220 struct is_any_pointer : public std::false_type {};
221
222 template<typename T>
223 struct is_any_pointer<T *> : public std::true_type {};
224
225 template<typename T>
226 struct is_any_pointer<T * const> : public std::true_type {};
227
228 template<typename T>
229 struct is_any_pointer<const T *> : public std::true_type {};
230
231 template<typename T>
232 struct is_any_pointer<const T * const> : public std::true_type {};
233
234 template<typename T>
235 struct is_any_pointer<std::shared_ptr<T>> : public std::true_type {};
236
237 template<typename T>
238 struct is_any_pointer<std::shared_ptr<T> const> : public std::true_type {};
239
240 template<typename T>
241 struct is_any_pointer<std::shared_ptr<T> &> : public std::true_type {};
242
243 template<typename T>
244 struct is_any_pointer<std::shared_ptr<T> const &> : public std::true_type {};
245
246 template<typename T>
247 struct is_any_pointer<std::unique_ptr<T>> : public std::true_type {};
248
249 template<typename T>
250 struct is_any_pointer<std::unique_ptr<T> const> : public std::true_type {};
251
252 template<typename T>
253 struct is_any_pointer<std::unique_ptr<T> &> : public std::true_type {};
254
255 template<typename T>
256 struct is_any_pointer<std::unique_ptr<T> const &> : public std::true_type {};
257
258 template<typename T>
259 struct is_any_pointer<std::weak_ptr<T>> : public std::true_type {};
260
261 template<typename T>
262 struct is_any_pointer<std::weak_ptr<T> const> : public std::true_type {};
263
264 template<typename T>
265 struct is_any_pointer<std::weak_ptr<T> &> : public std::true_type {};
266
267 template<typename T>
268 struct is_any_pointer<std::weak_ptr<T> const &> : public std::true_type {};
269
282 template<typename T>
283 struct remove_any_pointer { using type = T; };
284
285 template<typename T>
286 struct remove_any_pointer<T *> { using type = T; };
287
288 template<typename T>
289 struct remove_any_pointer<T * const> { using type = T; };
290
291 template<typename T>
292 struct remove_any_pointer<const T *> { using type = T; };
293
294 template<typename T>
295 struct remove_any_pointer<const T * const> { using type = T; };
296
297 template<typename T>
298 struct remove_any_pointer<std::shared_ptr<T>> { using type = T; };
299
300 template<typename T>
301 struct remove_any_pointer<std::shared_ptr<T> const> { using type = T; };
302
303 template<typename T>
304 struct remove_any_pointer<std::shared_ptr<T> &> { using type = T; };
305
306 template<typename T>
307 struct remove_any_pointer<std::shared_ptr<T> const &> { using type = T; };
308
309 template<typename T>
310 struct remove_any_pointer<std::unique_ptr<T>> { using type = T; };
311
312 template<typename T>
313 struct remove_any_pointer<std::unique_ptr<T> const> { using type = T; };
314
315 template<typename T>
316 struct remove_any_pointer<std::unique_ptr<T> &> { using type = T; };
317
318 template<typename T>
319 struct remove_any_pointer<std::unique_ptr<T> const &> { using type = T; };
320
321 template<typename T>
322 struct remove_any_pointer<std::weak_ptr<T>> { using type = T; };
323
324 template<typename T>
325 struct remove_any_pointer<std::weak_ptr<T> const> { using type = T; };
326
327 template<typename T>
328 struct remove_any_pointer<std::weak_ptr<T> &> { using type = T; };
329
330 template<typename T>
331 struct remove_any_pointer<std::weak_ptr<T> const &> { using type = T; };
332
335 template<typename T>
336 using remove_any_pointer_t = typename remove_any_pointer<T>::type;
337
342 template<typename>
343 struct is_stl_container : std::false_type {};
344
345 template<typename T, std::size_t N>
346 struct is_stl_container<std::array<T, N>> : public std::true_type {};
347
348 template<typename... Args>
349 struct is_stl_container<std::vector<Args...>> : public std::true_type {};
350
351 template<typename... Args>
352 struct is_stl_container<std::deque<Args...>> : public std::true_type {};
353
354 template<typename... Args>
355 struct is_stl_container<std::list<Args...>> : public std::true_type {};
356
357 template<typename... Args>
358 struct is_stl_container<std::forward_list<Args...>> : public std::true_type {};
359
360 template<typename... Args>
361 struct is_stl_container<std::set<Args...>> : public std::true_type {};
362
363 template<typename... Args>
364 struct is_stl_container<std::multiset<Args...>> : public std::true_type {};
365
366 template<typename... Args>
367 struct is_stl_container<std::map<Args...>> : public std::true_type {};
368
369 template<typename... Args>
370 struct is_stl_container<std::multimap<Args...>> : public std::true_type {};
371
372 template<typename... Args>
373 struct is_stl_container<std::unordered_set<Args...>> : public std::true_type {};
374
375 template<typename... Args>
376 struct is_stl_container<std::unordered_multiset<Args...>> : public std::true_type {};
377
378 template<typename... Args>
379 struct is_stl_container<std::unordered_map<Args...>> : public std::true_type {};
380
381 template<typename... Args>
382 struct is_stl_container<std::unordered_multimap<Args...>> : public std::true_type {};
383
384 template<typename... Args>
385 struct is_stl_container<std::stack<Args...>> : public std::true_type {};
386
387 template<typename... Args>
388 struct is_stl_container<std::queue<Args...>> : public std::true_type {};
389
390 template<typename... Args>
391 struct is_stl_container<std::priority_queue<Args...>> : public std::true_type {};
392
393 template <typename T>
394 struct is_stl {
395 static constexpr bool value =
397 };
398
403 template<typename... Args>
405 static constexpr std::size_t value = sizeof...(Args);
406 };
407
408 template<typename...>
410
411 template<typename Head, typename... Tail>
412 struct peek_last_type<Head, Tail...> : public peek_last_type<Tail...> {};
413
414 template<typename Tail>
415 struct peek_last_type<Tail> {
416 using type = Tail;
417 };
418
419 template<typename... Args>
420 using peek_last_type_t = typename peek_last_type<Args...>::type;
428 template<std::size_t, typename...>
430
435 template<typename T>
436 struct last_index_type<0, T> { using type = T; };
437
442 template<std::size_t N, typename T, typename... Args>
443 struct last_index_type<N, T, Args...> : public last_index_type<N - 1, Args...> {};
444
447 template<std::size_t N, typename... Args>
448 using last_index_type_t = typename last_index_type<N, Args...>::type;
449
460 template<std::size_t...>
462
466 template<int N, std::size_t... S>
467 struct generate_sequence : generate_sequence<N - 1, N - 1, S...> {};
468
473 template<std::size_t... S>
474 struct generate_sequence<0, S...> { using type = sequence_generator<S...>; };
475
478 template<std::size_t... Args>
479 using generate_sequence_t = typename generate_sequence<Args...>::type;
480
486 template<typename T>
487 struct return_type { using type = T; };
488
489 template<typename R, typename... Ts>
490 struct return_type<std::function<R (Ts...)>> { using type = R; };
491
492 template<typename R, typename... Ts>
493 struct return_type<std::function<R (Ts...)> const> { using type = R; };
494
495 template<typename R, typename T, typename... Ts>
496 struct return_type<std::function<R (Ts...)> T:: *> { using type = R; };
497
498 template<typename R, typename T, typename... Ts>
499 struct return_type<std::function<R (Ts...)> const T:: *> { using type = R; };
500
501 template<typename R, typename T, typename... Ts>
502 struct return_type<std::function<R (Ts...)> T:: * const &> { using type = R; };
503
504 template<typename R, typename T, typename... Ts>
505 struct return_type<std::function<R (Ts...)> const T:: * const> { using type = R; };
506
507 template<typename R, typename... Ts>
508 struct return_type<R (*)(Ts...)> { using type = R; };
509
510 template<typename R, typename... Ts>
511 struct return_type<R& (*)(Ts...)> { using type = R; };
512
513 template<typename R, typename T>
514 struct return_type<R (T:: *)() const> { using type = R; };
515
516 template<typename R, typename T>
517 struct return_type<R & (T:: *)() const> { using type = R; };
518
519 template<typename R, typename T>
520 struct return_type<std::shared_ptr<R> (T:: *)() const> { using type = R; };
521
522 template<typename R, typename T>
523 struct return_type<std::shared_ptr<R> & (T:: *)() const> { using type = R; };
524
525 template<typename R, typename T>
526 struct return_type<R (T:: * const)() const> { using type = R; };
527
528 template<typename R, typename T>
529 struct return_type<R & (T:: * const)() const> { using type = R; };
530
531 template<typename R, typename T>
532 struct return_type<std::shared_ptr<R> (T:: * const)() const> { using type = R; };
533
534 template<typename R, typename T>
535 struct return_type<std::shared_ptr<R> & (T:: * const)() const> { using type = R; };
536
537 template<typename R, typename T>
538 struct return_type<R (T:: * const &)() const> { using type = R; };
539
540 template<typename R, typename T>
541 struct return_type<R & (T:: * const &)() const> { using type = R; };
542
543 template<typename R, typename T>
544 struct return_type<std::shared_ptr<R> (T:: * const &)() const> { using type = R; };
545
546 template<typename R, typename T>
547 struct return_type<std::shared_ptr<R> & (T:: * const &)() const> { using type = R; };
548
551 template<typename T>
552 using return_type_t = typename return_type<T>::type;
553
556 template<typename T>
557 struct is_pod : std::integral_constant<
558 bool,
559 std::is_trivial<T>::value && std::is_standard_layout<T>::value
560 > {};
561
565 template<typename>
566 struct is_bool : public std::false_type {};
567
568 template<>
569 struct is_bool<bool> : public std::true_type {};
570
571 template<>
572 struct is_bool<bool &> : public std::true_type {};
573
574 template<>
575 struct is_bool<bool const &> : public std::true_type {};
576
577 template<>
578 struct is_bool<bool const> : public std::true_type {};
579
587 template<typename>
588 struct is_pair : public std::false_type {};
589
590 template<typename T, typename U>
591 struct is_pair<std::pair<T, U>> : public std::true_type{} ;
592
593 template<typename T, typename U>
594 struct is_pair<std::pair<T, U> &> : public std::true_type {};
595
596 template<typename T, typename U>
597 struct is_pair<std::pair<T, U> const &> : public std::true_type {};
598
599 template<typename T, typename U>
600 struct is_pair<std::pair<T, U> const> : public std::true_type {};
601
605 template<typename>
606 struct is_string : public std::false_type {};
607
608 template<>
609 struct is_string<std::string> : public std::true_type {};
610
611 template<>
612 struct is_string<std::string &> : public std::true_type {};
613
614 template<>
615 struct is_string<std::string const &> : public std::true_type {};
616
617 template<>
618 struct is_string<std::string const> : public std::true_type {};
619
623 template<typename>
624 struct is_char_pointer : public std::false_type{};
625
626 template<>
627 struct is_char_pointer<char*> : public std::true_type{};
628
629 template<>
630 struct is_char_pointer<const char*> : public std::true_type{};
631
632 template<>
633 struct is_char_pointer<char* const> : public std::true_type{};
634
635 template<>
636 struct is_char_pointer<const char* const> : public std::true_type{};
637
642 template<typename T>
643 struct is_sparta_enum : public std::false_type {};
644
649 template<typename T>
650 struct is_sparta_enum<sparta::utils::Enum<T>> : public std::true_type {};
651} // namespace MetaStruct
typename add_pointer< T >::type add_pointer_t
Alias Template for add_pointer.
typename return_type< T >::type return_type_t
Alias Template for return_type.
typename remove_any_pointer< T >::type remove_any_pointer_t
Alias Template for remove_pointer.
typename generate_sequence< Args... >::type generate_sequence_t
Alias Template for generate_sequence.
typename last_index_type< N, Args... >::type last_index_type_t
Alias Template for last_index_type.
Macros for handling exponential backoff.
This templated struct takes a type and gives back a nested typedef of a pointer to that type.
This is the generic template.
This templated struct lets us know about whether the datatype is actually an ordinary object or point...
Templated struct for detecting Boolean Type.
Templated struct for detecting char pointer type.
This templated struct lets us know about whether the datatype is actually an std::pair object....
Replacement for std::is_pod (deprecated in C++20)
Detect whether template parameter is sparta::utils::Enum type. Case when it is not a sparta::utils::E...
This templated struct takes a type and tells us whether that type is a STL container.
Templated struct for detecting String Type.
This Variadic templated struct helps us know about the type of the very last or tail item in a parame...
This templated struct takes a target type and another parameter pack of types and returns a nested bo...
This Variadic templated struct contains a nested value which stores the length of any parameter pack ...
Template type helper that removes any pointer. A modeler may call certain APIs with shared pointers t...
This templated struct lets us know about the return type from any random function pointer....
This Variadic templated struct basically works much like std::integer_sequence. It represents a compi...