C++ Library Extensions 2022.12.09
To help learn modern C++ programming
tpf_types.hpp
Go to the documentation of this file.
1
12#ifndef _TPF_TYPES_HPP
13#define _TPF_TYPES_HPP
14
15#ifndef NOMINMAX
16#define NOMINMAX
17#endif
18
19#ifndef Tpf_FormatWidth
20#define Tpf_FormatWidth 12
21#endif // end of Tpf_FormatWidth
22
23#ifndef Tpf_FormatPrecision
24#define Tpf_FormatPrecision 6
25#endif // end of Tpf_FormatWidth
26
27#ifndef Tpf_ToleranceFloat
28 #define Tpf_ToleranceFloat 1.0e-7
29#endif
30
31#ifndef Tpf_ToleranceDouble
32 #define Tpf_ToleranceDouble 1.0e-12
33#endif
34
35#ifndef Tpf_ToleranceLongDouble
36 #define Tpf_ToleranceLongDouble 1.0e-12
37#endif
38
39#ifdef _MSVC_LANG
40
41 #if _MSVC_LANG < 201703L
42 #error This libary requires C++17 Standard (Visual Studio 2017).
43 #endif
44
45#else
46
47 #if __cplusplus < 201703
48 #error This library requires C++17 Standard (GNU g++ version 8.0 or clang++ version 8.0 above)
49 #endif // end of __cplusplus
50
51#endif // end of _MSVC_LANG
52
53#include <iostream>
54#include <iomanip>
55#include <sstream>
56#include <numeric>
57#include <type_traits>
58#include <string>
59#include <cstring>
60#include <vector>
61#include <deque>
62#include <exception>
63#include <variant>
64#include <tuple>
65#include <array>
66#include <set>
67#include <unordered_set>
68#include <map>
69#include <unordered_map>
70#include <list>
71#include <any>
72#include <functional>
73#include <future>
74#include <thread>
75#include <atomic>
76#include <mutex>
77#include <memory>
78#include <iterator>
79#include <execution>
80#include <ratio>
81#include <optional>
82#include <string_view>
83#include <cassert>
84
85#ifdef _MSC_VER
86 #define __FUNCTION_NAME__ __FUNCSIG__
87#else
88 #define __FUNCTION_NAME__ __PRETTY_FUNCTION__
89#endif
90
91namespace tpf
92{
93 namespace literals
94 {
95 inline constexpr std::size_t operator""_size_t(unsigned long long value)
96 {
97 return static_cast<std::size_t>(value);
98 }
99
100 inline constexpr unsigned int operator""_unsigned(unsigned long long value)
101 {
102 return static_cast<unsigned int>(value);
103 }
104
105 inline constexpr short operator""_short(unsigned long long value)
106 {
107 return static_cast<short>(value);
108 }
109
110 inline constexpr unsigned short operator""_ushort(unsigned long long value)
111 {
112 return static_cast<unsigned short>(value);
113 }
114
115 inline constexpr char operator""_char(unsigned long long value)
116 {
117 return static_cast<char>(value);
118 }
119
120 inline constexpr char operator""_schar(unsigned long long value)
121 {
122 return static_cast<signed char>(value);
123 }
124
125 inline constexpr unsigned char operator""_uchar(unsigned long long value)
126 {
127 return static_cast<unsigned char>(value);
128 }
129
130 inline constexpr long double operator""_ldouble(long double value)
131 {
132 return value;
133 }
134 }
135}
136
141namespace tpf
142{
143 enum class direction_t{ left, right };
144
150 template<typename Type>
151 using remove_cv_ref_t = std::remove_cv_t<std::remove_reference_t<Type>>;
152
153 template<typename Type>
154 constexpr bool is_const_v = std::is_const_v<std::remove_reference_t<Type>>;
155
161 template<typename Type>
162 using decay_remove_cv_ref_t = std::remove_cv_t<std::remove_reference_t<std::decay_t<Type>>>;
163
169 template<typename Type>
170 using decay_remove_ref_t = std::remove_reference_t<std::decay_t<Type>>;
171
177 template<typename Type>
179
180 template<typename Type_1, typename Type_2>
181 auto maximum(Type_1 a, Type_2 b)
182 {
183 return a >= b ? a : b;
184 }
185
186 template<typename Type_1, typename Type_2, typename... Types>
187 auto maximum(Type_1 a, Type_2 b, Types... args)
188 {
189 if constexpr(sizeof...(args)==0)
190 return maximum(a, b);
191 else
192 return maximum(maximum(a, b), maximum(b, args...));
193 }
194
195 template<typename Type_1, typename Type_2>
196 auto minimum(Type_1 a, Type_2 b)
197 {
198 return b < a ? b : a;
199 }
200
201 template<typename Type_1, typename Type_2, typename... Types>
202 auto minimum(Type_1 a, Type_2 b, Types... args)
203 {
204 if constexpr(sizeof...(args)==0)
205 return minimum(a, b);
206 else
207 return minimum(minimum(a, b), minimum(b, args...));
208 }
209
215 template<typename Type>
216 constexpr bool is_const_reference_v =
217 std::is_reference_v<Type> && std::is_const_v<std::remove_reference_t<Type>>;
218
223 class debug_exception: public std::exception
224 {
225 private:
226 std::string m_message;
227 int m_lineno;
228 std::string m_file_name;
229 std::string m_what_msg;
230
231 public:
232 debug_exception(std::string message,
233 int lineno, std::string file_name):
234 m_lineno(lineno), m_message(message), m_file_name(file_name)
235 {
236 std::ostringstream os;
237
238 os << "debug_exception - file [" << this->m_file_name << "]\n";
239 os << "thread id [" << std::this_thread::get_id() << "] - ";
240 os << "line [" << this->m_lineno<<"]\n";
241 os << "message: " << this->m_message;
242
243 this->m_what_msg = os.str();
244 }
245
246 virtual const char* what() const noexcept override
247 {
248 return this->m_what_msg.c_str();
249 }
250
251 }; // end of class debug_exception
252
253 template<typename Type>
254 constexpr unsigned long long two_power_n(Type n)
255 {
256 unsigned long long two_power = 1;
257 return (two_power << (unsigned long long)n);
258 }
259
264 namespace types
265 {
266 template<typename Type>
267 inline constexpr auto type_max_v = std::numeric_limits<Type>::max();
268
269 inline constexpr size_t InvalidIndex = type_max_v<size_t>;
270 inline constexpr size_t SelectAll = InvalidIndex;
271
272 using big_integer_t = long long;
273 using big_unsigned_t = unsigned long long;
274
275 template<std::size_t KeyIndex, typename Type, auto Index, auto... Indices>
276 constexpr auto get_nth_value(std::integer_sequence<Type, Index, Indices...>) noexcept
277 {
278 if constexpr(KeyIndex == 0)
279 return Index;
280 else if constexpr(KeyIndex>0 && sizeof...(Indices) != 0)
281 {
282 return get_nth_value<KeyIndex-1>(std::integer_sequence<Type, Indices...>{});
283 }
284 else
285 return InvalidIndex;
286 }
287
288 template<auto Id, auto... Ids>
289 using index_t = std::index_sequence<(std::size_t)Id, (std::size_t)Ids...>;
290
291 template<auto N>
292 using make_index_t = std::make_index_sequence<(std::size_t)N>;
293
294 template<typename ...Types>
295 using index_for = std::make_index_sequence<sizeof...(Types)>;
296
297 template<typename Type>
299
300 template<typename Type, Type Tag = Type{}>
302 {
303 public:
304
305 using type = Type;
306 static constexpr Type tag = Tag;
307
308 protected:
310
311 public:
312
313 tag_type(Type v = Type{}) noexcept: value{ std::move(v) } { }
314
315 template<typename ArgType, typename... ArgTypes>
316 tag_type(ArgType arg, ArgTypes... args) noexcept:
317 value{ std::move(arg), std::move(args)... } { }
318
319 tag_type(const tag_type&) noexcept = default;
320 tag_type& operator=(const tag_type&) noexcept = default;
321
322 tag_type(tag_type&&) noexcept= default;
323 tag_type& operator=(tag_type&&) noexcept = default;
324
325 const Type& get() const noexcept { return value; }
326 Type& get() noexcept { return value; }
327
328 operator const Type&() const noexcept{ return get(); }
329 operator Type&() noexcept { return get(); }
330 };
331
332 namespace hidden
333 {
334 template<typename Type>
336 {
337 constexpr static bool value = false;
338 };
339
340 template<typename Type, int Tag>
342 {
343 constexpr static bool value = true;
344 };
345
346 template<typename Type>
348
349 template<typename Type>
351 {
352 constexpr static bool value = false;
353 };
354
355 template<template<auto...> class ContainerType, auto... Ints>
356 struct st_is_numbers_type_v<ContainerType<Ints...>>
357 {
358 constexpr static bool value = true;
359 };
360
361 }
362 // end of namespace hidden
363
364 template<typename Type>
365 constexpr bool is_tag_type_v = hidden::is_tag_type_v<remove_cvref_t<Type>>;
366
367 template<typename Type>
369
370 template<typename Type>
371 decltype(auto) get_value(Type&& arg)
372 {
373 if constexpr(is_tag_type_v<Type>)
374 {
375 if constexpr(std::is_rvalue_reference_v<decltype(arg)>)
376 return std::move(arg.value);
377 else
378 return arg.get();
379 }
380 else
381 return std::forward<Type>(arg);
382 }
383
384 namespace hidden
385 {
386 // assume non-primitive type
387 template<typename Type, auto Tag, bool = false>
389 {
390 using type = Type;
391 };
392
393 template<typename Type, auto Tag>
395 {
397 };
398
399 template<typename Type, auto Tag>
400 using non_class_wrapper_t = typename
402
403 }
404 // end of namespace hidden
405
406 template<typename Type, auto Tag>
408
409 template <class TargetType, class _Ty>
410 [[nodiscard]] constexpr std::enable_if_t<std::is_same_v<std::remove_reference_t<TargetType>,
411 std::remove_reference_t<_Ty>>, _Ty&&>
412 smart_forward(std::remove_reference_t<_Ty>& _Arg) noexcept
413 {
414 // std::cout <<"forwarding" << std::endl;
415 return static_cast<_Ty&&>(_Arg);
416 }
417
418 template <class TargetType, class _Ty>
419 [[nodiscard]] constexpr std::enable_if_t< !std::is_same_v<std::remove_reference_t<TargetType>,
420 std::remove_reference_t<_Ty>>, TargetType>
421 smart_forward(std::remove_reference_t<_Ty>& _Arg) noexcept
422 {
423 // std::cout <<"casting"<< std::endl;
424 return static_cast<TargetType>(_Arg);
425 }
426
427 template <class TargetType, class _Ty>
428 [[nodiscard]] constexpr std::enable_if_t< std::is_same_v<std::remove_reference_t<TargetType>,
429 std::remove_reference_t<_Ty>>, _Ty&&>
430 smart_forward(std::remove_reference_t<_Ty>&& _Arg) noexcept
431 {
432 // std::cout <<"forwarding" << std::endl;
433 static_assert(!std::is_lvalue_reference_v<_Ty>, "bad forward call");
434 return static_cast<_Ty&&>(_Arg);
435 }
436
437 template <class TargetType, class _Ty>
438 [[nodiscard]] constexpr std::enable_if_t< !std::is_same_v<std::remove_reference_t<TargetType>,
439 std::remove_reference_t<_Ty>>, TargetType>
440 smart_forward(std::remove_reference_t<_Ty>&& _Arg) noexcept
441 {
442 // std::cout <<"casting"<< std::endl;
443 return static_cast<TargetType>(_Arg);
444 }
445
446 template <class TargetType, class _Ty>
447 [[nodiscard]] constexpr std::enable_if_t< std::is_same_v<std::remove_reference_t<TargetType>,
448 std::remove_reference_t<_Ty>>, std::remove_reference_t<_Ty>&&>
449 smart_move(_Ty&& _Arg) noexcept
450 {
451 // forward _Arg as movable
452 return static_cast<std::remove_reference_t<_Ty>&&>(_Arg);
453 }
454
455 template <class TargetType, class _Ty>
456 [[nodiscard]] constexpr std::enable_if_t< !std::is_same_v<std::remove_reference_t<TargetType>,
457 std::remove_reference_t<_Ty>>, TargetType>
458 smart_move(_Ty&& _Arg) noexcept
459 {
460 // forward _Arg as movable
461 return static_cast<TargetType>(_Arg);
462 }
463
464 template<auto N, typename T, typename Deleter>
465 inline auto& cast_ref(std::unique_ptr<T[], Deleter>& uptr) noexcept
466 {
467 return reinterpret_cast<T(&)[N]>(uptr[0]);
468 }
469
470 template<auto N, typename T, typename Deleter>
471 inline auto& cast_ref(std::index_sequence<N>, std::unique_ptr<T[], Deleter>& uptr) noexcept
472 {
473 return reinterpret_cast<T(&)[N]>(uptr[0]);
474 }
475
476 template<auto N, typename T, typename Deleter>
477 inline auto& cast_ref(std::unique_ptr<T[], Deleter> const& uptr) noexcept
478 {
479 return reinterpret_cast<const T(&)[N]>(uptr[0]);
480 }
481
482 template<auto N, typename T, typename Deleter>
483 inline auto& cast_ref(std::index_sequence<N>, std::unique_ptr<T[], Deleter> const& uptr) noexcept
484 {
485 return reinterpret_cast<const T(&)[N]>(uptr[0]);
486 }
487
489 template<auto N1, auto N2, typename T, typename Deleter>
490 inline auto& cast_ref(std::unique_ptr<T[], Deleter>& uptr) noexcept
491 {
492 return reinterpret_cast<T(&)[N1][N2]>(uptr[0]);
493 }
494
495 template<auto N1, auto N2, typename T, typename Deleter>
496 inline auto& cast_ref(std::index_sequence<N1, N2>, std::unique_ptr<T[], Deleter>& uptr) noexcept
497 {
498 return reinterpret_cast<T(&)[N1][N2]>(uptr[0]);
499 }
500
501 template<auto N1, auto N2, typename T, typename Deleter>
502 inline auto& cast_ref(std::unique_ptr<T[], Deleter> const& uptr) noexcept
503 {
504 return reinterpret_cast<const T(&)[N1][N2]>(uptr[0]);
505 }
506
507 template<auto N1, auto N2, typename T, typename Deleter>
508 inline auto& cast_ref(std::index_sequence<N1, N2>, std::unique_ptr<T[], Deleter> const& uptr) noexcept
509 {
510 return reinterpret_cast<const T(&)[N1][N2]>(uptr[0]);
511 }
513 template<auto N1, auto N2, auto N3, typename T, typename Deleter>
514 inline auto& cast_ref(std::unique_ptr<T[], Deleter>& uptr) noexcept
515 {
516 return reinterpret_cast<T(&)[N1][N2][N3]>(uptr[0]);
517 }
518
519 template<auto N1, auto N2, auto N3, typename T, typename Deleter>
520 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, std::unique_ptr<T[], Deleter>& uptr) noexcept
521 {
522 return reinterpret_cast<T(&)[N1][N2][N3]>(uptr[0]);
523 }
524
525 template<auto N1, auto N2, auto N3, typename T, typename Deleter>
526 inline auto& cast_ref(std::unique_ptr<T[], Deleter> const& uptr) noexcept
527 {
528 return reinterpret_cast<const T(&)[N1][N2][N3]>(uptr[0]);
529 }
530
531 template<auto N1, auto N2, auto N3, typename T, typename Deleter>
532 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, std::unique_ptr<T[], Deleter> const& uptr) noexcept
533 {
534 return reinterpret_cast<const T(&)[N1][N2][N3]>(uptr[0]);
535 }
536
538
539 template<auto N1, auto N2, typename T, auto N,
540 typename = std::enable_if_t<N1* N2 == N>>
541 inline auto& cast_ref(T(&array)[N]) noexcept
542 {
543 using array2_t = T[N1][N2];
544 return reinterpret_cast<array2_t&>(array[0]);
545 }
546
547 template<auto N1, auto N2, typename T, auto N,
548 typename = std::enable_if_t<N1* N2 == N>>
549 inline auto& cast_ref(std::index_sequence<N1, N2>, T(&array)[N]) noexcept
550 {
551 using array2_t = T[N1][N2];
552 return reinterpret_cast<array2_t&>(array[0]);
553 }
554
555 template<auto N1, auto N2, typename T, auto N = N1 * N2>
556 inline auto& cast_ref(T(&array)[N1][N2]) noexcept
557 {
558 using array_t = T[N];
559 return reinterpret_cast<array_t&>(array[0][0]);
560 }
561
562 template<auto N1, auto N2, typename T, auto N = N1 * N2>
563 inline auto& cast_ref(std::index_sequence<N1, N2>, T(&array)[N1][N2]) noexcept
564 {
565 using array_t = T[N];
566 return reinterpret_cast<array_t&>(array[0][0]);
567 }
568
569 template<auto N1, auto N2, auto N3, typename T, auto N,
570 typename = std::enable_if_t<N1* N2* N3 == N>>
571 inline auto& cast_ref(T(&array)[N]) noexcept
572 {
573 using array3_t = T[N1][N2][N3];
574 return reinterpret_cast<array3_t&>(array[0]);
575 }
576
577 template<auto N1, auto N2, auto N3, typename T, auto N,
578 typename = std::enable_if_t<N1* N2* N3 == N>>
579 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, T(&array)[N]) noexcept
580 {
581 using array3_t = T[N1][N2][N3];
582 return reinterpret_cast<array3_t&>(array[0]);
583 }
584
585 template<auto N1, auto N2, auto N3, typename T, auto N = N1 * N2* N3>
586 inline auto& cast_ref(T(&array)[N1][N2][N3]) noexcept
587 {
588 using array_t = T[N];
589 return reinterpret_cast<array_t&>(array[0][0][0]);
590 }
591
592 template<auto N1, auto N2, auto N3, typename T, auto N = N1 * N2* N3>
593 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, T(&array)[N1][N2][N3]) noexcept
594 {
595 using array_t = T[N];
596 return reinterpret_cast<array_t&>(array[0][0][0]);
597 }
598
599 template<auto N, typename T,
600 typename = std::enable_if_t<std::is_pointer_v<T>>>
601 inline auto& cast_ref(T array) noexcept
602 {
603 using ele_t = std::remove_pointer_t<T>;
604
605 using array_t = ele_t[N];
606 return reinterpret_cast<array_t&>(array[0]);
607 }
608
609 template<auto N1, auto N2, typename T,
610 typename = std::enable_if_t<std::is_pointer_v<T>>>
611 inline auto& cast_ref(T array) noexcept
612 {
613 using ele_t = std::remove_pointer_t<T>;
614
615 using array_t = ele_t[N1][N2];
616 return reinterpret_cast<array_t&>(array[0]);
617 }
618
619 template<auto N1, auto N2, auto N3, typename T,
620 typename = std::enable_if_t<std::is_pointer_v<T>>>
621 inline auto& cast_ref(T array) noexcept
622 {
623 using ele_t = std::remove_pointer_t<T>;
624
625 using array_t = ele_t[N1][N2][N3];
626 return reinterpret_cast<array_t&>(array[0]);
627 }
628
629 template<auto N, typename T,
630 typename = std::enable_if_t<std::is_pointer_v<T>>>
631 inline auto& cast_ref(std::index_sequence<N>, T array) noexcept
632 {
633 using ele_t = std::remove_pointer_t<T>;
634 using array_t = ele_t[N];
635 return reinterpret_cast<array_t&>(array[0]);
636 }
637
638 template<auto N1, auto N2, typename T,
639 typename = std::enable_if_t<std::is_pointer_v<T>>>
640 inline auto& cast_ref(std::index_sequence<N1, N2>, T array) noexcept
641 {
642 using ele_t = std::remove_pointer_t<T>;
643 using array_t = ele_t[N1][N2];
644 return reinterpret_cast<array_t&>(array[0]);
645 }
646
647 template<auto N1, auto N2, auto N3, typename T,
648 typename = std::enable_if_t<std::is_pointer_v<T>>>
649 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, T array) noexcept
650 {
651 using ele_t = std::remove_pointer_t<T>;
652
653 using array_t = ele_t[N1][N2][N3];
654 return reinterpret_cast<array_t&>(array[0]);
655 }
656
657 template<std::size_t N1, typename T, std::size_t N,
658 typename = std::enable_if_t<N1 == N>>
659 inline auto& cast_ref(std::array<T, N>& array) noexcept
660 {
661 using c_array_t = T[N];
662 return reinterpret_cast<c_array_t&>(array[0]);
663 }
664
665 template<std::size_t N1, typename T, std::size_t N,
666 typename = std::enable_if_t<N1 == N>>
667 inline auto& cast_ref(std::array<T, N> const& array) noexcept
668 {
669 using c_array_t = const T[N];
670 return reinterpret_cast<c_array_t&>(array[0]);
671 }
672
673 template<std::size_t N1, std::size_t N2, typename T, std::size_t N,
674 typename = std::enable_if_t< N1 * N2 == N>>
675 inline auto& cast_ref(std::array<T, N>& array) noexcept
676 {
677 using c_array_t = T[N1][N2];
678 return reinterpret_cast<c_array_t&>(array[0]);
679 }
680
681 template<std::size_t N1, std::size_t N2, typename T, std::size_t N,
682 typename = std::enable_if_t< N1 * N2 == N>>
683 inline auto& cast_ref(std::array<T, N> const& array) noexcept
684 {
685 using c_array_t = const T[N1][N2];
686 return reinterpret_cast<c_array_t&>(array[0]);
687 }
688
689 template<std::size_t N1, typename T, std::size_t N,
690 typename = std::enable_if_t< N1 == N>>
691 inline auto& cast_ref(std::index_sequence<N1>, std::array<T, N>& array) noexcept
692 {
693 using c_array_t = T[N1];
694 return reinterpret_cast<c_array_t&>(array[0]);
695 }
696
697 template<std::size_t N1, typename T, std::size_t N,
698 typename = std::enable_if_t< N1 == N>>
699 inline auto& cast_ref(std::index_sequence<N1>, std::array<T, N> const& array) noexcept
700 {
701 using c_array_t = const T[N1];
702 return reinterpret_cast<c_array_t&>(array[0]);
703 }
704
705 template<std::size_t N1, std::size_t N2, typename T, std::size_t N,
706 typename = std::enable_if_t< N1 * N2 == N>>
707 inline auto& cast_ref(std::index_sequence<N1, N2>, std::array<T, N>& array) noexcept
708 {
709 using c_array_t = T[N1][N2];
710 return reinterpret_cast<c_array_t&>(array[0]);
711 }
712
713 template<std::size_t N1, std::size_t N2, typename T, std::size_t N,
714 typename = std::enable_if_t< N1 * N2 == N>>
715 inline auto& cast_ref(std::index_sequence<N1, N2>, std::array<T, N> const& array) noexcept
716 {
717 using c_array_t = const T[N1][N2];
718 return reinterpret_cast<c_array_t&>(array[0]);
719 }
720
721 template<std::size_t N1, std::size_t N2, std::size_t N3, typename T, std::size_t N,
722 typename = std::enable_if_t< N1 * N2 * N3 == N>>
723 inline auto& cast_ref(std::array<T, N>& array) noexcept
724 {
725 using c_array_t = T[N1][N2][N3];
726 return reinterpret_cast<c_array_t&>(array[0]);
727 }
728
729 template<std::size_t N1, std::size_t N2, std::size_t N3, typename T, std::size_t N,
730 typename = std::enable_if_t< N1 * N2 * N3 == N>>
731 inline auto& cast_ref(std::array<T, N> const& array) noexcept
732 {
733 using c_array_t = const T[N1][N2][N3];
734 return reinterpret_cast<c_array_t&>(array[0]);
735 }
736
737 template<std::size_t N1, std::size_t N2, std::size_t N3, typename T, std::size_t N,
738 typename = std::enable_if_t< N1 * N2 * N3 == N>>
739 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, std::array<T, N>& array) noexcept
740 {
741 using c_array_t = T[N1][N2][N3];
742 return reinterpret_cast<c_array_t&>(array[0]);
743 }
744
745 template<std::size_t N1, std::size_t N2, std::size_t N3, typename T, std::size_t N,
746 typename = std::enable_if_t< N1 * N2 * N3 == N>>
747 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, std::array<T, N> const& array) noexcept
748 {
749 using c_array_t = const T[N1][N2][N3];
750 return reinterpret_cast<c_array_t&>(array[0]);
751 }
752
754
755 template<std::size_t N, typename T>
756 inline auto& cast_ref(std::vector<T>& vctr) noexcept
757 {
758 assert(N == vctr.size());
759
760 using c_array_t = T[N];
761 return reinterpret_cast<c_array_t&>(vctr[0]);
762 }
763
764 template<std::size_t N, typename T>
765 inline auto& cast_ref(std::vector<T> const& vctr) noexcept
766 {
767 assert(N == vctr.size());
768
769 using c_array_t = const T[N];
770 return reinterpret_cast<c_array_t&>(vctr[0]);
771 }
772
773 template<std::size_t N, typename T>
774 inline auto& cast_ref(std::index_sequence<N>, std::vector<T>& vctr) noexcept
775 {
776 assert(N == vctr.size());
777
778 using c_array_t = T[N];
779 return reinterpret_cast<c_array_t&>(vctr[0]);
780 }
781
782 template<std::size_t N, typename T>
783 inline auto& cast_ref(std::index_sequence<N>, std::vector<T> const& vctr) noexcept
784 {
785 assert(N == vctr.size());
786
787 using c_array_t = const T[N];
788 return reinterpret_cast<c_array_t&>(vctr[0]);
789 }
790
791 template<std::size_t N1, std::size_t N2, typename T>
792 inline auto& cast_ref(std::vector<T>& vctr) noexcept
793 {
794 assert(N1 * N2 == vctr.size());
795
796 using c_array_t = T[N1][N2];
797 return reinterpret_cast<c_array_t&>(vctr[0]);
798 }
799
800 template<std::size_t N1, std::size_t N2, typename T>
801 inline auto& cast_ref(std::vector<T> const& vctr) noexcept
802 {
803 assert(N1 * N2 == vctr.size());
804
805 using c_array_t = const T[N1][N2];
806 return reinterpret_cast<c_array_t&>(vctr[0]);
807 }
808
809 template<std::size_t N1, std::size_t N2, typename T>
810 inline auto& cast_ref(std::index_sequence<N1, N2>, std::vector<T>& vctr) noexcept
811 {
812 assert(N1 * N2 == vctr.size());
813
814 using c_array_t = T[N1][N2];
815 return reinterpret_cast<c_array_t&>(vctr[0]);
816 }
817
818 template<std::size_t N1, std::size_t N2, typename T>
819 inline auto& cast_ref(std::index_sequence<N1, N2>, std::vector<T> const& vctr) noexcept
820 {
821 assert(N1 * N2 == vctr.size());
822
823 using c_array_t = const T[N1][N2];
824 return reinterpret_cast<c_array_t&>(vctr[0]);
825 }
826
827 template<std::size_t N1, std::size_t N2, std::size_t N3, typename T>
828 inline auto& cast_ref(std::vector<T>& vctr) noexcept
829 {
830 assert(N1 * N2 * N3 == vctr.size());
831
832 using c_array_t = T[N1][N2][N3];
833 return reinterpret_cast<c_array_t&>(vctr[0]);
834 }
835
836 template<std::size_t N1, std::size_t N2, std::size_t N3, typename T>
837 inline auto& cast_ref(std::vector<T> const& vctr) noexcept
838 {
839 assert(N1 * N2 * N3 == vctr.size());
840
841 using c_array_t = const T[N1][N2][N3];
842 return reinterpret_cast<c_array_t&>(vctr[0]);
843 }
844
845 template<std::size_t N1, std::size_t N2, std::size_t N3, typename T>
846 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, std::vector<T>& vctr) noexcept
847 {
848 assert(N1 * N2 * N3 == vctr.size());
849
850 using c_array_t = T[N1][N2][N3];
851 return reinterpret_cast<c_array_t&>(vctr[0]);
852 }
853
854 template<std::size_t N1, std::size_t N2, std::size_t N3, typename T>
855 inline auto& cast_ref(std::index_sequence<N1, N2, N3>, std::vector<T> const& vctr) noexcept
856 {
857 assert(N1 * N2 * N3 == vctr.size());
858
859 using c_array_t = const T[N1][N2][N3];
860 return reinterpret_cast<c_array_t&>(vctr[0]);
861 }
862
863 template<size_t N1, size_t N2, typename T, size_t N,
864 typename = std::enable_if_t<N1* N2 == N>>
865 inline auto cast_array(T(&array)[N]) noexcept
866 {
867 using array_t = T[N1][N2];
868 return *reinterpret_cast<array_t*>(array);
869 }
870
871 template<size_t N1, size_t N2, typename T, size_t N = N1 * N2>
872 inline auto cast_array(T(&array)[N1][N2]) noexcept
873 {
874 using array_t = T[N];
875 return *reinterpret_cast<array_t*>(array);
876 }
877
878 template<size_t N1, size_t N2, size_t N3, typename T, size_t N,
879 typename = std::enable_if_t<N1* N2* N3 == N>>
880 inline auto cast_array(T(&array)[N]) noexcept
881 {
882 using array_t = T[N1][N2][N3];
883 return *reinterpret_cast<array_t*>(array);
884 }
885
886 template<size_t N1, size_t N2, size_t N3, typename T, size_t N = N1 * N2* N3>
887 inline auto cast_array(T(&array)[N1][N2][N3]) noexcept
888 {
889 using array_t = T[N];
890 return *reinterpret_cast<array_t*>(array);
891 }
892
893 template<typename T, size_t N>
894 inline auto cast_array(std::array<T, N>& array) noexcept
895 {
896 using c_array_t = T[N];
897 return *reinterpret_cast<c_array_t*>(array.data());
898 }
899
900 template<typename T, size_t N>
901 inline auto cast_array(std::array<T, N> const& array) noexcept
902 {
903 using c_array_t = const T[N];
904 return *reinterpret_cast<c_array_t*>(array.data());
905 }
906
907 template<size_t N1, size_t N2, typename T, size_t N,
908 typename = std::enable_if_t< N1 * N2 == N>>
909 inline auto cast_array(std::array<T, N>& array) noexcept
910 {
911 using c_array_t = T[N1][N2];
912 return *reinterpret_cast<c_array_t*>(array.data());
913 }
914
915 template<size_t N1, size_t N2, typename T, size_t N,
916 typename = std::enable_if_t< N1 * N2 == N>>
917 inline auto cast_array(std::array<T, N> const& array) noexcept
918 {
919 using c_array_t = const T[N1][N2];
920 return *reinterpret_cast<c_array_t*>(array.data());
921 }
922
923 template<size_t N1, size_t N2, size_t N3, typename T, size_t N,
924 typename = std::enable_if_t< N1 * N2 * N3 == N>>
925 inline auto cast_array(std::array<T, N>& array) noexcept
926 {
927 using c_array_t = T[N1][N2][N3];
928 return *reinterpret_cast<c_array_t*>(array.data());
929 }
930
931 template<size_t N1, size_t N2, size_t N3, typename T, size_t N,
932 typename = std::enable_if_t< N1 * N2 * N3 == N>>
933 inline auto cast_array(std::array<T, N> const& array) noexcept
934 {
935 using c_array_t = T[N1][N2][N3];
936 return *reinterpret_cast<c_array_t*>(array.data());
937 }
938
939 // always returns lvalue reference
940 template<auto Index, typename... ArgTypes,
941 typename = std::enable_if_t<(Index < sizeof...(ArgTypes))>>
942 decltype(auto) get_nth_argument(ArgTypes&&... args)
943 {
944 auto arguments = std::forward_as_tuple( std::forward<ArgTypes>(args)... );
945
946 using element_t = decltype(std::get<Index>(arguments));
947
948 return std::forward<element_t>(std::get<Index>(arguments));
949 }
950
956 template<typename... Types> struct type_list_t{};
957 template<auto... Ints> struct numbers_t{};
958
959 template<typename T, size_t Size>
960 auto convert_to_tuple(const std::array<T, Size>& array);
961
962 template<typename Type, auto Size>
963 using create_tuple_t = decltype(types::convert_to_tuple(std::array<Type, Size>{}));
964
965 namespace hidden
966 {
967 template<typename Type>
969 {
970 static constexpr bool value = false;
971 };
972
973 template<typename Type, typename... Types>
974 struct st_is_vector_v<std::vector<Type, Types...>>
975 {
976 static constexpr bool value = true;
977 };
978
979 template<typename Type>
981 {
982 static constexpr bool value = false;
983 };
984
985 template<typename Type, auto... Indices>
986 struct st_is_integer_sequence<std::integer_sequence<Type, Indices...>>
987 {
988 static constexpr bool value = true;
989 };
990
991 template<typename Type>
993
994 template<typename T>
996 {
997 static constexpr bool value = false;
998 };
999
1000 template<typename... Ts>
1002 {
1003 static constexpr bool value = true;
1004 };
1005
1006 template<typename T>
1008
1009 template<typename T>
1011 {
1012 using type = T;
1013 };
1014
1015 template<template<typename...> class TemplateType, typename... Types>
1016 struct st_recursive_type_list<TemplateType<Types...>>
1017 {
1019 };
1020
1021 template<typename T>
1023
1024 }
1025 // end of namespace hidden
1026
1027 template<typename Type>
1029
1030 template<typename Type>
1031 constexpr bool is_integer_sequence_v = hidden::is_integer_sequence_v<remove_cvref_t<Type>>;
1032
1033 template<typename T>
1034 constexpr bool is_type_list_v = hidden::is_type_list_v<remove_cv_ref_t<T>>;
1035
1036 template<typename T>
1038
1044 template<typename... Types>
1046
1052 template<typename... Types>
1054
1060 template<typename... Types>
1062
1064
1065 template<template<typename...> class TemplateType>
1066 constexpr auto template_category() { return TemplateCategory::Type; }
1067
1068 template<template<typename T, auto...> class TemplateType>
1069 constexpr auto template_category() { return TemplateCategory::Type_Value; }
1070
1071 template<template<auto...> class TemplateType>
1072 constexpr auto template_category() { return TemplateCategory::Value; }
1073
1074 template<template<auto, typename...> class TemplateType>
1075 constexpr auto template_category() { return TemplateCategory::Value_Type; }
1076
1077 template<typename>
1078 constexpr auto template_category(...) { return TemplateCategory::Unknown; }
1079
1080 namespace hidden
1081 {
1082 template<typename Type>
1084 {
1085 static constexpr bool value = false;
1086 };
1087
1088 template<template<typename...> class TemplateType, typename... Types>
1089 struct st_is_template_type<TemplateType<Types...>>
1090 {
1091 static constexpr bool value = true;
1092 };
1093
1094 template<template<typename T, auto...> class TemplateType, typename T, T... args>
1095 struct st_is_template_type<TemplateType<T, args...>>
1096 {
1097 static constexpr bool value = true;
1098 };
1099
1100 template<template<auto...> class TemplateType, auto... args>
1101 struct st_is_template_type<TemplateType<args...>>
1102 {
1103 static constexpr bool value = true;
1104 };
1105
1106 template<template<auto, typename...> class TemplateType, auto arg, typename... Types>
1107 struct st_is_template_type<TemplateType<arg, Types...>>
1108 {
1109 static constexpr bool value = true;
1110 };
1111
1112 template<typename Type>
1114 }
1115 // end of namespace hidden
1116
1117 template<typename Type>
1118 constexpr bool is_template_type_v = hidden::is_template_type_v<remove_cvref_t<Type>>;
1119
1120 namespace hidden
1121 {
1122 template<typename... Types>
1124 {
1125 using type = std::tuple< std::vector<Types>... >;
1126 };
1127
1128 template<typename... Types>
1130 {
1131 using type = std::tuple<std::vector<Types>... >;
1132 };
1133
1134 template<template<typename...> class CntrType, typename... Types>
1135 struct st_type_list_to_tuple_of_vectors<CntrType<Types...>>
1136 {
1137 using type = std::tuple< std::vector<Types>... >;
1138 };
1139
1140 template<typename TupleType>
1142
1143 template<typename... Types>
1144 struct st_tuple_to_type_list<std::tuple<Types...>>
1145 {
1146 using type = type_list_t<Types...>;
1147 };
1148
1149 template<typename TupleType>
1151
1152 template<typename TypeList>
1154
1155 template<typename... Types>
1157 {
1158 using type = std::tuple<Types...>;
1159 };
1160
1161 template<typename TypeList>
1163
1164 template<typename TupleType>
1166
1167 template<typename... Types>
1168 struct st_variant_to_type_list<std::variant<Types...>>
1169 {
1170 using type = type_list_t<Types...>;
1171 };
1172
1173 template<typename VarType>
1175
1176 }
1177 // end of namespace hidden
1178
1179 template<typename TupleType>
1181
1182 template<typename TypeList>
1184
1185 template<typename VarType>
1187
1188 template<typename... Types>
1190
1191 namespace hidden
1192 {
1193 template<std::size_t ...I>
1195 {
1196 using type = std::vector<std::size_t>;
1197 };
1198
1199 template<typename Type> struct st_index_tuple_vector;
1200
1201 template<std::size_t ...Is>
1202 struct st_index_tuple_vector<std::index_sequence<Is...>>
1203 {
1204 using type = std::tuple<typename st_vector<Is>::type...>;
1205 };
1206
1207 }
1208 // end of namespace hidden
1209
1210 template<std::size_t N>
1212
1213 template<typename PointerType, typename SizeType>
1214 struct array_wrapper_t: public std::pair<PointerType, SizeType>
1215 {
1216 public:
1217 using base_type = std::pair<PointerType, SizeType>;
1218
1219 template<typename ElementType, size_t ElementCount>
1220 array_wrapper_t(ElementType(&array)[ElementCount]) noexcept:
1221 std::pair<ElementType*, size_t>{array, ElementCount} { }
1222 };
1223
1224 template<typename ElementType, size_t ElementCount>
1226
1227 template<typename ElementType, size_t ElementSize>
1228 auto array_wrapper(ElementType(&array)[ElementSize]) noexcept
1229 {
1231 }
1232
1233 template<typename Type>
1234 auto to_ref(const Type& value) { return std::ref(const_cast<Type&>(value)); }
1235
1236 template<typename Type>
1237 constexpr bool is_array_v = std::is_array_v<remove_cv_ref_t<Type>>;
1238
1239 template<typename ElementType, size_t ElementSize>
1240 constexpr size_t array_size(ElementType(&array)[ElementSize]) noexcept { return (size_t) ElementSize; }
1241
1242 // forward declaration
1243 template<typename ContainerType> class reverse_st;
1244 template<typename ContainerType> auto reverse(ContainerType&& container);
1245 template<typename ElementType, size_t ElementCount> auto reverse(ElementType(&array)[ElementCount]);
1246
1247 template<typename Type, typename... Types> auto reverse(Type&& arg, Types&&... args);
1248 template<typename Type, typename... Types> auto make_vector(Type&& arg, Types&&... args);
1249 template<typename Type, typename... Types> auto make_container(Type&& arg, Types&&... args);
1250
1251 template< template<typename, std::size_t> class ContainerType,
1252 typename ArgType, typename... ArgTypes>
1253 auto make_container(ArgType&& arg, ArgTypes&& ... args);
1254
1255 template< template<typename, std::size_t> class ContainerType,
1256 typename ArgType, typename... ArgTypes>
1257 auto make_container(ArgType&& arg, ArgTypes&& ... args);
1258
1259 template<typename ContainerType, typename IndexType>
1260 decltype(auto) get_element(ContainerType container, IndexType index);
1261
1262 #if !defined(__clang_major__)
1263 template<typename Type, typename... Types> auto make_variants(Type&& arg, Types&&... args);
1264 #endif
1265
1266 template<typename Type>
1267 decltype(auto) decay(Type&& arg)
1268 {
1269 using type = std::remove_reference_t<Type>;
1270
1271 if constexpr(std::is_array_v<type> || std::is_function_v<type>)
1272 return decay_remove_cv_ref_t<type>(arg);
1273 else
1274 return std::forward<Type>(arg);
1275 }
1276
1277 namespace hidden
1278 {
1279 template<typename Type>
1281 }
1282
1290 template<typename Type>
1291 std::string type_to_string()
1292 {
1293 #ifdef __NVCC__
1294
1295 { std::string fname = typeid(hidden::st_dummy_type_container<Type>).name();
1296
1297 const char* to_str = "struct tpf::types::hidden::st_dummy_type_container<";
1298
1299 std::size_t len = strlen(to_str);
1300
1301 auto pos = fname.find(to_str);
1302
1303 if(pos != fname.npos) // we found substring
1304 fname = fname.substr(pos + len);
1305
1306 // remove trailing "> "
1307 fname.pop_back();
1308
1310
1311 to_str = " __ptr64"; len = strlen(to_str);
1312 while( (pos = fname.find(to_str)) != fname.npos)
1313 fname.erase(pos, len);
1314
1315 to_str = " __ptr32"; len = strlen(to_str);
1316 while( (pos = fname.find(to_str)) != fname.npos)
1317 fname.erase(pos, len);
1318
1319 to_str = "enum class"; len = strlen(to_str);
1320 while( (pos = fname.find(to_str)) != fname.npos)
1321 fname.erase(pos, len);
1322
1323 to_str = "enum"; len = strlen(to_str);
1324 while( (pos = fname.find(to_str)) != fname.npos)
1325 fname.erase(pos, len);
1326
1327 to_str = "class"; len = strlen(to_str);
1328 while( (pos = fname.find(to_str)) != fname.npos)
1329 fname.erase(pos, len);
1330
1331 to_str = "struct"; len = strlen(to_str);
1332 while( (pos = fname.find(to_str)) != fname.npos)
1333 fname.erase(pos, len);
1334
1335 while(fname.back() == ' ') fname.pop_back();
1336
1337 return fname;
1338 }
1339
1340 #elif defined(__FUNCSIG__)
1341 std::string fname(__FUNCSIG__);
1342 const char* to_str = "to_string<";
1343 size_t len = strlen(to_str);
1344 auto pos = fname.find("to_string<");
1345 fname = fname.substr(pos+len);
1346 fname = fname.substr(0, fname.find_last_of('>'));
1347
1349
1350 to_str = " __ptr64"; len = strlen(to_str);
1351 while( (pos = fname.find(to_str)) != fname.npos)
1352 fname.erase(pos, len);
1353
1354 to_str = " __ptr32"; len = strlen(to_str);
1355 while( (pos = fname.find(to_str)) != fname.npos)
1356 fname.erase(pos, len);
1357
1358 to_str = "enum class"; len = strlen(to_str);
1359 while( (pos = fname.find(to_str)) != fname.npos)
1360 fname.erase(pos, len);
1361
1362 to_str = "enum"; len = strlen(to_str);
1363 while( (pos = fname.find(to_str)) != fname.npos)
1364 fname.erase(pos, len);
1365
1366 to_str = "class"; len = strlen(to_str);
1367 while( (pos = fname.find(to_str)) != fname.npos)
1368 fname.erase(pos, len);
1369
1370 to_str = "struct"; len = strlen(to_str);
1371 while( (pos = fname.find(to_str)) != fname.npos)
1372 fname.erase(pos, len);
1373
1374 while(fname.back() == ' ') fname.pop_back();
1375
1376 return fname;
1377 #else
1378
1379 std::string fname(__PRETTY_FUNCTION__);
1380
1381 #ifdef __clang_major__
1382 const char* ftext = "[Type = ";
1383 auto pos = fname.find(ftext) + strlen(ftext);
1384 fname = fname.substr(pos);
1385 fname.pop_back();
1386 return fname;
1387
1388 #elif defined(__ICL)
1389 const char* ftext = "type_to_string<";
1390 auto pos = fname.find(ftext) + strlen(ftext);
1391 fname = fname.substr(pos);
1392 pos = fname.find_last_of('>');
1393 return fname.substr(0, pos);
1394 #else
1395 const char* ftext = "[with Type = ";
1396 auto pos = fname.find(ftext) + strlen(ftext);
1397 fname = fname.substr(pos);
1398 pos = fname.find_first_of(';');
1399 return fname.substr(0, pos);
1400 #endif
1401 #endif
1402
1403 } // end of type_to_string()
1404
1405 } // end of namespace types
1406
1407} // end of namespace tpf
1408
1409#define Tpf_DebugException(debug_message) tpf::debug_exception{debug_message, __LINE__, __FILE__}
1410
1411
1416#define Tpf_ThrowDebugException(debug_message) throw tpf::debug_exception{debug_message, __LINE__, __FILE__}
1417
1422#define Tpf_GetTypeName(type_arg) tpf::types::type_to_string<type_arg>()
1423
1428#define Tpf_GetTypeCategory(instance_arg) Tpf_GetTypeName(decltype(instance_arg))
1429
1434#define Tpf_GetValueCategory(instance_arg) Tpf_GetTypeName(decltype((instance_arg)))
1435
1436namespace tpf::types
1437{
1438 template<typename Type>
1439 struct range
1440 {
1442
1443 union
1444 {
1446 };
1447 };
1448
1449 template<typename Type>
1450 std::ostream& operator<<(std::ostream& os, range<Type> const& r)
1451 {
1452 os <<"<" << r.begin<<", " << r.end << ">"; return os;
1453 }
1454
1455 template<typename Type>
1456 range(Type)->range<Type>;
1457
1458 template<typename Type>
1459 range(Type, Type)->range<Type>;
1460
1461} // end of namespace tpf::types
1462
1467namespace tpf
1468{
1469 template<typename IndexType, typename ContainerType,
1470 typename container_t = tpf::remove_cv_ref_t<ContainerType>,
1471 typename iterator_type = typename container_t::iterator>
1472 auto index_to_iterator(ContainerType&& cntr, IndexType&& index);
1473
1474 template<typename IndexType, typename ContainerType,
1475 typename container_t = tpf::remove_cv_ref_t<ContainerType>,
1476 typename reverse_iterator_type = typename container_t::reverse_iterator>
1477 auto index_to_reverse_iterator(ContainerType&& cntr, IndexType&& offset);
1478
1479 template<typename ContainerType,
1480 typename container_t = tpf::remove_cv_ref_t<ContainerType>,
1481 typename iterator_type = typename container_t::iterator>
1482 auto iterator_to_index(ContainerType&& cntr, iterator_type&& offset);
1483
1484 template<typename ContainerType,
1485 typename container_t = tpf::remove_cv_ref_t<ContainerType>,
1486 typename reverse_iterator_type = typename container_t::reverse_iterator>
1487 auto reverse_iterator_to_index(ContainerType&& cntr, reverse_iterator_type&& offset);
1488
1489 template<typename ReverseIteratorType,
1490 typename reverse_iterator_type = std::remove_reference_t<ReverseIteratorType>>
1491 inline auto reverse_iterator_to_iterator(ReverseIteratorType&& itr)
1492 {
1493 return itr.base() - 1;
1494 }
1495
1496 template<typename IteratorType,
1497 typename iterator_type = std::remove_reference_t<IteratorType>>
1498 inline auto iterator_to_reverse_iterator(IteratorType&& itr)
1499 {
1500 return std::make_reverse_iterator(std::forward<IteratorType>(itr));
1501 }
1502
1503 template<direction_t direction = direction_t::left,
1504 typename ContainerType = std::vector<int>,
1505 typename container_t = tpf::remove_cv_ref_t<ContainerType>,
1506 typename iterator_type = typename container_t::iterator,
1507 typename reverse_iterator_type = typename container_t::reverse_iterator>
1508 auto make_rotator(ContainerType&& cntr);
1509
1510 template<direction_t direction = direction_t::left,
1511 typename ContainerType = std::vector<int>,
1512 typename container_t = tpf::remove_cv_ref_t<ContainerType>,
1513 typename iterator_type = typename container_t::iterator,
1514 typename reverse_iterator_type = typename container_t::reverse_iterator,
1515 typename execution_policy_type = std::execution::parallel_unsequenced_policy>
1516 auto make_rotator(ContainerType&& cntr, execution_policy_type policy);
1517
1518 template<typename ForwardIterator, typename EleType, typename CompareCallbackType = std::less<>>
1519 auto find_range_iterators(ForwardIterator first, ForwardIterator last,
1520 const EleType& value, CompareCallbackType&& compare_callback = CompareCallbackType{})
1521 {
1522 auto range = std::equal_range(first, last, value, std::forward<CompareCallbackType>(compare_callback));
1523
1524 return std::make_tuple(std::distance(range.first, range.second), range.first, range.second);
1525 }
1526
1527 template<typename ForwardIterator, typename EleType, typename CompareCallbackType = std::less<>>
1528 auto find_range_indices(ForwardIterator first, ForwardIterator last,
1529 const EleType& value, CompareCallbackType&& compare_callback = CompareCallbackType{})
1530 {
1531 auto range = std::equal_range(first, last, value, std::forward<CompareCallbackType>(compare_callback));
1532
1533 return std::make_tuple(std::distance(range.first, range.second),
1534 std::distance(first, range.first), std::distance(first, range.second));
1535 }
1536
1537 template<typename EleType, template<typename, typename...> class ContainerType, typename... Types,
1538 typename CompareCallbackType = std::less<>>
1539 auto find_range_iterators(const ContainerType<EleType, Types...>& container, const EleType& value,
1540 CompareCallbackType&& compare_callback = CompareCallbackType{})
1541 {
1542 return find_range_iterators(container.cbegin(), container.cend(),
1543 value, std::forward<CompareCallbackType>(compare_callback));
1544 }
1545
1546 template<typename EleType, template<typename, typename...> class ContainerType, typename... Types,
1547 typename CompareCallbackType = std::less<>>
1548 auto find_range_indices(const ContainerType<EleType, Types...>& container, const EleType& value,
1549 CompareCallbackType&& compare_callback = CompareCallbackType{})
1550 {
1551 return find_range_indices(container.cbegin(), container.cend(),
1552 value, std::forward<CompareCallbackType>(compare_callback));
1553 }
1554
1555 template<typename ForwardIterator, typename EleType, typename CompareCallbackType = std::less<>>
1556 auto binary_find_iterator(ForwardIterator first, ForwardIterator last,
1557 const EleType& value, CompareCallbackType&& compare_callback = CompareCallbackType{})
1558 {
1559 auto start = std::lower_bound(first, last, value, compare_callback);
1560
1561 return start != last && !compare_callback(value, *start) ? start : last;
1562 }
1563
1564 template<typename ForwardIterator, typename EleType, typename CompareCallbackType = std::less<>>
1565 auto binary_find_index(ForwardIterator first, ForwardIterator last,
1566 const EleType& value, CompareCallbackType&& compare_callback = CompareCallbackType{})
1567 {
1568 auto start = std::lower_bound(first, last, value, compare_callback);
1569
1570 auto iterator = (start != last && !compare_callback(value, *start)) ? start : last;
1571
1572 return (iterator != last) ?
1573 std::distance(first, iterator) : std::distance(first, last);
1574 }
1575
1576 template<typename EleType, template<typename, typename...> class ContainerType, typename... Types,
1577 typename CompareCallbackType = std::less<>>
1578 auto binary_find_iterator(const ContainerType<EleType, Types...>& container, const EleType& value,
1579 CompareCallbackType&& compare_callback = CompareCallbackType{})
1580 {
1581 return binary_find_iterator(container.cbegin(), container.cend(), value,
1582 std::forward<CompareCallbackType>(compare_callback));
1583 }
1584
1585 template<typename ForwardIterator, typename EleType, typename CompareCallbackType = std::less<>>
1586 auto binary_find_bool_iterator_pair(ForwardIterator first, ForwardIterator last,
1587 const EleType& value, CompareCallbackType&& compare_callback = CompareCallbackType{})
1588 {
1589 auto iterator = binary_find_iterator(first, last, value,
1590 std::forward<CompareCallbackType>(compare_callback));
1591
1592 return (iterator != last) ?
1593 std::make_pair(true, iterator) : std::make_pair(false, iterator);
1594 }
1595
1596 template<typename EleType, template<typename, typename...> class ContainerType, typename... Types,
1597 typename CompareCallbackType = std::less<>>
1598 auto binary_find_bool_iterator_pair(const ContainerType<EleType, Types...>& container, const EleType& value,
1599 CompareCallbackType&& compare_callback = CompareCallbackType{})
1600 {
1601 return binary_find_bool_iterator_pair(container.cbegin(), container.cend(), value,
1602 std::forward<CompareCallbackType>(compare_callback));
1603 }
1604
1605 template<typename EleType, template<typename, typename...> class ContainerType, typename... Types,
1606 typename CompareCallbackType = std::less<> >
1607 auto binary_find_index(const ContainerType<EleType, Types...>& container, const EleType& value,
1608 CompareCallbackType&& compare_callback = CompareCallbackType{})
1609 {
1610 return binary_find_index(container.cbegin(), container.cend(), value,
1611 std::forward<CompareCallbackType>(compare_callback));
1612 }
1613
1614 template<typename ForwardIterator, typename EleType, typename CompareCallbackType = std::less<>>
1615 auto binary_find_bool_index_pair(ForwardIterator first, ForwardIterator last,
1616 const EleType& value, CompareCallbackType&& compare_callback = CompareCallbackType{})
1617 {
1618 auto start = std::lower_bound(first, last, value, compare_callback);
1619
1620 auto iterator = (start != last && !compare_callback(value, *start)) ? start : last;
1621
1622 return (iterator != last) ?
1623 std::make_pair(true, std::distance(first, iterator)) :
1624 std::make_pair(false, std::distance(first, iterator));
1625 }
1626
1627 template<typename EleType, template<typename, typename...> class ContainerType, typename... Types,
1628 typename CompareCallbackType = std::less<>>
1629 auto binary_find_bool_index_pair(const ContainerType<EleType, Types...>& container, const EleType& value,
1630 CompareCallbackType&& compare_callback = CompareCallbackType{})
1631 {
1632 return binary_find_bool_index_pair(container.cbegin(), container.cend(), value,
1633 std::forward<CompareCallbackType>(compare_callback));
1634 }
1635
1637 {
1639 std::atomic<int> thread_count{0};
1641 };
1642
1643 struct boolean
1644 {
1645 static constexpr bool Left = false;
1646 static constexpr bool Right = true;
1647
1648 static constexpr bool Or = false;
1649 static constexpr bool And = true;
1650
1651 static constexpr bool No = false;
1652 static constexpr bool Yes = true;
1653
1654 static constexpr bool False = false;
1655 static constexpr bool True = true;
1656
1657 static constexpr bool Before = false;
1658 static constexpr bool After = true;
1659
1660 static constexpr bool Prepend = false;
1661 static constexpr bool Append = true;
1662 };
1663
1664 namespace types
1665 {
1672 template<auto FuncType, typename... ArgTypes>
1673 constexpr auto is_noexcept_v = noexcept(FuncType(std::declval<ArgTypes>()...));
1674
1675 namespace hidden
1676 {
1677 template<typename Type>
1679 {
1680 static constexpr bool value = false;
1681 };
1682
1683 template<typename... Types>
1684 struct is_variant_st<std::variant<Types...>>
1685 {
1686 static constexpr bool value = true;
1687 };
1688
1689 template<typename Type>
1691
1692 template<typename Type>
1694 {
1695 static constexpr bool value = false;
1696 };
1697
1698 template<typename Type, typename... Types>
1699 struct is_unique_ptr_st<std::unique_ptr<Type, Types...>>
1700 {
1701 static constexpr bool value = true;
1702 };
1703
1704 template<typename Type>
1706
1707 template<typename Type>
1709 {
1710 static constexpr bool value = false;
1711 };
1712
1713 template<typename Type_1, typename Type_2>
1714 struct is_pair_st<std::pair<Type_1, Type_2>>
1715 {
1716 static constexpr bool value = true;
1717 };
1718
1719 template<typename Type>
1721
1723 template<typename Type>
1725 {
1726 static constexpr bool value = false;
1727 };
1728
1729 template<typename Type, typename... Types>
1730 struct is_pair_of_variant_st<std::pair<Type, Types...>>
1731 {
1732 static constexpr bool value = true;
1733 };
1734
1735 template<typename Type>
1736 constexpr auto is_pair_of_variant_v
1738
1739 template<typename Type>
1741 {
1742 using type = Type;
1743 static constexpr bool value = false;
1744 };
1745
1746 template<typename KeyType, typename ValueType, typename... Types>
1747 struct is_map_or_unordered_map_st<std::map<KeyType, ValueType, Types...>>
1748 {
1749 using type = std::pair<KeyType, ValueType>;
1750 static constexpr bool value = true;
1751 };
1752
1753 template<typename KeyType, typename ValueType, typename... Types>
1754 struct is_map_or_unordered_map_st<std::unordered_map<KeyType, ValueType, Types...>>
1755 {
1756 using type = std::pair<KeyType, ValueType>;
1757 static constexpr bool value = true;
1758 };
1759
1760 template<typename Type>
1762
1763 template<typename Type>
1765
1766 template<typename Type>
1768 {
1769 using type = Type;
1770 static constexpr bool value = false;
1771 };
1772
1773 template<typename Type, typename... Types>
1774 struct is_set_or_unordered_set_st<std::set<Type, Types...>>
1775 {
1776 using type = Type;
1777 static constexpr bool value = true;
1778 };
1779
1780 template<typename Type, typename... Types>
1781 struct is_set_or_unordered_set_st<std::unordered_set<Type, Types...>>
1782 {
1783 using type = Type;
1784 static constexpr bool value = true;
1785 };
1786
1787 template<typename Type>
1789
1790 template<typename Type>
1792 {
1793 static constexpr bool value = false;
1794 static constexpr bool empty = true;
1795 };
1796
1797 template<>
1798 struct is_tuple_st<std::tuple<>>
1799 {
1800 static constexpr bool value = true;
1801 static constexpr bool empty = true;
1802 };
1803
1804 template<typename Type, typename... Types>
1805 struct is_tuple_st<std::tuple<Type, Types...>>
1806 {
1807 static constexpr bool value = true;
1808 static constexpr bool empty = false;
1809 };
1810
1811 template<typename Type>
1813
1814 template<typename Type>
1816
1817 template<typename Type>
1819 {
1820 static constexpr bool value = false;
1821 };
1822
1823 template<>
1825 {
1826 static constexpr bool value = true;
1827 };
1828
1829 template<typename Type>
1831
1832 template<typename Type>
1834 {
1835 static constexpr bool value = false;
1836 };
1837
1838 template<typename Type, typename... Types>
1839 struct is_basic_string_st<std::basic_string<Type, Types...>>
1840 {
1841 static constexpr bool value = true;
1842 };
1843
1844 template<typename Type, typename... Types>
1845 struct is_basic_string_st<std::basic_string_view<Type, Types...>>
1846 {
1847 static constexpr bool value = true;
1848 };
1849
1850 template<typename Type>
1852
1853 template<typename Type>
1855 {
1856 static constexpr bool value = false;
1857 };
1858
1859 template<>
1860 struct is_char_st<char>
1861 {
1862 static constexpr bool value = true;
1863 };
1864
1865 template<>
1866 struct is_char_st<unsigned char>
1867 {
1868 static constexpr bool value = true;
1869 };
1870
1871 template<typename Type>
1873
1874 }
1875 // end of namespace hidden
1876
1877 template<typename Type>
1878 constexpr bool is_char_v = hidden::is_char_v<Type>;
1879
1880 template<typename Type>
1881 constexpr auto is_variant_v = hidden::is_variant_v<Type>;
1882
1883 template<typename Type>
1884 constexpr auto is_unique_ptr_v = hidden::is_variant_v<Type>;
1885
1886 template<typename Type>
1887 constexpr auto is_pair_v = hidden::is_pair_v<Type>;
1888
1889 template<typename Type>
1890 constexpr auto is_pair_of_variant_v = hidden::is_pair_of_variant_v<Type>;
1891
1892 template<typename Type>
1893 constexpr auto is_tuple_v = hidden::is_tuple_v<remove_cvref_t<Type>>;
1894
1895 template<typename Type>
1896 constexpr auto is_tuple_empty_v = hidden::is_tuple_empty_v<remove_cvref_t<Type>>;
1897
1898 namespace hidden
1899 {
1900 template<typename Type>
1902 {
1903 static constexpr size_t value = 1;
1904 };
1905
1906 template<typename Type, typename... ArgTypes>
1907 struct st_tuple_size<std::tuple<Type, ArgTypes...>>
1908 {
1909 static constexpr size_t value = 1 + sizeof...(ArgTypes);
1910 };
1911
1912 template<typename Type>
1914 }
1915 // end of namespace hidden
1916
1917 template<typename Type>
1918 constexpr auto tuple_size_v = hidden::tuple_size_v<remove_cvref_t<Type>>;
1919
1920 template<typename Type>
1921 constexpr auto is_any_v = hidden::is_any_v<Type>;
1922
1923 template<typename Type>
1924 constexpr auto is_map_or_unordered_map_v = hidden::is_map_or_unordered_map_v<Type>;
1925
1926 template<typename Type>
1928
1929 template<typename Type>
1930 constexpr auto is_basic_string_v = hidden::is_basic_string_v<Type>;
1931
1932 template<typename Type>
1933 constexpr auto is_set_or_unordered_set_v = hidden::is_set_or_unordered_set_v<Type>;
1934
1935 } // end of namespace types
1936
1937 template<template<typename, typename...> class ContainerType, typename EleType, typename... Types>
1938 struct set_tag
1939 {
1940 using set_element_t = EleType;
1941
1942 using set_t = ContainerType<EleType, Types...>;
1943 using sets_t = ContainerType<ContainerType<EleType, Types...>>;
1944 using set_of_sets_t = ContainerType<ContainerType<ContainerType<EleType, Types...>>>;
1945 using sets_of_sets_t = ContainerType<ContainerType<ContainerType<ContainerType<EleType, Types...>>>>;
1946
1947 using duet_set_element_t = std::tuple<set_element_t, set_element_t>;
1948 using duet_set_t = std::tuple<set_t, set_t>;
1949 using duet_sets_t = std::tuple<sets_t, sets_t>;
1950 using duet_set_of_sets_t = std::tuple<set_of_sets_t, set_of_sets_t>;
1951 using duet_sets_of_sets_t = std::tuple<sets_of_sets_t, sets_of_sets_t>;
1952
1953 using set_of_duets_t = ContainerType<duet_set_t>;
1954
1955 using trio_set_element_t = std::tuple<set_element_t, set_element_t, set_element_t>;
1956 using trio_set_t = std::tuple<set_t, set_t, set_t>;
1957 using trio_sets_t = std::tuple<sets_t, sets_t, sets_t>;
1958 using trio_set_of_sets_t = std::tuple<set_of_sets_t, set_of_sets_t, set_of_sets_t>;
1959 using trio_sets_of_sets_t = std::tuple<sets_of_sets_t, sets_of_sets_t, sets_of_sets_t>;
1960 };
1961
1962 template<typename SetTagType = set_tag<std::vector, int>>
1964
1965 template<typename SetTagType = set_tag<std::vector, int>>
1966 using set_t = typename SetTagType::set_t;
1967
1968 template<typename SetTagType = set_tag<std::vector, int>>
1969 using sets_t = typename SetTagType::sets_t;
1970
1971 template<typename SetTagType = set_tag<std::vector, int>>
1973
1974 template<typename SetTagType = set_tag<std::vector, int>>
1976
1977 template<typename SetTagType = set_tag<std::vector, int>>
1979
1980 template<typename SetTagType = set_tag<std::vector, int>>
1982
1983 template<typename SetTagType = set_tag<std::vector, int>>
1985
1986 template<typename SetTagType = set_tag<std::vector, int>>
1988
1989 template<typename SetTagType = set_tag<std::vector, int>>
1991
1992 template<typename SetTagType = set_tag<std::vector, int>>
1994
1995 template<typename SetTagType = set_tag<std::vector, int>>
1997
1998 template<typename SetTagType = set_tag<std::vector, int>>
2000
2001 template<typename SetTagType = set_tag<std::vector, int>>
2003
2004 template<typename SetTagType = set_tag<std::vector, int>>
2006
2007 template<typename SetTagType = set_tag<std::vector, int>>
2009
2014 namespace types
2015 {
2020 struct no_type_t{}; // "zero" in C++ type system
2021 // no_type_t plays the role of zero in C++ type system.
2022
2025
2026 template<typename Type>
2027 constexpr bool is_no_type_v = std::is_same_v<Type, no_type_t>;
2028
2029 template<typename CharType>
2030 std::basic_ostream<CharType>&
2031 operator<<(std::basic_ostream<CharType>& os, const no_type_t&)
2032 {
2033 os << "invalid"; return os;
2034 }
2035
2036 template<typename CharType>
2037 std::basic_ostream<CharType>&
2038 operator>>(std::basic_ostream<CharType>& os, const no_type_t&)
2039 {
2040 os << "no_type_t"; return os;
2041 }
2042
2043 namespace hidden
2044 {
2045 template<typename T, typename S>
2046 auto addition_vaild_fn(T t, S s) -> decltype(t + s);
2048
2049 template<typename T, typename S>
2050 constexpr bool is_addition_valid_v =
2051 !is_no_type_v<decltype(addition_vaild_fn(std::declval<T>(), std::declval<S>()))>;
2052
2053 template<typename T, typename S>
2054 auto subtraction_vaild_fn(T t, S s) -> decltype(t - s);
2056
2057 template<typename T, typename S>
2058 constexpr bool is_subtraction_valid_v =
2059 !is_no_type_v<decltype(subtraction_vaild_fn(std::declval<T>(), std::declval<S>()))>;
2060
2061 template<typename T, typename S>
2062 auto multiplication_vaild_fn(T t, S s) -> decltype(t * s);
2064
2065 template<typename T, typename S>
2067 !is_no_type_v<decltype(multiplication_vaild_fn(std::declval<T>(), std::declval<S>()))>;
2068
2069 template<typename T, typename S>
2070 auto division_vaild_fn(T t, S s) -> decltype(t / s);
2072
2073 template<typename T, typename S>
2074 constexpr bool is_division_valid_v =
2075 !is_no_type_v<decltype(division_vaild_fn(std::declval<T>(), std::declval<S>()))>;
2076
2077 template<typename T, typename S>
2078 constexpr bool is_arithmetic_valid_v = is_addition_valid_v<T, S> && is_subtraction_valid_v<T, S>
2079 && is_multiplication_valid_v<T, S> && is_division_valid_v<T, S>;
2080 }
2081 // end of namespace hidden
2082
2083 template<typename T, typename S>
2084 constexpr bool is_addition_valid_v =
2085 hidden::is_addition_valid_v<remove_cvref_t<T>, remove_cvref_t<S>>;
2086
2087 template<typename T, typename S>
2088 constexpr bool is_subtraction_valid_v =
2089 hidden::is_subtraction_valid_v<remove_cvref_t<T>, remove_cvref_t<S>>;
2090
2091 template<typename T, typename S>
2093 hidden::is_multiplication_valid_v<remove_cvref_t<T>, remove_cvref_t<S>>;
2094
2095 template<typename T, typename S>
2096 constexpr bool is_division_valid_v =
2097 hidden::is_division_valid_v<remove_cvref_t<T>, remove_cvref_t<S>>;
2098
2099 template<typename T, typename S>
2100 constexpr bool is_arithmetic_valid_v =
2101 hidden::is_arithmetic_valid_v<remove_cvref_t<T>, remove_cvref_t<S>>;
2102
2103 struct void_type_t{};
2104
2105 namespace hidden
2106 {
2107 template<typename Type> struct return_type_st
2108 {
2109 using type = Type;
2110 };
2111
2112 template<> struct return_type_st<void>
2113 {
2115 };
2116
2117 template<typename Type>
2119
2120 }
2121 // end of namespace hidden
2122
2123 template<typename Type>
2125
2126 template<typename Type>
2127 constexpr bool is_valid_type_v = !is_no_type_v<Type>;
2128
2129 inline constexpr no_type_t operator+(no_type_t, no_type_t) noexcept { return {}; }
2130 inline constexpr no_type_t operator-(no_type_t, no_type_t) noexcept { return {}; }
2131 inline constexpr no_type_t operator*(no_type_t, no_type_t) noexcept { return {}; }
2132 inline constexpr no_type_t operator/(no_type_t, no_type_t) noexcept { return {}; }
2133
2134 inline constexpr bool operator==(no_type_t, no_type_t) noexcept { return true; }
2135 inline constexpr bool operator!=(no_type_t, no_type_t) noexcept { return false; }
2136
2137 template<typename T>
2138 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, bool>
2139 operator==(no_type_t, T&&) noexcept { return false; }
2140
2141 template<typename T>
2142 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, bool>
2143 operator!=(T&&, no_type_t) noexcept { return false; }
2144
2145 template<typename T>
2146 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, no_type_t>
2147 operator+(no_type_t, T&&) noexcept { return {}; }
2148
2149 template<typename T>
2150 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, no_type_t>
2151 operator+(T&&, no_type_t) noexcept { return {}; }
2152
2153 template<typename T>
2154 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, no_type_t>
2155 operator-(no_type_t, T&&) noexcept { return {}; }
2156
2157 template<typename T>
2158 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, no_type_t>
2159 operator-(T&&, no_type_t) noexcept { return {}; }
2160
2161 template<typename T>
2162 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, no_type_t>
2163 operator*(no_type_t, T&&) noexcept { return {}; }
2164
2165 template<typename T>
2166 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, no_type_t>
2167 operator*(T&&, no_type_t) noexcept { return {}; }
2168
2169 template<typename T>
2170 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, no_type_t>
2171 operator/(no_type_t, T&&) noexcept { return {}; }
2172
2173 template<typename T>
2174 constexpr std::enable_if_t<!is_no_type_v<remove_cvref_t<T>>, no_type_t>
2175 operator/(T&&, no_type_t) noexcept { return {}; }
2176
2177 namespace hidden
2178 {
2179 template<typename Type>
2181 {
2182 static constexpr bool value = false;
2183 };
2184
2185 template<typename Type, size_t Size>
2186 struct st_is_std_array<std::array<Type, Size>>
2187 {
2188 static constexpr bool value = true;
2189 };
2190
2191 template<typename Type>
2193 {
2194 static constexpr size_t value = 0;
2196 };
2197
2198 template<typename Type, size_t Size>
2199 struct st_std_array_element<std::array<Type, Size>>
2200 {
2201 static constexpr size_t value = Size;
2202 using type = Type;
2203 };
2204 }
2205 // end of namespace hidden
2206
2207 template<typename Type>
2209
2210 template<typename Type>
2212
2213 template<typename Type>
2215
2217 template<typename T, T Value>
2219 {
2220 using type = T;
2221 static constexpr T Index = Value;
2222 static constexpr T Size = Value;
2223 };
2224
2225 template<auto Index>
2226 using indexer_t = indexer_type< remove_cvref_t<decltype(Index)>, Index>;
2227
2228 template<typename T, T RowValue, T ColumnValue>
2230 {
2231 using type = T;
2232 static constexpr T Row = RowValue;
2233 static constexpr T RowSize = RowValue;
2234 static constexpr T Column = ColumnValue;
2235 static constexpr T ColumnSize = ColumnValue;
2236
2237 // GNU g++, clang++, oneAPI DPC++ supports
2238 // but Microsoft MSVC 2019 fails
2239 // #if !defined(_MSVC_LANG)
2240
2241 template<auto RowIndex, auto ColumnIndex>
2243 {
2244 return ColumnSize * RowIndex + ColumnIndex;
2245 }
2246
2247 // #endif
2248 };
2249
2250 template<auto RowValue, auto ColumnValue>
2251 using indexer_2d_t = indexer_2d_type< remove_cvref_t<decltype(RowValue)>, RowValue, ColumnValue>;
2252
2253 template<typename T, T HeightValue, T RowValue, T ColumnValue>
2255 {
2256 using type = T;
2257 static constexpr T Height = HeightValue;
2258 static constexpr T HeightSize = HeightValue;
2259 static constexpr T Row = RowValue;
2260 static constexpr T RowSize = RowValue;
2261 static constexpr T Column = ColumnValue;
2262 static constexpr T ColumnSize = ColumnValue;
2263
2264 // GNU g++, clang++, oneAPI DPC++ supports
2265 // but Microsoft MSVC fails
2266 // #if !defined(_MSVC_LANG)
2267 template<auto HeightIndex, auto RowIndex, auto ColumnIndex>
2270 {
2271 return RowSize * ColumnSize * HeightIndex + ColumnSize * RowIndex + ColumnIndex;
2272 }
2273 // #endif
2274 };
2275
2276 template<auto HeightValue, auto RowValue, auto ColumnValue>
2277 using indexer_3d_t = indexer_3d_type< remove_cvref_t<decltype(RowValue)>, HeightValue, RowValue, ColumnValue>;
2278
2279 template<auto... Indices>
2281 std::integer_sequence< std::common_type_t<remove_cvref_t<decltype(Indices)>...>, Indices...>;
2282
2283 template<auto Size>
2285 std::make_integer_sequence<remove_cvref_t<decltype(Size)>, Size>;
2286
2287
2288 template<auto N, typename T, T Id, T...Ids>
2289 constexpr T fn_seq_element(std::integer_sequence<T, Id, Ids...>)
2290 {
2291 if constexpr(N == 0)
2292 return Id;
2293 else
2294 fn_seq_element<N-1>(std::integer_sequence<T, Ids...>{});
2295 }
2296
2297 template<typename T, T Id, T...Ids>
2298 auto seq_to_array(std::integer_sequence<T, Id, Ids...>)
2299 {
2300 return std::array{ Id, Ids... };
2301 }
2302
2303 template<typename IdType, typename IntType, std::size_t N>
2304 std::array<IntType, N>
2305 seq_indices(IdType i, std::array<IntType, N> const& powers)
2306 {
2307 std::array<IntType, N> indices;
2308 IntType n = (IntType)i;
2309
2310 for(IntType j = 0; j < (IntType)N; ++j)
2311 {
2312 indices[j] = (IntType)n / powers[j];
2313 n = (IntType)n % powers[j];
2314 }
2315
2316 return indices;
2317 }
2318
2319 inline bool is_stack_reversed()
2320 {
2321 auto func = [](auto a, auto b)
2322 {
2323 return &b > &a;
2324 };
2325
2326 return func(1, 2);
2327 }
2328
2329 inline bool is_stack_in_order()
2330 {
2331 return !is_stack_reversed();
2332 }
2333
2334 inline constexpr bool StackInOrder = true;
2335
2336 inline constexpr bool InOrderSequence = true;
2337 inline constexpr bool ReverseSequence = false;
2338
2339 namespace hidden
2340 {
2341 // can return negative value
2342 template<auto Begin, auto End, auto Size>
2343 constexpr auto compute_span()
2344 {
2345 using type_t = decltype(Begin);
2346
2347 if constexpr(Size == 0 || Size == 1)
2348 return 0;
2349 else if constexpr(Size == 2)
2350 return End - Begin;
2351 else
2352 {
2353 return (End - Begin) / (type_t) (Size - 1);
2354 }
2355 }
2356
2357 template<typename T> struct st_sequence_first_element
2358 {
2359 static constexpr T value = std::numeric_limits<T>::max();
2360 };
2361
2362 template<typename T, T First, T... Remainders>
2363 struct st_sequence_first_element<std::integer_sequence<T, First, Remainders...>>
2364 {
2365 static constexpr T value = First;
2366 };
2367
2368 template<typename T>
2370
2372 template<typename T> struct st_sequence_last_element;
2373
2374 template<typename T, T First>
2375 struct st_sequence_last_element<std::integer_sequence<T, First>>
2376 {
2377 static constexpr T value = First;
2378 };
2379
2380 template<typename T, T First, T... Remainders>
2381 struct st_sequence_last_element<std::integer_sequence<T, First, Remainders...>>
2382 {
2383 static constexpr T value = st_sequence_last_element<std::integer_sequence<T, Remainders...>>::value;
2384 };
2385
2386 template<typename T>
2388
2390 template<auto Nth, typename SequenceType> struct st_sequence_nth_element;
2391
2392 template<typename T, T First, T...Remainders>
2393 struct st_sequence_nth_element<0, std::integer_sequence<T, First, Remainders...>>
2394 {
2395 static constexpr T value = First;
2396 };
2397
2398 template<auto Nth, typename T, T First, T...Remainders>
2399 struct st_sequence_nth_element<Nth, std::integer_sequence<T, First, Remainders...>>
2400 {
2401 static constexpr T value = st_sequence_nth_element<Nth-1, std::integer_sequence<T, Remainders...>>::value;
2402 };
2403
2404 template<auto Nth, typename SequenceType>
2406
2408 template<typename T> struct st_sequence_element_count
2409 {
2410 static constexpr size_t value = std::numeric_limits<size_t>::max();
2411 };
2412
2413 template<typename T, T... Elements>
2414 struct st_sequence_element_count<std::integer_sequence<T, Elements...>>
2415 {
2416 static constexpr size_t value = sizeof...(Elements);
2417 };
2418
2419 template<typename T>
2421
2422 template<typename T, typename S> struct st_revese_sequence_operation;
2423
2424 template<typename T, T... args>
2425 struct st_revese_sequence_operation<std::integer_sequence<T, args...>, std::integer_sequence<T>>
2426 {
2427 using type = std::integer_sequence<T, args...>;
2428 };
2429
2430 template<typename T, T... args1, T first, T... args2>
2432 std::integer_sequence<T, args1...>,
2433 std::integer_sequence<T, first, args2...>>
2434 {
2435 using left = std::integer_sequence<T, first, args1...>;
2436 using right = std::integer_sequence<T, args2...>;
2437
2439 };
2440
2441 template<typename T> struct st_reverse_sequence;
2442
2443 template<typename T, T... args>
2444 struct st_reverse_sequence< std::integer_sequence<T, args...>>
2445 {
2447 std::integer_sequence<T>, std::integer_sequence<T, args...> >::type;
2448 };
2449
2450 template<typename SequenceType>
2452
2453 template<typename T>
2455 {
2457 };
2458
2459 template<typename T, T... Elements>
2460 struct st_sequence_element_type<std::integer_sequence<T, Elements...>>
2461 {
2462 using type = T;
2463 };
2464
2465 template<typename T>
2467
2468 template<typename T> struct st_sequence_span;
2469
2470 template<typename T, T First>
2471 struct st_sequence_span<std::integer_sequence<T, First>>
2472 {
2473 static constexpr T value = 0;
2474 };
2475
2476 template<typename T, T First, T Second, T... Remainders>
2477 struct st_sequence_span<std::integer_sequence<T, First, Second, Remainders...>>
2478 {
2479 static constexpr T value = Second - First;
2480 };
2481
2482 template<typename SequenceType>
2484
2485 template<typename T, auto FirstValue, auto LastValue, size_t CountValue,
2486 bool stack_order = StackInOrder>
2488 {
2489 using type = T;
2490 static constexpr T Begin = FirstValue;
2491 static constexpr T Last = LastValue;
2492 static constexpr T End = LastValue + 1;
2493 static constexpr T Span = compute_span<FirstValue, LastValue, (T)CountValue>();
2494 static constexpr size_t Count = CountValue;
2495 static constexpr bool InOrder = StackInOrder;
2496 };
2497
2498 template<typename T, auto FirstValue, auto LastValue, size_t CountValue>
2499 struct st_sequence_info<T, FirstValue, LastValue, CountValue, !StackInOrder>
2500 {
2501 using type = T;
2502 static constexpr T Begin = LastValue;
2503 static constexpr T Last = FirstValue;
2504 static constexpr T End = FirstValue - 1;
2505 static constexpr T Span = compute_span<LastValue, FirstValue, (T)CountValue>();
2506 static constexpr size_t Count = CountValue;
2507 static constexpr bool InOrder = !StackInOrder;
2508 };
2509
2510 template<bool StackOrder, typename SequenceType>
2512 sequence_first_element_v<SequenceType>, sequence_last_element_v<SequenceType>,
2513 sequence_element_count_v<SequenceType>, StackOrder>;
2514
2515 }
2516 // end of namespace hidden
2517
2518 template<typename SequenceType>
2520
2521 template<typename SequenceType>
2522 constexpr auto sequence_first_element_v = hidden::sequence_first_element_v<remove_cvref_t<SequenceType>>;
2523
2524 template<typename SequenceType>
2525 constexpr auto sequence_last_element_v = hidden::sequence_last_element_v<remove_cvref_t<SequenceType>>;
2526
2527 template<auto Nth, typename SequenceType>
2528 constexpr auto sequence_nth_element_v = hidden::sequence_nth_element_v<Nth, remove_cvref_t<SequenceType>>;
2529
2530 template<typename SequenceType>
2531 constexpr auto sequence_element_count_v = hidden::sequence_element_count_v<remove_cvref_t<SequenceType>>;
2532
2533 template<typename SequenceType>
2535
2536 template<typename SequenceType>
2537 constexpr auto sequence_span_v = hidden::sequence_span_v<remove_cvref_t<SequenceType>>;
2538
2539 template<bool StackOrder, typename SequenceType>
2541
2542 namespace hidden
2543 {
2544 template<typename T, T BeginValue, T EndValue, T IncrementValue>
2546 {
2547 using type = T;
2548 static constexpr type Begin = BeginValue;
2549 static constexpr type End = EndValue;
2550 static constexpr type Increment = IncrementValue;
2551 };
2552
2553 template<typename T, T... Indices, T Begin, T End, T Increment>
2554 constexpr auto fn_create_sequence_in_order(std::integer_sequence<T, Indices...>,
2556 {
2557 if constexpr (Increment > 0)
2558 {
2559 if constexpr (Begin + Increment < End)
2560 {
2561 using sequence_t = std::integer_sequence<T, Indices..., Begin>;
2563
2564 return fn_create_sequence_in_order(sequence_t{}, range_t{});
2565 }
2566 else
2567 {
2568 return std::integer_sequence<T, Indices..., Begin>{};
2569 }
2570 }
2571 else
2572 {
2573 if constexpr (Begin + Increment > End)
2574 {
2575 using sequence_t = std::integer_sequence<T, Indices..., Begin>;
2577
2578 return fn_create_sequence_in_order(sequence_t{}, range_t{});
2579 }
2580 else
2581 {
2582 return std::integer_sequence<T, Indices..., Begin>{};
2583 }
2584 }
2585 }
2586
2587 template<typename T, T... Indices, T Begin, T End, T Increment>
2588 constexpr auto fn_create_sequence_reverse_order(std::integer_sequence<T, Indices...>,
2590 {
2591 if constexpr(Increment > 0)
2592 {
2593 if constexpr (Begin + Increment < End)
2594 {
2595 using sequence_t = std::integer_sequence<T, Begin, Indices...>;
2597
2598 return fn_create_sequence_reverse_order(sequence_t{}, range_t{});
2599 }
2600 else
2601 {
2602 return std::integer_sequence<T, Begin, Indices...>{};
2603 }
2604 }
2605 else
2606 {
2607 if constexpr (Begin + Increment > End)
2608 {
2609 using sequence_t = std::integer_sequence<T, Begin, Indices...>;
2611
2612 return fn_create_sequence_reverse_order(sequence_t{}, range_t{});
2613 }
2614 else
2615 {
2616 return std::integer_sequence<T, Begin, Indices...>{};
2617 }
2618 }
2619 }
2620
2621 template<bool SequenceInOrder, auto... Values>
2623
2624 template<bool SequenceInOrder, auto EndValue>
2625 struct st_create_workhorse_range<SequenceInOrder, EndValue>
2626 {
2627 using value_type = std::make_signed_t<remove_cvref_t<decltype(EndValue)>>;
2629 using type =
2630 std::conditional_t<SequenceInOrder,
2631 remove_cvref_t<decltype(fn_create_sequence_in_order(std::integer_sequence<value_type>{}, workhorse_range_type{}))>,
2632 remove_cvref_t<decltype(fn_create_sequence_reverse_order(std::integer_sequence<value_type>{}, workhorse_range_type{}))>>;
2633 };
2634
2635 template<bool SequenceInOrder, auto BeginValue, auto EndValue>
2636 struct st_create_workhorse_range<SequenceInOrder, BeginValue, EndValue>
2637 {
2638 using value_type = std::make_signed_t<remove_cvref_t<decltype(EndValue)>>;
2639
2641 st_workhorse_range<value_type, (value_type)BeginValue, (value_type)EndValue,
2642 BeginValue < EndValue ? (value_type)1 : (value_type)-1 >;
2643
2644 using type =
2645 std::conditional_t<SequenceInOrder,
2646 remove_cvref_t<decltype(fn_create_sequence_in_order(std::integer_sequence<value_type>{}, workhorse_range_type{}))>,
2647 remove_cvref_t<decltype(fn_create_sequence_reverse_order(std::integer_sequence<value_type>{}, workhorse_range_type{}))>>;
2648 };
2649
2650 template<bool SequenceInOrder, auto BeginValue, auto EndValue, auto IncrementValue>
2651 struct st_create_workhorse_range<SequenceInOrder, BeginValue, EndValue, IncrementValue>
2652 {
2653 using value_type = std::make_signed_t<remove_cvref_t<decltype(EndValue)>>;
2654
2656 (value_type)BeginValue, (value_type)EndValue, (value_type)IncrementValue>;
2657
2658 using type =
2659 std::conditional_t<SequenceInOrder,
2660 remove_cvref_t<decltype(fn_create_sequence_in_order(std::integer_sequence<value_type>{}, workhorse_range_type{}))>,
2661 remove_cvref_t<decltype(fn_create_sequence_reverse_order(std::integer_sequence<value_type>{}, workhorse_range_type{}))>>;
2662 };
2663
2664 }
2665 // end of namespace hidden
2666
2667 template<bool SequenceInOrder, auto... RangeValues>
2668 using make_sequence_t = typename hidden::st_create_workhorse_range<SequenceInOrder, RangeValues...>::type;
2669
2671 {
2672 auto func = [](auto a, auto b)
2673 {
2674 return &b > &a;
2675 };
2676
2677 return func(1, 2);
2678 }
2679
2680 // create std::array 2d accessor
2681 template<auto RowValue, auto ColumnValue, typename ArrayType,
2682 auto Count = RowValue * ColumnValue,
2683 typename = std::enable_if_t< is_std_array_v<ArrayType> && Count == std_array_size_v<ArrayType>>>
2684 decltype(auto) array_indexer(ArrayType&& array)
2685 {
2686 return [&array, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto indexer)
2687 {
2688 return rank.Column * indexer.Row + indexer.Column;
2689 };
2690 }
2691
2692 template<auto RowValue, auto ColumnValue, typename ArrayType,
2693 auto Count = RowValue * ColumnValue,
2694 typename = std::enable_if_t< is_std_array_v<ArrayType> && Count == std_array_size_v<ArrayType>>>
2695 decltype(auto) array_indexer_row_column(ArrayType&& array)
2696 {
2697 return [&array, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto row_index, auto column_index)
2698 {
2699 return rank.Column * row_index + column_index;
2700 };
2701 }
2702
2703 // create std::array 2d accessor
2704 template<auto RowValue, auto ColumnValue, typename ArrayType,
2705 auto Count = RowValue * ColumnValue,
2706 typename = std::enable_if_t< is_std_array_v<ArrayType> && Count == std_array_size_v<ArrayType>>>
2707 decltype(auto) array_writer(ArrayType&& array)
2708 {
2709 return [&array, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto indexer, auto&& value)
2710 {
2711 array[rank.Column * indexer.Row + indexer.Column] = value;
2712 return value;
2713 };
2714 }
2715
2716 // create std::array 2d accessor
2717 template<auto RowValue, auto ColumnValue, typename ArrayType,
2718 auto Count = RowValue * ColumnValue,
2719 typename = std::enable_if_t< is_std_array_v<ArrayType> && Count == std_array_size_v<ArrayType>>>
2720 decltype(auto) array_writer_row_column(ArrayType&& array)
2721 {
2722 return [&array, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto row_index,
2723 auto column_index, auto&& value)
2724 {
2725 array[rank.Column * row_index + column_index] = value; return value;
2726 };
2727 }
2728
2729 // create std::array 2d accessor
2730 template<auto RowValue, auto ColumnValue, typename ArrayType,
2731 auto Count = RowValue * ColumnValue,
2732 typename = std::enable_if_t< is_std_array_v<ArrayType> && Count == std_array_size_v<ArrayType>>>
2733 decltype(auto) array_reader(ArrayType&& array)
2734 {
2735 return [&array, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto indexer)
2736 {
2737 return array[rank.Column * indexer.Row + indexer.Column];
2738 };
2739 }
2740
2741 template<auto RowValue, auto ColumnValue, typename ArrayType,
2742 auto Count = RowValue * ColumnValue,
2743 typename = std::enable_if_t< is_std_array_v<ArrayType> && Count == std_array_size_v<ArrayType>>>
2744 decltype(auto) array_reader_row_column(ArrayType&& array)
2745 {
2746 return [&array, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto row_index, auto column_index)
2747 {
2748 return array[rank.Column * row_index + column_index];
2749 };
2750 }
2751
2752 template<auto RowValue, auto ColumnValue, typename TupleType,
2753 auto Count = RowValue * ColumnValue,
2754 typename = std::enable_if_t<is_tuple_v<TupleType> && Count == tuple_size_v<TupleType>>>
2755 decltype(auto) tuple_reader(TupleType&& tuple)
2756 {
2757 return [&tuple, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto indexer)
2758 {
2759 constexpr auto Index = rank.Column * indexer.Row + indexer.Column;
2760 return std::get<Index>(tuple);
2761 };
2762 }
2763
2764 // create std::tuple 2d accessor
2765 template<auto RowValue, auto ColumnValue, typename TupleType,
2766 auto Count = RowValue * ColumnValue,
2767 typename = std::enable_if_t<is_tuple_v<TupleType> && Count == tuple_size_v<TupleType>>>
2768 decltype(auto) tuple_reader_row_column(TupleType&& tuple)
2769 {
2770 return [&tuple, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto row_indexer, auto column_indexer)
2771 {
2772 constexpr auto Index = rank.Column * row_indexer.Index + column_indexer.Index;
2773 return std::get<Index>(tuple);
2774 };
2775 }
2776
2778 template<auto RowValue, auto ColumnValue, typename TupleType,
2779 auto Count = RowValue * ColumnValue,
2780 typename = std::enable_if_t<is_tuple_v<TupleType> && Count == tuple_size_v<TupleType>>>
2781 decltype(auto) tuple_writer(TupleType&& tuple)
2782 {
2783 return [&tuple, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto indexer, auto&& value)
2784 {
2785 constexpr auto Index = rank.Column * indexer.Row + indexer.Column;
2786 std::get<Index>(tuple) = value;
2787 };
2788 }
2789
2790 // create std::tuple 2d accessor
2791 template<auto RowValue, auto ColumnValue, typename TupleType,
2792 auto Count = RowValue * ColumnValue,
2793 typename = std::enable_if_t<is_tuple_v<TupleType> && Count == tuple_size_v<TupleType>>>
2794 decltype(auto) tuple_writer_row_column(TupleType&& tuple)
2795 {
2796 return [&tuple, rank = indexer_2d_t<RowValue, ColumnValue>{}](auto row_indexer,
2797 auto column_indexer, auto&& value)
2798 {
2799 constexpr auto Index = rank.Column * row_indexer.Index + column_indexer.Index;
2800 std::get<Index>(tuple) = value;
2801 };
2802 }
2803
2804 namespace hidden
2805 {
2806 template<typename... ArgTypes>
2807 void process_arguments(ArgTypes&&...) { }
2808
2809 // WARNING: drive_workhorse is for internal USE only
2810 // It works only when the sequence increments by ONE - 1,
2811 // otherwise, it does not work.
2812 template<typename WorkhorseType, auto... Indices>
2813 void drive_workhorse(WorkhorseType&& workhorse, typed_sequence_t<Indices...>)
2814 {
2815 auto cabin =[&workhorse](auto indexer)
2816 {
2817 workhorse(indexer); return 0;
2818 };
2819
2821 {
2822 constexpr auto Size = sizeof...(Indices) - 1;
2823
2825 }
2826 else
2827 {
2828 process_arguments( cabin( indexer_t<Indices>{} )... );
2829 }
2830 }
2831
2832 // WARNING: drive_workhorse is for internal USE only
2833 // It works only when the sequence increments by ONE - 1,
2834 // or the sequence is continuous.
2835 // otherwise, it does not work.
2836 // For 2D sequence with two separate indexer_t
2837 template<typename WorkhorseType, auto... RowIndices, auto... ColumnIndices>
2838 std::enable_if_t<std::is_invocable_v<WorkhorseType, indexer_t<0>, indexer_t<0>>>
2839 drive_workhorse(WorkhorseType&& cabin,
2841 {
2842 constexpr auto ColumnSize = sizeof...(ColumnIndices);
2843 constexpr auto RowSize = sizeof...(RowIndices);
2844
2845 auto process_column = [&cabin, col_size = indexer_t<ColumnSize>{}](auto row_indexer)
2846 {
2847 auto row_fixed = [&cabin, row_indexer](auto col)
2848 {
2849 cabin(row_indexer, col); return 0;
2850 };
2851
2853 };
2854
2856 }
2857
2858 // WARNING: drive_workhorse is for internal USE only
2859 // It works only when the sequence increments by ONE - 1,
2860 // or the sequence is continuous.
2861 // otherwise, it does not work.
2862 // For 2D sequence with ONE indexer_2d_t
2863 template<typename WorkhorseType, auto... RowIndices, auto... ColumnIndices>
2864 std::enable_if_t<std::is_invocable_v<WorkhorseType, indexer_2d_t<0, 0>>>
2865 drive_workhorse(WorkhorseType&& cabin,
2867 {
2868 auto cabin_mount =[&cabin](auto indexer_row, auto index_column)
2869 {
2871 };
2872
2873 constexpr auto ColumnSize = sizeof...(ColumnIndices);
2874 constexpr auto RowSize = sizeof...(RowIndices);
2875
2876 drive_workhorse(cabin_mount,
2878 }
2879
2880 // WARNING: drive_workhorse is for internal USE only
2881 // It works only when the sequence increments by ONE - 1,
2882 // or the sequence is continuous.
2883 // otherwise, it does not work.
2884 // For 3D sequence with THREE indexer_t's as its arguments
2885 template<typename WorkhorseType,
2886 auto... HeightIndices, auto... RowIndices, auto... ColumnIndices>
2887 std::enable_if_t<std::is_invocable_v<WorkhorseType, indexer_t<0>, indexer_t<0>, indexer_t<0>>>
2890 {
2891 constexpr auto HeightSize = sizeof...(HeightIndices);
2892 constexpr auto RowSize = sizeof...(RowIndices);
2893 constexpr auto ColumnSize = sizeof...(ColumnIndices);
2894
2895 auto process_height = [&cabin, row_size = indexer_t<RowSize>{},
2896 col_size = indexer_t<ColumnSize>{}](auto height_indexer)
2897 {
2898 auto height_fixed = [&cabin, height_indexer](auto row_indexer, auto col_indexer)
2899 {
2900 cabin(height_indexer, row_indexer, col_indexer); return 0;
2901 };
2902
2903 drive_workhorse(height_fixed,
2905 make_typed_sequence_t<col_size.Index>{});
2906 };
2907
2909 }
2910
2911 // WARNING: drive_workhorse is for internal USE only
2912 // It works only when the sequence increments by ONE - 1,
2913 // or the sequence is continuous.
2914 // otherwise, it does not work.
2915 // For 3D sequence with ONE indexer_3d_t's as its argument.
2916 template<typename WorkhorseType,
2917 auto... HeightIndices, auto... RowIndices, auto... ColumnIndices>
2918 std::enable_if_t<std::is_invocable_v<WorkhorseType, indexer_3d_t<0, 0, 0>>>
2921 {
2922 auto cabin_mount =[&cabin](auto height_indexer,
2923 auto row_indexer, auto column_indexer)
2924 {
2926 };
2927
2928 constexpr auto HeightSize = sizeof...(HeightIndices);
2929 constexpr auto RowSize = sizeof...(RowIndices);
2930 constexpr auto ColumnSize = sizeof...(ColumnIndices);
2931
2934 }
2935
2936 }
2937 // end of namespace hidden
2938
2940 // WARNING: use drive_workhorse with care
2941 // It works only when the sequence increments by ONE - 1,
2942 // or the sequence is continuous.
2943 // otherwise, it does not work.
2944 template<size_t Count, typename WorkhorseType>
2945 std::enable_if_t<std::is_invocable_v<WorkhorseType, indexer_t<0>>>
2946 drive_workhorse(WorkhorseType&& workhorse)
2947 {
2948 // we do not need to wrap workhorse with cabin
2950 }
2951
2952 // WARNING: use drive_workhorse with care
2953 // It works only when the sequence increments by ONE - 1,
2954 // or the sequence is continuous.
2955 // otherwise, it does not work.
2956 //
2957 // For 2D loop - Consider using for_workhorse() instead
2958 template<auto RowCount, auto ColumnCount, typename WorkhorseType>
2960 std::is_invocable_v<WorkhorseType, indexer_t<0>, indexer_t<0>>
2961 || std::is_invocable_v<WorkhorseType, indexer_2d_t<0, 0> > >
2962 drive_workhorse(WorkhorseType&& workhorse)
2963 {
2964 hidden::drive_workhorse(workhorse,
2967 }
2968
2969 // WARNING: use drive_workhorse with care
2970 // It works only when the sequence increments by ONE - 1,
2971 // or the sequence is continuous.
2972 // otherwise, it does not work. Consider using for_workhorse() instead
2973 //
2974 // For 3D loop - Consider using for_workhorse() instead
2975 template<auto HeightCount, auto RowCount, auto ColumnCount, typename WorkhorseType>
2976 std::enable_if_t<std::is_invocable_v<WorkhorseType, indexer_3d_t<0, 0, 0>>
2977 || std::is_invocable_v<WorkhorseType, indexer_t<0>, indexer_t<0>, indexer_t<0> > >
2978 drive_workhorse(WorkhorseType&& workhorse)
2979 {
2982 }
2983
2984 namespace hidden
2985 {
2986 template<typename WorkhorseType, auto... Indices>
2987 std::enable_if_t<std::is_invocable_v<remove_cvref_t<WorkhorseType>, indexer_t<0>>>
2989 {
2990 ( (void)workhorse(indexer_t<Indices>{}), ...);
2991 }
2992
2993 template<typename WorkhorseType, auto... Indices,
2994 typename dummy_sequence = sequence_info_t<StackInOrder, typed_sequence_t<1>>>
2995 std::enable_if_t<std::is_invocable_v<remove_cvref_t<WorkhorseType>, indexer_t<0>, dummy_sequence>>
2997 {
2998 using sequence_type = sequence_info_t<StackInOrder, typed_sequence_t<Indices...>>;
2999 ( (void)workhorse(indexer_t<Indices>{}, sequence_type{}), ...);
3000 }
3001
3002 template<typename TupleType, typename WorkhorseType, auto... Indices>
3003 std::enable_if_t< is_tuple_v<remove_cvref_t<TupleType>> &&
3004 std::is_invocable_v<remove_cvref_t<WorkhorseType>, indexer_t<0>>>
3005 run_workhorse(TupleType&& tuple, WorkhorseType&& workhorse, typed_sequence_t<Indices...>)
3006 {
3007 ( (void)workhorse(indexer_t<Indices>{}), ...);
3008 }
3009
3010 template<typename TupleType, typename WorkhorseType, auto... Indices>
3011 std::enable_if_t< is_tuple_v<remove_cvref_t<TupleType>> &&
3012 std::is_invocable_v<remove_cvref_t<WorkhorseType>,
3013 indexer_t<0>, std::tuple_element_t<0, remove_cvref_t<TupleType>>>>
3014 run_workhorse(TupleType&& tuple, WorkhorseType&& workhorse, typed_sequence_t<Indices...>)
3015 {
3016 ( (void)workhorse(indexer_t<Indices>{}, std::get<Indices>(tuple)), ...);
3017 }
3018 }
3019 // end of namespace hidden
3020
3021 template<auto... RangeValues, typename WorkhorseType,
3022 typename dummy_sequence = make_sequence_t<StackInOrder, 1>,
3023 typename sequence_info = sequence_info_t<true, dummy_sequence>>
3024 std::enable_if_t<std::is_invocable_v<remove_cvref_t<WorkhorseType>, indexer_t<0>>||
3025 std::is_invocable_v<remove_cvref_t<WorkhorseType>, indexer_t<0>, sequence_info>>
3026 for_workhorse(WorkhorseType&& workhorse)
3027 {
3029 }
3030
3031 template<typename TupleType, typename WorkhorseType,
3032 typename dummy_sequence = make_sequence_t<StackInOrder, 1>,
3033 typename sequence_info = sequence_info_t<true, dummy_sequence>>
3034 std::enable_if_t< is_tuple_v<remove_cvref_t<TupleType>> && (
3035 std::is_invocable_v<remove_cvref_t<WorkhorseType>, indexer_t<0>> ||
3036 std::is_invocable_v<remove_cvref_t<WorkhorseType>, indexer_t<0>, sequence_info> )>
3037 for_workhorse(TupleType&& tuple, WorkhorseType&& workhorse)
3038 {
3039 hidden::run_workhorse(workhorse,
3041 }
3042
3043 namespace hidden
3044 {
3045 template<auto... Ints, typename FuncType>
3047 {
3048 return std::tuple{ f(indexer_t<Ints>{})... };
3049 }
3050
3051 template<auto... Ints, typename FuncType>
3053 {
3054 return std::tuple{ f(indexer_t<Ints>{})... };
3055 }
3056 }
3057 // end of namespace hidden
3058
3059 template<auto... RangeValues, typename FuncType>
3060 auto for_tuple(FuncType&& f)
3061 {
3063 }
3064
3065 template<typename... Types>
3066 auto reverse_tuple( std::tuple<Types...> const& tuple)
3067 {
3068 constexpr long long N = sizeof...(Types) - 1;
3069
3070 auto reverse = [&](auto i)
3071 {
3072 return std::get<i.Index>(tuple);
3073 };
3074
3075 return for_tuple<N, -1>(reverse);
3076 }
3077
3078 namespace hidden
3079 {
3080 template<typename... Types>
3082 {
3083 static constexpr size_t value = sizeof...(Types);
3084 };
3085
3086 template<typename... Types>
3087 struct type_count_st<type_list_t<Types...>>
3088 {
3089 static constexpr size_t value = sizeof...(Types);
3090 };
3091
3092 template<template<typename...> class TemplateType, typename... Types>
3093 struct type_count_st<TemplateType<Types...>>
3094 {
3095 static constexpr size_t value = sizeof...(Types);
3096 };
3097
3098 template<typename... Types>
3099 constexpr auto type_count_v = type_count_st<Types...>::value;
3100
3101 // if T is an iterator, this function is enabled
3102 // and returns the value type of the iterator type T
3103 // if T is not an iterator, then this function is SFINAEd out
3104 template<typename T> constexpr std::enable_if_t<true,
3105 typename std::iterator_traits<T>::value_type>
3107
3108 // this is catch all function for iterator_value_type_fn()
3110
3111 // if T is an iterator iterator_value_type_fn returns value_type of the
3112 // iterator, otherwise NoTypeDummy is returned.
3113 // if the returned value is Not equal to NoTypeDummy,
3114 // then T is an iterator, otherwise not an iterator
3115 template<typename T>
3116 constexpr bool is_iterator_type_v =
3117 is_valid_type_v<decltype(iterator_value_type_fn(std::declval<T>()))>;
3118
3119 template<typename T>
3121 is_iterator_type_v<T> && !std::is_pointer_v<T>;
3122
3123 // if T is an iterator, it returns T::value_type
3124 // otherwise, it returns NoTypeDummy
3125 template<typename T>
3126 using iterator_value_type_t = decltype(iterator_value_type_fn(std::declval<T>()));
3127
3128 // if T is an iterator, this returns T
3129 // otherwise, it is SFINAEd out
3130 template<typename Type, typename ReturnType>
3131 using enable_if_iterator_type_t = std::enable_if_t<is_iterator_type_v<Type>, ReturnType>;
3132
3133 // if T is an iterator, this returns T::value_type
3134 // otherwise, it is SFINAEd out
3135 template<typename T>
3136 using enable_if_iterator_value_type_t = std::enable_if_t<is_iterator_type_v<T>, iterator_value_type_t<T>>;
3137
3138 // if T is an iterator, this returns T::value_type
3139 // otherwise, it returns T
3140 template<typename T>
3142 typename std::conditional<is_iterator_type_v<T>, iterator_value_type_t<T>, T>::type;
3143
3144 }
3145 // end of namespace hidden
3146
3147 template<typename T>
3148 constexpr bool is_iterator_type_v = hidden::is_iterator_type_v<remove_cv_ref_t<T>>;
3149
3150 template<typename T>
3152 hidden::is_iterator_excluding_pointer_v<remove_cv_ref_t<T>>;
3153
3154 template<typename Type, typename ReturnType>
3156
3157 template<typename... Types>
3158 constexpr auto type_count_v = hidden::type_count_v<Types...>;
3159
3160 template<typename... Types>
3161 type_list_t<Types...> type_to_string(Types&&... args)
3162 {
3163 return {};
3164 }
3165
3171
3176 using integer_list_t = type_list_t<short, unsigned short,
3177 int, unsigned int, long, unsigned long,
3178 long long, unsigned long long>;
3179
3185
3191
3196 using integral_list_t = type_list_t<char, unsigned char, short, unsigned short,
3197 int, unsigned int, long, unsigned long,
3198 long long, unsigned long long>;
3199
3204 using unsigned_integral_list_t = type_list_t<unsigned char, unsigned short,
3205 unsigned int, unsigned long, unsigned long long>;
3206
3212 int, long int, long long int>;
3213
3219
3224 using numerical_number_list_t = type_list_t<char, unsigned char, short, unsigned short,
3225 int, unsigned int, long, unsigned long, long long, unsigned long long, float, double, long double>;
3226
3232
3238
3243 namespace hidden
3244 {
3245 template<typename Type>
3247 {
3249 static constexpr bool value = false;
3250 static constexpr size_t count = 1;
3251 };
3252
3253 // zero or more template parameters
3254 template<template<typename...>class ContainerType, typename...Types>
3255 struct is_template_st<ContainerType<Types...>>
3256 {
3257 using type = type_list_t<Types...>;
3258 static constexpr bool value = true;
3259 static constexpr size_t count = sizeof...(Types);
3260 };
3261
3262 template<template<typename, auto...>class ContainerType, typename Type, auto... Args>
3263 struct is_template_st<ContainerType<Type, Args...>>
3264 {
3266 static constexpr bool value = true;
3267 static constexpr size_t count = 1;
3268 };
3269
3270 template<typename Type>
3272
3273 template<typename Type>
3275
3276 template<typename Type>
3278
3279 template<typename Type1, typename Type2>
3281 {
3282 static constexpr bool value = false;
3283 };
3284
3285 template<template<typename...> class ContainerType, typename... Types>
3286 struct is_same_template_type_st<ContainerType<Types...>, ContainerType<Types...>>
3287 {
3288 static constexpr bool value = true;
3289 };
3290
3291 template<template<typename, typename...> class ContainerType,
3292 typename Type, typename... Types>
3293 struct is_same_template_type_st<ContainerType<Type, Types...>, ContainerType<Type, Types...>>
3294 {
3295 static constexpr bool value = true;
3296 };
3297
3298 template<template<typename, typename, typename...> class ContainerType,
3299 typename Type1, typename Type2, typename... Types>
3300 struct is_same_template_type_st<ContainerType<Type1, Type2, Types...>,
3301 ContainerType<Type1, Type2, Types...>>
3302 {
3303 static constexpr bool value = true;
3304 };
3305
3306 template<template<typename, typename, typename, typename...> class ContainerType,
3307 typename Type1, typename Type2, typename Type3, typename... Types>
3308 struct is_same_template_type_st<ContainerType<Type1, Type2, Type3, Types...>,
3309 ContainerType<Type1, Type2, Type3, Types...>>
3310 {
3311 static constexpr bool value = true;
3312 };
3313
3314 template<template<typename, typename, typename, typename...> class ContainerType,
3315 typename Type1, typename Type2, typename Type3, typename Type4, typename... Types>
3316 struct is_same_template_type_st<ContainerType<Type1, Type2, Type3, Type4, Types...>,
3317 ContainerType<Type1, Type2, Type3, Type4, Types...>>
3318 {
3319 static constexpr bool value = true;
3320 };
3321
3322 template<typename Type1, typename Type2>
3324
3325 template<typename Type1, typename Type2>
3327 {
3328 static constexpr bool value = false;
3329 };
3330
3331 template<template<typename...> class ContainerType,
3332 typename... Types1, typename... Types2>
3333 struct is_same_template_st<ContainerType<Types1...>, ContainerType<Types2...>>
3334 {
3335 static constexpr bool value = true;
3336 };
3337
3338 template<template<typename, typename...> class ContainerType,
3339 typename TypeA, typename... TypeAs,
3340 typename TypeB, typename... TypeBs>
3341 struct is_same_template_st<ContainerType<TypeA, TypeAs...>,
3342 ContainerType<TypeB, TypeBs...>>
3343 {
3344 static constexpr bool value = true;
3345 };
3346
3347 template<template<typename, typename, typename...> class ContainerType,
3348 typename TypeA1, typename TypeA2, typename... TypeAs,
3349 typename TypeB1, typename TypeB2, typename... TypeBs>
3350 struct is_same_template_st<ContainerType<TypeA1, TypeA2, TypeAs...>,
3351 ContainerType<TypeB1, TypeB2, TypeBs...>>
3352 {
3353 static constexpr bool value = true;
3354 };
3355
3356 template<template<typename, typename, typename, typename...> class ContainerType,
3357 typename TypeA1, typename TypeA2, typename TypeA3, typename... TypeAs,
3358 typename TypeB1, typename TypeB2, typename TypeB3, typename... TypeBs>
3359 struct is_same_template_st<ContainerType<TypeA1, TypeA2, TypeA3, TypeAs...>,
3360 ContainerType<TypeB1, TypeB2, TypeB3, TypeBs...>>
3361 {
3362 static constexpr bool value = true;
3363 };
3364
3365 template<template<typename, typename, typename, typename...> class ContainerType,
3366 typename TypeA1, typename TypeA2, typename TypeA3, typename TypeA4, typename... TypeAs,
3367 typename TypeB1, typename TypeB2, typename TypeB3, typename TypeB4, typename... TypeBs>
3368 struct is_same_template_st<ContainerType<TypeA1, TypeA2, TypeA3, TypeA4, TypeAs...>,
3369 ContainerType<TypeB1, TypeB2, TypeB3, TypeB4, TypeBs...>>
3370 {
3371 static constexpr bool value = true;
3372 };
3373
3374 template<typename Type1, typename Type2>
3376
3377 }
3378 // end of namespace hidden
3379
3386 template<typename Type>
3387 constexpr auto is_template_v = hidden::is_template_v<Type>;
3388
3389 template<typename Type>
3390 constexpr auto template_parameter_count = hidden::template_parameter_count<Type>;
3391
3392 template<typename Type>
3394
3395 template<typename Type1, typename Type2>
3396 constexpr auto is_same_template_type_v = hidden::is_same_template_type_v<Type1, Type2>;
3397
3398 template<typename Type1, typename Type2>
3399 constexpr auto is_same_template_v = hidden::is_same_template_v<Type1, Type2>;
3400
3405 namespace hidden
3406 {
3407 template<typename Type>
3409 {
3410 static constexpr bool value = false;
3411 };
3412
3413 template<>
3414 struct is_string_st<const char*>
3415 {
3416 static constexpr bool value = true;
3417 };
3418
3419 template<>
3420 struct is_string_st<const wchar_t*>
3421 {
3422 static constexpr bool value = true;
3423 };
3424
3425 template<typename CharType>
3426 struct is_string_st<std::basic_string<CharType>>
3427 {
3428 static constexpr bool value = true;
3429 };
3430
3431 template<typename Type>
3433
3434 }
3435 // end of namespace hidden
3436
3445 template<typename Type>
3446 constexpr auto is_string_v = hidden::is_string_v<Type>;
3447
3452 namespace hidden
3453 {
3454 template<typename Type1, typename Type2>
3455 constexpr auto is_operable_fn(Type1&& arg1, Type2&& arg2)
3456 noexcept(noexcept(std::declval<remove_cv_ref_t<Type1>>())
3457 && noexcept(std::declval<remove_cv_ref_t<Type2>>())) -> decltype(true ? arg1 : arg2);
3458
3459 constexpr no_type_t is_operable_fn(...) noexcept;
3460
3461 template<typename Type1, typename Type2>
3462 using is_operable_t = std::remove_reference_t<decltype(is_operable_fn(std::declval<Type1>(), std::declval<Type2>()))>;
3463
3464 template<typename Type1, typename Type2>
3465 constexpr auto is_operable_v =
3466 is_valid_type_v<is_operable_t<Type1, Type2>>;
3467
3468 template<typename Type>
3469 constexpr auto is_empty_available_fn(Type&& arg)
3470 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.empty());
3471
3472 constexpr no_type_t is_empty_available_fn(...) noexcept;
3473
3474 template<typename Type>
3475 constexpr bool is_empty_available_v =
3476 is_valid_type_v<decltype(is_empty_available_fn(std::declval<Type>()))>;
3477
3478 template<typename Type>
3479 constexpr auto is_capacity_available_fn(Type&& arg)
3480 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.capacity());
3481
3482 constexpr no_type_t is_capacity_available_fn(...) noexcept;
3483
3484 template<typename Type>
3485 constexpr bool is_capacity_available_v =
3486 is_valid_type_v<decltype(is_capacity_available_fn(std::declval<Type>()))>;
3487
3488 template<typename Type>
3489 constexpr auto is_shrink_to_fit_available_fn(Type&& arg)
3490 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.shrink_to_fit());
3491
3493
3494 template<typename Type>
3496 is_valid_type_v<decltype(is_shrink_to_fit_available_fn(std::declval<Type>()))>;
3497
3498 template<typename Type>
3499 constexpr auto is_size_available_fn(Type&& arg)
3500 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.size());
3501
3502 constexpr no_type_t is_size_available_fn(...) noexcept;
3503
3504 template<typename Type>
3505 constexpr bool is_size_available_v =
3506 is_valid_type_v<decltype(is_size_available_fn(std::declval<Type>()))>;
3507
3508 template<typename Type>
3509 constexpr auto is_front_available_fn(Type&& arg)
3510 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.front());
3511
3512 constexpr no_type_t is_front_available_fn(...) noexcept;
3513
3514 template<typename Type>
3515 constexpr bool is_front_available_v =
3516 is_valid_type_v<decltype(is_front_available_fn(std::declval<Type>()))>;
3517
3518 template<typename Type>
3519 constexpr auto is_back_available_fn(Type&& arg)
3520 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.back());
3521
3522 constexpr no_type_t is_back_available_fn(...) noexcept;
3523
3524 template<typename Type>
3525 constexpr bool is_back_available_v = is_valid_type_v<decltype(is_back_available_fn(std::declval<Type>()))>;
3526
3528 template<typename Type>
3529 constexpr auto is_begin_available_fn(Type&& arg)
3530 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.begin());
3531
3532 constexpr no_type_t is_begin_available_fn(...) noexcept;
3533
3534 template<typename Type>
3535 constexpr bool is_begin_available_v =
3536 is_valid_type_v<decltype(is_begin_available_fn(std::declval<Type>()))>;
3537
3539 template<typename Type>
3540 constexpr auto is_end_available_fn(Type&& arg)
3541 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.end());
3542
3543 constexpr no_type_t is_end_available_fn(...) noexcept;
3544
3545 template<typename Type>
3546 constexpr bool is_end_available_v =
3547 is_valid_type_v<decltype(is_end_available_fn(std::declval<Type>()))>;
3548
3550 template<typename Type>
3551 constexpr auto is_rbegin_available_fn(Type&& arg)
3552 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.rbegin());
3553
3554 constexpr no_type_t is_rbegin_available_fn(...) noexcept;
3555
3556 template<typename Type>
3557 constexpr bool is_rbegin_available_v =
3558 is_valid_type_v<decltype(is_rbegin_available_fn(std::declval<Type>()))>;
3559
3561 template<typename Type>
3562 constexpr auto is_rend_available_fn(Type&& arg)
3563 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.rend());
3564
3565 constexpr no_type_t is_rend_available_fn(...) noexcept;
3566
3567 template<typename Type>
3568 constexpr bool is_rend_available_v =
3569 is_valid_type_v<decltype(is_rend_available_fn(std::declval<Type>()))>;
3570
3572 template<template<typename, typename...> class ContainerType,
3573 typename Type, typename... Types>
3574 constexpr auto is_push_front_valid_fn(ContainerType<Type, Types...>&& arg)
3575 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.push_front(std::declval<Type>()));
3576
3577 constexpr no_type_t is_push_front_valid_fn(...) noexcept;
3578
3579 template<typename Type>
3581 is_valid_type_v<decltype(is_push_front_valid_fn(std::declval<Type>()))>;
3582
3584 template<template<typename, typename...> class ContainerType,
3585 typename Type, typename... Types>
3586 constexpr auto is_index_operator_valid_fn(ContainerType<Type, Types...>&& arg)
3587 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.operator[]((size_t)1));
3588
3589 constexpr no_type_t is_index_operator_valid_fn(...) noexcept;
3590
3591 template<typename Type>
3593 is_valid_type_v<decltype(is_index_operator_valid_fn(std::declval<Type>()))>;
3594
3596 template<template<typename, typename...> class ContainerType,
3597 typename Type, typename... Types>
3598 constexpr auto is_push_back_valid_fn(ContainerType<Type, Types...>&& arg)
3599 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.push_back(std::declval<Type>()));
3600
3601 constexpr no_type_t is_push_back_valid_fn(...) noexcept;
3602
3603 template<typename Type>
3605 is_valid_type_v<decltype(is_push_back_valid_fn(std::declval<Type>()))>;
3606
3608
3609 template<template<typename, typename...> class ContainerType,
3610 typename Type, typename... Types>
3611 constexpr auto is_erase_valid_fn(ContainerType<Type, Types...>&& arg)
3612 ->decltype(arg.erase(arg.cbegin()));
3613
3615
3616 template<typename Type>
3617 constexpr bool is_erase_available_v =
3618 is_valid_type_v<decltype(is_erase_valid_fn(std::declval<Type>()))>;
3619
3621
3622 template<template<typename, typename...> class ContainerType,
3623 typename Type, typename... Types>
3624 constexpr auto is_reserve_valid_fn(ContainerType<Type, Types...>&& arg)
3625 ->decltype(arg.reserve((size_t)0));
3626
3628
3629 template<typename Type>
3630 constexpr bool is_reserve_available_v =
3631 is_valid_type_v<decltype(is_reserve_valid_fn(std::declval<Type>()))>;
3632
3634 template<template<typename, typename...> class ContainerType,
3635 typename Type, typename... Types>
3636 constexpr auto is_insert_valid_fn(ContainerType<Type, Types...>&& arg)
3637 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.insert(std::declval<Type>()));
3638
3639 constexpr no_type_t is_insert_valid_fn(...) noexcept;
3640
3641 template<typename Type>
3642 constexpr bool is_insert_available_v =
3643 is_valid_type_v<decltype(is_insert_valid_fn(std::declval<tpf::remove_cv_ref_t<Type>>()))>;
3644
3645 // /////////////////////////////////////////
3646 // template<template<typename, typename...> class ContainerType,
3647 // typename Type, typename... Types>
3648 // constexpr auto is_index_operator_valid_fn(ContainerType<Type, Types...>&& arg)
3649 // noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.operator[](std::declval<size_t>()));
3650
3651 // constexpr no_type_t is_index_operator_valid_fn(...) noexcept;
3652
3653 // template<typename Type>
3654 // constexpr bool is_index_operator_available_v =
3655 // is_valid_type_v<decltype(is_index_operator_valid_fn(std::declval<tpf::remove_cv_ref_t<Type>>()))>;
3656
3658
3659 template<template<typename, typename...> class ContainerType,
3660 typename Type, typename... Types>
3661 constexpr auto is_insert_iterator_valid_fn(ContainerType<Type, Types...>&& arg)
3662 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.insert(arg.cend(), std::declval<Type>()));
3663
3665
3666 template<typename Type>
3668 is_valid_type_v<decltype(is_insert_iterator_valid_fn(std::declval<tpf::remove_cv_ref_t<Type>>()))>;
3669
3671 template<template<typename, typename...> class ContainerType,
3672 typename Type, typename... Types>
3673 constexpr auto is_resize_valid_fn(ContainerType<Type, Types...>&& arg)
3674 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.resize(std::declval<size_t>()));
3675
3676 constexpr no_type_t is_resize_valid_fn(...) noexcept;
3677
3678 template<typename Type>
3679 constexpr bool is_resize_available_v =
3680 is_valid_type_v<decltype(is_resize_valid_fn(std::declval<Type>()))>;
3681
3683 template<template<typename, typename...> class ContainerType,
3684 typename Type, typename... Types>
3685 constexpr auto is_emplace_front_valid_fn(ContainerType<Type, Types...>&& arg)
3686 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.emplace_front(std::declval<Type>()));
3687
3688 constexpr no_type_t is_emplace_front_valid_fn(...) noexcept;
3689
3690 template<typename Type>
3692 is_valid_type_v<decltype(is_emplace_front_valid_fn(std::declval<Type>()))>;
3693
3695 template<template<typename, typename...> class ContainerType,
3696 typename Type, typename... Types>
3697 constexpr auto is_emplace_back_valid_fn(ContainerType<Type, Types...>&& arg)
3698 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.emplace_back(std::declval<Type>()));
3699
3700 constexpr no_type_t is_emplace_back_valid_fn(...) noexcept;
3701
3702 template<typename Type>
3704 is_valid_type_v<decltype(is_emplace_back_valid_fn(std::declval<Type>()))>;
3705
3707
3708 template<template<typename, typename...> class ContainerType,
3709 typename Type, typename... Types>
3710 constexpr auto is_emplace_valid_fn(ContainerType<Type, Types...>&& arg)
3711 noexcept(noexcept(std::declval<ContainerType<Type, Types...>>()))->decltype(arg.emplace(arg.cbegin(), std::declval<Type>()));
3712
3713 constexpr no_type_t is_emplace_valid_fn(...) noexcept;
3714
3715 template<typename Type>
3716 constexpr bool is_emplace_available_v =
3717 is_valid_type_v<decltype(is_emplace_valid_fn(std::declval<Type>()))>;
3718
3720
3721 template<typename Type>
3722 constexpr auto is_pop_front_available_fn(Type&& arg)
3723 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.pop_front());
3724
3725 constexpr no_type_t is_pop_front_available_fn(...) noexcept;
3726
3727 template<typename Type>
3729 is_valid_type_v<decltype(is_pop_front_available_fn(std::declval<Type>()))>;
3730
3731 template<typename Type>
3732 constexpr auto is_pop_back_available_fn(Type&& arg)
3733 noexcept(noexcept(std::declval<remove_cv_ref_t<Type>>()))->decltype(arg.pop_back());
3734
3735 constexpr no_type_t is_pop_back_available_fn(...) noexcept;
3736
3737 template<typename Type>
3738 constexpr bool is_pop_back_available_v =
3739 is_valid_type_v<decltype(is_pop_back_available_fn(std::declval<Type>()))>;
3740
3742
3743 template<typename Type>
3744 constexpr bool is_container_type_v =
3745 is_empty_available_v<Type> && is_size_available_v<Type> &&
3747
3748 template<typename Type, typename ReturnType = void>
3750
3751 template<typename Type, typename... Types>
3753
3754 template<typename Type>
3755 struct is_same_st<Type>
3756 {
3757 static constexpr bool value = true;
3758 };
3759
3760 template<typename Type1, typename Type2>
3761 struct is_same_st<Type1, Type2>
3762 {
3763 static constexpr bool value = std::is_same_v<Type1, Type2>;
3764 };
3765
3766 template<typename Type1, typename Type2, typename... Types>
3767 struct is_same_st<Type1, Type2, Types...>
3768 {
3769 static constexpr bool value = is_same_st<Type1, Type2>::value &&
3770 is_same_st<Type2, Types...>::value;
3771 };
3772
3773 template<typename Type>
3775 {
3776 static constexpr bool value = true;
3777 };
3778
3779 template<typename Type1, typename Type2>
3780 struct is_same_st<type_list_t<Type1, Type2>>
3781 {
3782 static constexpr bool value = is_same_st<Type1, Type2>::value;
3783 };
3784
3785 template<typename Type1, typename Type2, typename... Types>
3786 struct is_same_st<type_list_t<Type1, Type2, Types...>>
3787 {
3788 static constexpr bool value =
3789 is_same_st<Type1, Type2, Types...>::value;
3790 };
3791
3792 template<typename Type, typename... Types>
3793 constexpr auto is_same_v = is_same_st<Type, Types...>::value;
3794
3795 // test if TestType is in the list
3796 template<typename TestType, typename... Types>
3798 {
3799 static constexpr bool value = false;
3800 };
3801
3802 template<typename TestType>
3803 struct is_in_list_st<TestType>
3804 {
3805 static constexpr bool value = false;
3806 };
3807
3808 template<typename TestType, typename Type>
3809 struct is_in_list_st<TestType, Type>
3810 {
3811 static constexpr bool value = std::is_same_v<TestType, Type>;
3812 };
3813
3814 template<typename TestType, typename Type, typename... Types>
3815 struct is_in_list_st<TestType, Type, Types...>
3816 {
3817 static constexpr bool value =
3818 std::is_same_v<TestType, Type>
3819 || is_in_list_st<TestType, Types...>::value;
3820 };
3821
3822 template<typename TestType>
3823 struct is_in_list_st<TestType, type_list_t<>>
3824 {
3825 static constexpr bool value = false;
3826 };
3827
3828 template<typename TestType, typename Type>
3829 struct is_in_list_st<TestType, type_list_t<Type>>
3830 {
3832 };
3833
3834 template<typename TestType, typename Type, typename... Types>
3835 struct is_in_list_st<TestType, type_list_t<Type, Types...>>
3836 {
3837 static constexpr bool value = is_in_list_st<TestType, Type, Types...>::value;
3838 };
3839
3840 template<typename TestType, typename... Types>
3841 constexpr bool is_in_list_v = is_in_list_st<TestType, Types...>::value;
3842
3843 template<typename TypeList, typename... TestTypes>
3845
3846 template<typename... Types>
3848 {
3849 static constexpr bool value = false;
3850 };
3851
3852 template<typename... Types, typename TestType>
3853 struct are_all_in_list_st<type_list_t<Types...>, TestType>
3854 {
3855 static constexpr bool value = is_in_list_v<TestType, type_list_t<Types...>>;
3856 };
3857
3858 template<typename... Types, typename TestType, typename... TestTypes>
3859 struct are_all_in_list_st<type_list_t<Types...>, TestType, TestTypes...>
3860 {
3861 static constexpr bool tmp_value = is_in_list_v<TestType, type_list_t<Types...>>;
3862
3863 static constexpr bool value = sizeof...(TestTypes) == 0 ? tmp_value :
3864 tmp_value && are_all_in_list_st<type_list_t<Types...>, TestTypes...>::value;
3865 };
3866
3867 template<typename... Types>
3869 {
3870 static constexpr bool value = false;
3871 };
3872
3873 template<typename... Types, typename TestType>
3874 struct are_all_in_list_st<type_list_t<Types...>, type_list_t<TestType>>
3875 {
3876 static constexpr bool value = is_in_list_v<TestType, type_list_t<Types...>>;
3877 };
3878
3879 template<typename... Types, typename TestType, typename... TestTypes>
3880 struct are_all_in_list_st<type_list_t<Types...>, type_list_t<TestType, TestTypes...>>
3881 {
3882 static constexpr bool value =
3883 are_all_in_list_st<type_list_t<Types...>, TestType, TestTypes...>::value;
3884 };
3885
3886 template<typename TypeList, typename... TestTypes>
3887 constexpr auto are_all_in_list_v = are_all_in_list_st<TypeList, TestTypes...>::value;
3888
3889 template<typename Type>
3890 constexpr auto is_integer_v = is_in_list_v<Type, integer_list_t>;
3891
3892 template<typename Type>
3893 constexpr auto is_unsigned_integer_v = is_in_list_v<Type, unsigned_integer_list_t>;
3894
3895 template<typename Type>
3896 constexpr auto is_signed_integer_v = is_in_list_v<Type, signed_integer_list_t>;
3897
3898 template<typename Type>
3899 constexpr auto is_integral_v = is_in_list_v<Type, integral_list_t>;
3900
3901 template<typename Type>
3902 constexpr auto is_unsigned_integral_v = is_in_list_v<Type, unsigned_integral_list_t>;
3903
3904 template<typename Type>
3905 constexpr auto is_signed_integral_v = is_in_list_v<Type, signed_integral_list_t>;
3906
3907 template<typename Type>
3908 constexpr auto is_real_number_v = is_in_list_v<Type, real_number_list_t>;
3909
3910 template<typename Type>
3911 constexpr auto is_numerical_number_v = is_in_list_v<Type, numerical_number_list_t>;
3912
3913 template<typename... Types>
3915
3916 template<typename... Types>
3918
3919 template<typename... Types>
3921
3922 template<typename... Types>
3924
3925 template<typename... Types>
3927
3928 template<typename... Types>
3930
3931 template<typename... Types>
3933
3934 template<typename... Types>
3936
3937 template<typename Type, typename ReturnType = Type>
3939 std::enable_if_t<is_integral_v<Type>, ReturnType>;
3940
3941 template<typename Type, typename ReturnType = Type>
3943 std::enable_if_t<is_signed_integral_v<Type>, ReturnType>;
3944
3945 template<typename Type, typename ReturnType = Type>
3947 std::enable_if_t<is_unsigned_integral_v<Type>, ReturnType>;
3948
3949 template<typename Type, typename ReturnType = Type>
3951 std::enable_if_t<is_integer_v<Type>, ReturnType>;
3952
3953 template<typename Type, typename ReturnType = Type>
3955 std::enable_if_t<!is_integer_v<Type>, ReturnType>;
3956
3957 template<typename Type, typename ReturnType = Type>
3959 std::enable_if_t<is_signed_integer_v<Type>, ReturnType>;
3960
3961 template<typename Type, typename ReturnType = Type>
3963 std::enable_if_t<is_unsigned_integer_v<Type>, ReturnType>;
3964
3965 template<typename Type, typename ReturnType = Type>
3967 std::enable_if_t<is_real_number_v<Type>, ReturnType>;
3968
3969 template<typename Type, typename ReturnType = Type>
3971 std::enable_if_t<is_numerical_number_v<Type>, ReturnType>;
3972
3973 template<typename Type, bool bInteger = false>
3975 {
3976 using type = Type;
3977 };
3978
3979 template<typename Type>
3980 struct make_signed_st<Type, true>
3981 {
3982 using type = std::make_signed_t<Type>;
3983 };
3984
3985 template<typename Type>
3987
3988 template<typename Type, bool bInteger = false>
3990 {
3991 using type = Type;
3992 };
3993
3994 template<typename Type>
3996 {
3997 using type = std::make_unsigned_t<Type>;
3998 };
3999
4000 template<typename Type>
4002
4003 template<typename Type, bool bIntegral = false>
4005 {
4007 };
4008
4009 template<typename Type>
4011 {
4012 using type = std::make_signed_t<Type>;
4013 };
4014
4015 template<typename Type>
4017
4018 template<typename Type, bool bIntegral = false>
4020 {
4022 };
4023
4024 template<typename Type>
4026 {
4027 using type = std::make_signed_t<Type>;
4028 };
4029
4030 template<typename Type>
4032
4033 template<typename Type, typename... Types>
4035
4036 template<typename Type>
4038 {
4039 using type = Type;
4040 };
4041
4042 template<typename Type1, typename Type2>
4043 struct common_type_st<Type1, Type2>
4044 {
4046 };
4047
4048 template<typename Type1, typename Type2, typename... Types>
4049 struct common_type_st<Type1, Type2, Types...>
4050 {
4052 typename common_type_st<Type2, Types...>::type>;
4053 };
4054
4055 template<>
4057 {
4059 };
4060
4061 template<typename Type>
4063 {
4064 using type = Type;
4065 };
4066
4067 template<typename Type1, typename Type2>
4068 struct common_type_st<type_list_t<Type1, Type2>>
4069 {
4071 };
4072
4073 template<typename Type1, typename Type2, typename... Types>
4074 struct common_type_st<type_list_t<Type1, Type2, Types...>>
4075 {
4076 using type = typename common_type_st<Type1, Type2, Types...>::type;
4077 };
4078
4079 template<typename... Types>
4081
4082 template<>
4084 {
4086 };
4087
4088 template<>
4090 {
4092 };
4093
4094 template<typename Type>
4096 {
4097 using type = Type;
4098 };
4099
4100 template<typename Type>
4102 {
4103 using type = Type;
4104 };
4105
4106 template<typename Type, typename... Types>
4107 struct st_common_type_solver<Type, Types...>
4108 {
4109 using type = typename common_type_st<Type, Types...>::type;
4110 };
4111
4112 template<typename Type, typename... Types>
4114 {
4115 using type = typename common_type_st<Type, Types...>::type;
4116 };
4117
4118 template<typename... Types>
4119 using common_type_t = typename st_common_type_solver<Types...>::type;
4120
4121 template<typename... Types>
4122 constexpr auto common_type_v = is_valid_type_v<common_type_t<Types...>>;
4123
4124 template<typename... Types>
4126
4127 template<>
4129 {
4131 };
4132
4133 template<typename Type>
4135 {
4136 using type = Type;
4137 };
4138
4139 template<typename Type, typename... Types>
4140 struct select_first_type_st<Type, Types...>
4141 {
4142 using type = Type;
4143 };
4144
4145 template<>
4147 {
4149 };
4150
4151 template<typename Type>
4153 {
4154 using type = Type;
4155 };
4156
4157 template<typename Type, typename... Types>
4159 {
4160 using type = Type;
4161 };
4162
4163 template<typename... Types>
4164 using select_first_type_t = typename select_first_type_st<Types...>::type;
4165
4166 template<typename... Types>
4168
4169 template<typename... Types>
4171
4172 template<typename... Types>
4174
4175 template<>
4177 {
4179 };
4180
4181 template<typename Type>
4183 {
4184 using type = Type;
4185 };
4186
4187 template<typename Type, typename... Types>
4188 struct select_last_type_st<Type, Types...>
4189 {
4190 using type = std::conditional_t<sizeof...(Types)==0,
4192 };
4193
4194 template<>
4196 {
4198 };
4199
4200 template<typename Type>
4202 {
4203 using type = Type;
4204 };
4205
4206 template<typename Type, typename... Types>
4208 {
4209 using type = std::conditional_t<sizeof...(Types)==0,
4211 };
4212
4213 template<typename... Types>
4214 using select_last_type_t = typename select_last_type_st<Types...>::type;
4215
4216 template<typename... Types>
4218
4219 template<typename... Types>
4221
4222 template<auto SelectIndex, typename... Types>
4224
4225 template<auto SelectIndex>
4226 struct select_nth_type_st<SelectIndex>
4227 {
4229 };
4230
4231 template<typename Type, typename... Types>
4232 struct select_nth_type_st<0, Type, Types...>
4233 {
4234 using type = Type;
4235 };
4236
4237 template<auto SelectIndex, typename Type, typename... Types>
4238 struct select_nth_type_st<SelectIndex, Type, Types...>
4239 {
4240 using type = std::conditional_t<SelectIndex==0,
4241 Type, typename select_nth_type_st<SelectIndex-1, Types...>::type>;
4242 };
4243
4244 template<auto SelectIndex>
4245 struct select_nth_type_st<SelectIndex, type_list_t<>>
4246 {
4248 };
4249
4250 template<typename Type, typename... Types>
4252 {
4253 using type = Type;
4254 };
4255
4256 template<auto SelectIndex, typename Type, typename... Types>
4257 struct select_nth_type_st<SelectIndex, type_list_t<Type, Types...>>
4258 {
4259 using type = std::conditional_t<SelectIndex==0,
4260 Type, typename select_nth_type_st<SelectIndex-1, Types...>::type>;
4261 };
4262
4263 template<typename Type>
4265 {
4266 static constexpr bool value = false;
4267 };
4268
4269 template<typename Type>
4271 {
4272 static constexpr bool value = true;
4273 };
4274
4275 template<typename Type>
4276 constexpr auto is_reference_wrapper_v =
4278
4279 template<auto SelectIndex, typename... Types>
4280 using select_nth_type_t = typename select_nth_type_st<SelectIndex, Types...>::type;
4281
4282 template<auto SelectIndex, typename... Types>
4283 using nth_type_t = select_nth_type_t<SelectIndex, Types...>;
4284
4285 template<typename Type>
4287
4288 template<typename Type>
4289 constexpr auto is_template_template_v = is_template_v<first_parameter_type_t<Type>>;
4290
4291 template<typename Type>
4293
4294 template<auto SelectIndex, typename Type>
4296
4297 template<typename ArgType, typename... Types>
4299 {
4300 using type = type_list_t<ArgType, Types...>;
4301 };
4302
4303 template<typename ArgType, typename... Types>
4304 struct push_front_type_st<ArgType, type_list_t<Types...>>
4305 {
4306 using type = type_list_t<ArgType, Types...>;
4307 };
4308
4309 template<typename ArgType, typename... Types>
4310 using push_front_type_t = typename push_front_type_st<ArgType, Types...>::type;
4311
4312 template<typename ArgType, typename... Types>
4314 {
4315 using type = type_list_t<Types..., ArgType>;
4316 };
4317
4318 template<typename ArgType, typename... Types>
4319 struct push_back_type_st<ArgType, type_list_t<Types...>>
4320 {
4321 using type = type_list_t<Types..., ArgType>;
4322 };
4323
4324 template<typename ArgType, typename... Types>
4325 using push_back_type_t = typename push_back_type_st<ArgType, Types...>::type;
4326
4327 template<typename ListType>
4329
4330 template<>
4332 {
4334 };
4335
4336 template<typename Type, typename... Types>
4338 {
4339 using type = type_list_t<Types...>;
4340 };
4341
4342 template<typename... Types>
4344 {
4345 using type = typename pop_front_type_st<type_list_t<Types...>>::type;
4346 };
4347
4348 template<typename... Types>
4350 {
4351 using type = typename pop_front_type_st<type_list_t<Types...>>::type;
4352 };
4353
4354 template<typename... Types>
4355 using pop_front_type_t = typename pop_front_wrapper_st<Types...>::type;
4356
4357 template<typename LeftList, typename RightList>
4359
4360 template<typename... LeftTypes>
4362 {
4363 using type = type_list_t<LeftTypes...>;
4364 };
4365
4366 template<typename... LeftTypes, typename Type, typename... RightTypes>
4367 struct pop_back_type_st<type_list_t<LeftTypes...>, type_list_t<Type, RightTypes...>>
4368 {
4370 using right_list = type_list_t<RightTypes...>;
4371
4372 using type = std::conditional_t<sizeof...(RightTypes) == 0,
4374 };
4375
4376 template<typename... Types>
4378 {
4380 };
4381
4382 template<typename... Types>
4384 {
4386 };
4387
4388 template<typename... Types>
4389 using pop_back_type_t = typename pop_back_type_wrapper_st<Types...>::type;
4390
4392 template<size_t FirstN, typename LeftList, typename RightList> struct first_n_types_list_st;
4393
4394 template<>
4396 {
4398 };
4399
4400 template<typename RightType, typename... RightTypes>
4401 struct first_n_types_list_st<0, type_list_t<>, type_list_t<RightType, RightTypes...>>
4402 {
4404 };
4405
4406 template<typename... LeftTypes>
4408 {
4409 using type = type_list_t<LeftTypes...>;
4410 };
4411
4412 template<typename... LeftTypes, typename RightType, typename... RightTypes>
4413 struct first_n_types_list_st<1, type_list_t<LeftTypes...>, type_list_t<RightType, RightTypes...>>
4414 {
4415 using type = type_list_t<LeftTypes..., RightType>;
4416 };
4417
4418 template<size_t FirstN, typename... LeftTypes, typename RightType, typename... RightTypes>
4419 struct first_n_types_list_st<FirstN, type_list_t<LeftTypes...>, type_list_t<RightType, RightTypes...>>
4420 {
4421 // when FirstN == 0
4422 using type_list_0 = type_list_t<LeftTypes...>;
4423
4424 // when FirstN > 0, FirstN = 1, 2, 3...
4425 using type_list_1 = std::conditional_t<FirstN == 1, type_list_t<LeftTypes..., RightType>,
4426 typename first_n_types_list_st<FirstN-1, type_list_t<LeftTypes..., RightType>, type_list_t<RightTypes...>>::type>;
4427
4428 using type = std::conditional_t<FirstN == 0, type_list_0, type_list_1>;
4429 };
4430
4431 template<size_t FirstN, typename... Types> struct first_n_types_st;
4432
4433 template<size_t FirstN, typename... RightTypes>
4434 struct first_n_types_st<FirstN, type_list_t<>, RightTypes...>
4435 {
4436 // static_assert(FirstN <= sizeof...(RightTypes), "FirstN out of range");
4437
4438 using type = std::conditional_t<FirstN == 0, type_list_t<>,
4439 std::conditional_t<FirstN >= sizeof...(RightTypes), type_list_t<RightTypes...>,
4441 };
4442
4443 template<size_t FirstN, typename... RightTypes>
4444 struct first_n_types_st<FirstN, type_list_t<>, type_list_t<RightTypes...>>
4445 {
4446 // static_assert(FirstN <= sizeof...(RightTypes), "FirstN out of range");
4447
4448 using type = std::conditional_t<FirstN == 0, type_list_t<>,
4449 std::conditional_t<FirstN >= sizeof...(RightTypes), type_list_t<RightTypes...>,
4451 };
4452
4453 template<size_t FirstN, typename... RightTypes>
4454 using first_n_types_t = typename first_n_types_st<FirstN, type_list_t<>, RightTypes...>::type;
4455
4456 template<size_t FirstN, typename... RightTypes>
4457 using select_first_n_types_t = first_n_types_t<FirstN, RightTypes...>;
4458
4460 template<size_t LastN, typename LeftList, typename RightList> struct last_n_types_list_st;
4461
4462 template<>
4464 {
4466 };
4467
4468 template<typename LeftType, typename... LeftTypes>
4469 struct last_n_types_list_st<0, type_list_t<LeftType, LeftTypes...>, type_list_t<>>
4470 {
4472 };
4473
4474 template<typename... RightTypes>
4475 struct last_n_types_list_st<1, type_list_t<>, type_list_t<RightTypes...>>
4476 {
4478 };
4479
4480 template<typename LeftType, typename... LeftTypes, typename... RightTypes>
4481 struct last_n_types_list_st<1, type_list_t<LeftType, LeftTypes...>, type_list_t<RightTypes...>>
4482 {
4483 using type = type_list_t<select_last_type_t<type_list_t<LeftType, LeftTypes...>>, RightTypes...>;
4484 };
4485
4486 template<size_t LastN, typename LeftType, typename... LeftTypes, typename... RightTypes>
4487 struct last_n_types_list_st<LastN, type_list_t<LeftType, LeftTypes...>, type_list_t<RightTypes...>>
4488 {
4489 // LastN == 0
4490 using type0 = type_list_t<RightTypes...>;
4491
4492 using new_right = type_list_t<select_last_type_t<type_list_t<LeftType, LeftTypes...>>, RightTypes...>;
4493 using new_left = pop_back_type_t<type_list_t<LeftType, LeftTypes...>>;
4494
4495 // LastN = 1, 2, 3
4496 using type1 = std::conditional_t<LastN == 1, new_right,
4497 typename last_n_types_list_st<LastN-1, new_left, new_right>::type>;
4498
4499 using type = std::conditional_t<LastN==0, type0, type1>;
4500 };
4501
4502 template<size_t LastN, typename... LeftTypes>
4504 {
4505 // static_assert(FirstN <= sizeof...(LeftTypes), "FirstN out of range");
4506
4507 using type = std::conditional_t<LastN==0, type_list_t<>,
4508 std::conditional_t<LastN >= sizeof...(LeftTypes), type_list_t<LeftTypes...>,
4510 };
4511
4512 template<size_t LastN, typename... LeftTypes>
4513 struct last_n_types_st<LastN, type_list_t<LeftTypes...>>
4514 {
4515 // static_assert(FirstN <= sizeof...(LeftTypes), "FirstN out of range");
4516
4517 using type = std::conditional_t<LastN==0, type_list_t<>,
4518 std::conditional_t<LastN >= sizeof...(LeftTypes), type_list_t<LeftTypes...>,
4520 };
4521
4522 template<size_t LastN, typename... LeftTypes>
4523 using last_n_types_t = typename last_n_types_st<LastN, LeftTypes...>::type;
4524
4525 template<size_t LastN, typename... LeftTypes>
4526 using select_last_n_types_t = last_n_types_t<LastN, LeftTypes...>;
4527
4528 template<typename ArgType, typename... Types>
4530
4531 template<typename ArgType>
4532 struct is_type_in_list_st<ArgType>
4533 {
4534 static constexpr bool value = false;
4535 };
4536
4537 template<typename ArgType, typename Type, typename... RightTypes>
4538 struct is_type_in_list_st<ArgType, Type, RightTypes...>
4539 {
4540 static constexpr bool value = std::is_same_v<ArgType, Type> ? true :
4541 is_type_in_list_st<ArgType, RightTypes...>::value;
4542 };
4543
4544 template<typename ArgType>
4546 {
4547 static constexpr bool value = false;
4548 };
4549
4550 template<typename ArgType, typename Type, typename... RightTypes>
4551 struct is_type_in_list_st<ArgType, type_list_t<Type, RightTypes...>>
4552 {
4553 static constexpr bool value = is_type_in_list_st<ArgType, Type, RightTypes...>::value;
4554 };
4555
4556 template<typename ArgType, typename... Types>
4557 constexpr auto is_type_in_list_v = is_type_in_list_st<ArgType, Types...>::value;
4558
4559 template<typename TestType, typename TypeList, typename ReturnType = TestType>
4560 using enable_if_in_list_t = std::enable_if_t<is_type_in_list_v<TestType, TypeList>, ReturnType>;
4561
4562 template<typename TestTypeList, typename TypeList, typename ReturnType = void>
4563 using enable_if_all_in_list_t = std::enable_if_t<are_all_in_list_v<TypeList, TestTypeList>, ReturnType>;
4564
4565 template<typename ListType, typename... Types>
4567
4568 template<typename... Types>
4570 {
4571 using type = type_list_t<Types...>;
4572 };
4573
4574 template<typename... Types, typename Type>
4576 {
4577 using list = type_list_t<Types...>;
4578
4579 using type = std::conditional_t<is_type_in_list_v<Type, list>,
4580 list, type_list_t<Types..., Type>>;
4581 };
4582
4583 template<typename... Types, typename Type, typename... RightTypes>
4584 struct unique_types_st<type_list_t<Types...>, Type, RightTypes...>
4585 {
4586 using list = typename unique_types_st<type_list_t<Types...>, Type>::type;
4587
4588 using type = typename unique_types_st<list, RightTypes...>::type;
4589 };
4590
4591 template<typename... Types, typename... RightTypes>
4592 struct unique_types_st<type_list_t<Types...>, type_list_t<RightTypes...>>
4593 {
4594 using type = typename unique_types_st<type_list_t<Types...>, RightTypes...>::type;
4595 };
4596
4597 template<typename... Types>
4598 using unique_types_t = typename unique_types_st<type_list_t<>, Types...>::type;
4599
4600 template<typename Type, typename... Types>
4602 {
4603 // using list = unique_types_t<Type, Types...>;
4604 using type = std::variant<Type, Types...>;
4605 };
4606
4607 template<typename Type, typename... Types>
4608 struct to_variant_st<type_list_t<Type, Types...>>
4609 {
4610 using type = std::variant<Type, Types...>;
4611 };
4612
4613 template<typename Type, typename... Types>
4614 struct to_variant_st<std::tuple<Type, Types...>>
4615 {
4616 using list_t = unique_types_t<Type, Types...>;
4618 };
4619
4620 template<typename Type, typename... Types>
4621 using to_variant_t = typename to_variant_st<Type, Types...>::type;
4622
4623 template<typename... Types>
4625 {
4626 using type = std::tuple<Types...>;
4627 };
4628
4629 template<typename... Types>
4630 struct to_tuple_st<type_list_t<Types...>>
4631 {
4632 using type = std::tuple<Types...>;
4633 };
4634
4635 template<typename... Types>
4636 struct to_tuple_st<std::variant<Types...>>
4637 {
4638 using type = std::tuple<Types...>;
4639 };
4640
4641 template<typename... Types>
4642 using to_tuple_t = typename to_tuple_st<Types...>::type;
4643
4644 template<typename ArgType, typename RightList>
4646
4647 template<typename ArgType, typename... RightTypes>
4648 struct prepend_type_st<ArgType, type_list_t<RightTypes...>>
4649 {
4650 using type = type_list_t<ArgType, RightTypes...>;
4651 };
4652
4653 template<typename... ArgTypes, typename... RightTypes>
4654 struct prepend_type_st<type_list_t<ArgTypes...>, type_list_t<RightTypes...>>
4655 {
4656 using type = type_list_t<ArgTypes..., RightTypes...>;
4657 };
4658
4659 template<typename ArgType, typename RightList>
4661
4662 template<typename LeftList, typename RightList>
4664
4665 template<typename ArgType, typename... RightTypes>
4666 struct append_type_st<ArgType, type_list_t<RightTypes...>>
4667 {
4668 using type = type_list_t<RightTypes..., ArgType>;
4669 };
4670
4671 template<typename... ArgTypes, typename... RightTypes>
4672 struct append_type_st<type_list_t<ArgTypes...>, type_list_t<RightTypes...>>
4673 {
4674 using type = type_list_t<RightTypes..., ArgTypes...>;
4675 };
4676
4677 template<typename ArgType, typename RightList>
4679
4680 template<typename LeftList, typename... Types>
4682
4683 template<typename... Types>
4684 struct union_type_st< type_list_t<Types...> >
4685 {
4686 using type = type_list_t<Types...>;
4687 };
4688
4689 template<typename... Types, typename Type>
4690 struct union_type_st< type_list_t<Types...>, Type>
4691 {
4692 using list = type_list_t<Types...>;
4693
4694 using type = std::conditional_t<is_type_in_list_v<Type, list>,
4695 list, type_list_t<Types..., Type>>;
4696 };
4697
4698 template<typename... Types, typename Type, typename... RightTypes>
4699 struct union_type_st<type_list_t<Types...>, Type, RightTypes...>
4700 {
4701 using list = typename union_type_st<type_list_t<Types...>, Type>::type;
4702
4703 using type = std::conditional_t<sizeof...(RightTypes)==0,
4705 };
4706
4707 template<typename ArgType, typename... Types>
4708 struct union_type_st<ArgType, type_list_t<Types...>>
4709 {
4710 using list = type_list_t<Types...>;
4711 using type = std::conditional_t<is_in_list_v<ArgType, list>,
4712 list, type_list_t<ArgType, Types...>>;
4713 };
4714
4715 template<typename... Types>
4717 {
4718 using type = type_list_t<Types...>;
4719 };
4720
4721 template<typename... Types, typename Type>
4723 {
4724 using type = typename union_type_st<type_list_t<Types...>, Type>::type;
4725 };
4726
4727 template<typename... Types, typename Type, typename... RightTypes>
4728 struct union_type_st<type_list_t<Types...>, type_list_t<Type, RightTypes...>>
4729 {
4730 using type = typename union_type_st<type_list_t<Types...>, Type, RightTypes...>::type;
4731 };
4732
4733 template<typename LeftList, typename RightList>
4735
4736 template<typename LeftType, typename... Types>
4738
4739 template<typename... Types>
4741 {
4742 using type = type_list_t<Types...>;
4743 };
4744
4745 template<typename... Types, typename Type>
4747 {
4748 using list = type_list_t<Types...>;
4749
4750 using type = std::conditional_t<is_type_in_list_v<Type, list>,
4752 };
4753
4754 template<typename... Types, typename Type, typename... RightTypes>
4755 struct intersection_type_st<type_list_t<Types...>, Type, RightTypes...>
4756 {
4757 using left_list = type_list_t<Types...>;
4759
4760 using type = std::conditional_t<sizeof...(RightTypes) == 0,
4762 };
4763
4764 template<typename... Types>
4766 {
4767 using type = type_list_t<Types...>;
4768 };
4769
4770 template<typename... Types, typename Type>
4772 {
4773 using type = typename intersection_type_st<type_list_t<Types...>, Type>::type;
4774 };
4775
4776 template<typename... Types, typename Type, typename... RightTypes>
4777 struct intersection_type_st<type_list_t<Types...>, type_list_t<Type, RightTypes...>>
4778 {
4779 using type = typename intersection_type_st<type_list_t<Types...>, Type, RightTypes...>::type;
4780 };
4781
4782 template<typename LeftList, typename RightList>
4784
4785 template<typename ArgType, typename... Types>
4787
4788 template<typename ArgType>
4789 struct remove_type_st<ArgType>
4790 {
4792 };
4793
4794 template<typename ArgType, typename Type>
4795 struct remove_type_st<ArgType, Type>
4796 {
4797 using type = std::conditional_t<std::is_same_v<ArgType, Type>,
4799 };
4800
4801 template<typename ArgType, typename Type, typename... RightTypes>
4802 struct remove_type_st<ArgType, Type, RightTypes...>
4803 {
4805
4806 using type = std::conditional_t<sizeof...(RightTypes) == 0,
4808 };
4809
4810 template<typename ArgType>
4811 struct remove_type_st<ArgType, type_list_t<>>
4812 {
4814 };
4815
4816 template<typename ArgType, typename Type>
4818 {
4820 };
4821
4822 template<typename ArgType, typename Type, typename... RightTypes>
4823 struct remove_type_st<ArgType, type_list_t<Type, RightTypes...>>
4824 {
4825 using type = typename remove_type_st<ArgType, Type, RightTypes...>::type;
4826 };
4827
4828 template<typename ArgType, typename... Types>
4830 {
4831 using type = typename remove_type_st<ArgType, type_list_t<Types...>>::type;
4832 };
4833
4834 template<typename ArgType, typename... Types>
4835 struct remove_type_wrapper_st<ArgType, type_list_t<Types...>>
4836 {
4837 using type = typename remove_type_st<ArgType, type_list_t<Types...>>::type;
4838 };
4839
4840 template<typename ArgType, typename... Types>
4842 typename remove_type_wrapper_st<ArgType, Types...>::type;
4843
4844 template<typename LeftList, typename... Types>
4846
4847 template<typename... Types>
4849 {
4850 using type = type_list_t<Types...>;
4851 };
4852
4853 template<typename... Types, typename Type>
4855 {
4856 using type = remove_type_t<Type, type_list_t<Types...>>;
4857 };
4858
4859 template<typename... Types, typename Type, typename... RightTypes>
4860 struct difference_type_st<type_list_t<Types...>, Type, RightTypes...>
4861 {
4862 using list = typename difference_type_st<type_list_t<Types...>, Type>::type;
4863
4864 using type = std::conditional_t<sizeof...(RightTypes) == 0,
4866 };
4867
4868 template<typename... Types>
4870 {
4871 using type = type_list_t<Types...>;
4872 };
4873
4874 template<typename... Types, typename Type>
4876 {
4877 using type = typename difference_type_st<type_list_t<Types...>, Type>::type;
4878 };
4879
4880 template<typename... Types, typename Type, typename... RightTypes>
4881 struct difference_type_st<type_list_t<Types...>, type_list_t<Type, RightTypes...>>
4882 {
4883 using type = typename difference_type_st<type_list_t<Types...>, Type, RightTypes...>::type;
4884 };
4885
4886 template<typename LeftList, typename RightList>
4888
4889 template<typename NewType, typename OldType, typename... Types>
4891
4892 template<typename NewType, typename OldType>
4893 struct replace_type_st<NewType, OldType>
4894 {
4896 };
4897
4898 template<typename NewType, typename OldType, typename Type>
4899 struct replace_type_st<NewType, OldType, Type>
4900 {
4901 using type = std::conditional_t< std::is_same_v<OldType, Type>,
4903 };
4904
4905 template<typename NewType, typename OldType, typename Type, typename... RightTypes>
4906 struct replace_type_st<NewType, OldType, Type, RightTypes...>
4907 {
4909
4910 using type = std::conditional_t< sizeof...(RightTypes), list,
4912 };
4913
4914 template<typename NewType, typename OldType>
4915 struct replace_type_st<NewType, OldType, type_list_t<>>
4916 {
4918 };
4919
4920 template<typename NewType, typename OldType, typename Type>
4921 struct replace_type_st<NewType, OldType, type_list_t<Type>>
4922 {
4924 };
4925
4926 template<typename NewType, typename OldType, typename Type, typename... RightTypes>
4927 struct replace_type_st<NewType, OldType, type_list_t<Type, RightTypes...>>
4928 {
4929 using type = typename replace_type_st<NewType, OldType, Type, RightTypes...>::type;
4930 };
4931
4932 template<typename NewType, typename OldType, typename TypeList>
4934
4935 template<typename Type, typename... Types>
4937
4938 template<typename... LeftTypes>
4940 {
4941 static constexpr bool value = true;
4942 };
4943
4944 template<typename... LeftTypes, typename Type>
4946 {
4947 static constexpr bool value =
4948 is_type_in_list_v<Type, type_list_t<LeftTypes...>>;
4949 };
4950
4951 template<typename... LeftTypes, typename Type, typename... RightTypes>
4952 struct is_type_list_equivalent_st<type_list_t<LeftTypes...>, Type, RightTypes...>
4953 {
4954 static constexpr bool tmp_value =
4955 is_type_list_equivalent_st< type_list_t<LeftTypes...>, Type>::value;
4956
4957 static constexpr bool value = sizeof...(RightTypes)==0 ? tmp_value :
4958 tmp_value && is_type_list_equivalent_st<type_list_t<LeftTypes...>, RightTypes...>::value;
4959 };
4960
4961 template<typename... LeftTypes, typename... RightTypes>
4962 struct is_type_list_equivalent_st<type_list_t<LeftTypes...>, type_list_t<RightTypes...>>
4963 {
4964 static constexpr bool value = sizeof...(LeftTypes) != sizeof...(RightTypes) ?
4965 false : is_type_list_equivalent_st<type_list_t<LeftTypes...>, RightTypes...>::value;
4966 };
4967
4968 template<typename LeftList, typename RightList>
4970
4971 }
4972 // end of namespace hidden
4973
4974 template<typename Type>
4975 constexpr auto is_reference_wrapper_v = hidden::is_reference_wrapper_v<Type>;
4976
4984 template<typename Type, typename... Types>
4985 constexpr auto is_same_v = hidden::is_same_v<Type, Types...>;
4986
4987 template<typename Type, typename... Types>
4989
4990 template<typename Type, typename... Types>
4991 constexpr auto is_same_flat_v = is_same_v<flat_type_list_t<Type, Types...>>;
4992
4993 template<typename ReturnType, typename Type, typename... Types>
4994 using enable_if_same_t = std::enable_if_t< is_same_v<Type, Types...>, ReturnType>;
4995
4996 template<typename ReturnType, typename... Types>
4997 using enable_if_all_the_same_t = std::enable_if_t< is_same_v<Types...>, ReturnType>;
4998
4999 template<typename ReturnType, typename Type, typename... Types>
5001
5002 template<typename ReturnType, typename... Types>
5004
5006 template<typename Type, typename... Types>
5008
5009 template<typename... Types>
5011
5012 template<typename Type, typename... Types>
5014
5015 template<typename... Types>
5017
5025 template<typename TestType, typename... Types>
5026 constexpr auto is_in_list_v = hidden::is_in_list_v<TestType, Types...>;
5027
5028 template<typename Type>
5029 constexpr auto is_integer_v = hidden::is_integer_v<Type>;
5030
5031 template<typename Type>
5032 constexpr auto is_signed_integer_v = hidden::is_signed_integer_v<Type>;
5033
5034 template<typename Type>
5035 constexpr auto is_unsigned_integer_v = hidden::is_unsigned_integer_v<Type>;
5036
5037 template<typename Type>
5038 constexpr auto is_integral_v = hidden::is_integral_v<Type>;
5039
5040 template<typename Type>
5041 constexpr auto is_signed_integral_v = hidden::is_signed_integral_v<Type>;
5042
5043 template<typename Type>
5044 constexpr auto is_unsigned_integral_v = hidden::is_unsigned_integral_v<Type>;
5045
5046 template<typename Type>
5047 constexpr auto is_real_number_v = hidden::is_real_number_v<Type>;
5048
5049 template<typename Type>
5050 constexpr auto is_numerical_number_v = hidden::is_numerical_number_v<Type>;
5051
5052 template<typename TypeList, typename... TestTypes>
5053 constexpr auto are_all_in_list_v = hidden::are_all_in_list_v<TypeList, TestTypes...>;
5054
5055 template<typename... Types>
5056 constexpr auto are_integers_v = hidden::are_integers_v<Types...>;
5057
5058 template<typename... Types>
5060
5061 template<typename... Types>
5063
5064 template<typename... Types>
5065 constexpr auto are_integrals_v = hidden::are_integrals_v<Types...>;
5066
5067 template<typename... Types>
5069
5070 template<typename... Types>
5072
5073 template<typename... Types>
5075
5076 template<typename... Types>
5078
5079 template<typename Type, typename ReturnType = Type>
5081
5082 template<typename Type, typename ReturnType = Type>
5084
5085 template<typename Type, typename ReturnType = Type>
5087
5088 template<typename Type, typename ReturnType = Type>
5090
5091 template<typename Type, typename ReturnType = Type>
5093
5094 template<typename Type, typename ReturnType = Type>
5096
5097 template<typename Type, typename ReturnType = Type>
5099
5100 template<typename Type, typename ReturnType = Type>
5102
5103 template<typename Type, typename ReturnType = Type>
5105
5106 template<typename Type>
5108
5109 template<typename Type>
5111
5112 template<typename Type>
5114
5115 template<typename Type>
5117
5118 template<typename Type1, typename Type2>
5119 constexpr auto is_operable_v = hidden::is_operable_v<Type1, Type2>;
5120
5121 template<typename... Types>
5123
5124 template<typename... Types>
5126
5127 template<typename... Types>
5129
5130 template<typename... Types>
5132
5133 template<typename... Types>
5135
5136 template<typename... Types>
5137 constexpr auto common_type_v = hidden::common_type_v<Types...>;
5138
5139 template<typename ReturnType, typename... ArgTypes>
5141 std::enable_if_t< common_type_v< remove_cvref_t<ArgTypes>... >, ReturnType>;
5142
5143 template<typename... ArgTypes>
5145 std::enable_if_t< common_type_v< remove_cvref_t<ArgTypes>... > >;
5146
5147 template<std::size_t N, typename T, typename deleter = std::default_delete<T[]>>
5149 {
5150 constexpr static auto Count = N;
5151
5152 std::size_t size;
5153
5154 std::unique_ptr<T[], deleter> uptr;
5155
5156 auto& ref() noexcept
5157 {
5158 return tpf::types::cast_ref<N>(uptr);
5159 }
5160
5161 auto& ref() const noexcept
5162 {
5163 return tpf::types::cast_ref<N>(uptr);
5164 }
5165
5166 template<typename IndexType>
5167 T& operator[](IndexType n) noexcept
5168 {
5169 return uptr[n];
5170 }
5171
5172 template<typename IndexType>
5173 const T& operator[](IndexType n) const noexcept
5174 {
5175 return uptr[n];
5176 }
5177 };
5178
5179 /* for testing purpose */
5180 namespace hidden
5181 {
5182 template<typename... ArgTypes>
5184 {
5185 constexpr static std::size_t N = sizeof...(ArgTypes);
5186
5187 using common_t =
5189
5191 };
5192
5193 template<typename... ArgTypes>
5194 using make_unique_ptr_wrapper_t = typename st_unique_ptr_wrapper<ArgTypes...>::type;
5195
5196 template<typename deleter, typename... ArgTypes>
5198 {
5199 constexpr static std::size_t N = sizeof...(ArgTypes);
5200
5201 using common_t =
5203
5205 };
5206
5207 template<typename deleter, typename... ArgTypes>
5209 typename st_unique_ptr_wrapper_deleter<deleter, ArgTypes...>::type;
5210 }
5211 // end of namespace hidden
5212
5213 /* for testing purpose
5214 template<typename deleter, typename... ArgTypes>
5215 enable_if_common_exisits_t<hidden::make_unique_ptr_deleter_wrapper_t<deleter, ArgTypes...>, ArgTypes...>
5216 make_unique_with_deleter(ArgTypes&&... args)
5217 {
5218 constexpr static std::size_t N = sizeof...(ArgTypes);
5219
5220 using common_t =
5221 tpf::types::common_type_t<remove_cvref_t<ArgTypes>...>;
5222
5223 using wrapper_t = hidden::make_unique_ptr_deleter_wrapper_t<deleter, ArgTypes...>;
5224
5225 return wrapper_t{N, std::unique_ptr<common_t[], deleter>{ new common_t[]
5226 { smart_forward<common_t, ArgTypes>(args)... } } };
5227 }
5228 */
5229
5231
5232 namespace hidden
5233 {
5234 template<typename FuncType, typename... ArgTypes>
5235 auto safe_apply(FuncType&& f, std::tuple<ArgTypes...> const& args)
5236 -> decltype( f( std::declval<ArgTypes>()...));
5237
5238 template<typename FuncType, typename ArgType, std::size_t N, std::size_t... Ints>
5239 auto array_apply(FuncType&& f, std::array<ArgType, N> const& args,
5240 std::index_sequence<Ints...>)-> decltype( f( std::get<Ints>(args)... ));
5241
5242 no_type_t array_apply(...); // fall-back function, catch-all function
5243
5244 template<typename FuncType, typename ArgType, std::size_t N>
5245 auto safe_apply(FuncType&& f, std::array<ArgType, N> const& args)
5246 -> decltype( array_apply(f, args, std::make_index_sequence<N>{}) );
5247
5248 no_type_t safe_apply(...); // fall-back function, catch-all function
5249
5250 template<typename FuncType, typename TupleType>
5251 auto fn_apply(FuncType&& f, TupleType&& args) -> decltype( safe_apply(f, args) );
5252 no_type_t fn_apply(...); // fall-back function, catch-all function
5253 }
5254 // end of namespace hidden
5255
5256 template<typename FuncType, typename TupleType>
5257 using apply_return_t = decltype(hidden::fn_apply(std::declval<FuncType>(), std::declval<TupleType>()));
5258
5259 template<typename FuncType, typename... TupleTypes>
5260 using common_apply_t = std::common_type_t< apply_return_t<FuncType, TupleTypes>... >;
5261
5262 template<typename FuncType, typename TupleType>
5263 constexpr bool is_apply_v = !is_no_type_v<apply_return_t<FuncType, TupleType>>;
5264
5265 template<typename FuncType, typename... TupleTypes>
5266 constexpr bool all_apply_v = ( is_apply_v<FuncType, TupleTypes> && ... );
5267
5268 template<typename FuncType, typename... TupleTypes>
5269 constexpr bool common_apply_v = all_apply_v<FuncType, TupleTypes...> &&
5270 common_type_v<apply_return_t<FuncType, TupleTypes>...>;
5271
5272 template<typename ReturnType, typename FuncType, typename... TupleTypes>
5274 std::enable_if_t< all_apply_v<FuncType, TupleTypes...>, ReturnType>;
5275
5276 template<typename FuncType, typename... TupleTypes>
5277 using apply_return_tuple_t = std::tuple< apply_return_t<FuncType, TupleTypes> ...>;
5278
5279 template<typename FuncType, typename... TupleTypes>
5281 std::array<std::common_type_t<apply_return_t<FuncType, TupleTypes>...>, sizeof...(TupleTypes)>;
5282
5283 template<typename FuncType, typename... TupleTypes>
5285 std::vector<std::common_type_t<apply_return_t<FuncType, TupleTypes>...>>;
5286
5287 template<typename FuncType, typename... TupleTypes>
5288 using void_if_all_apply_t = enable_if_all_apply_t<void, FuncType, TupleTypes...>;
5289
5290 template<typename FuncType, typename... TupleTypes>
5292 enable_if_all_apply_t< apply_return_tuple_t<FuncType, TupleTypes...>, FuncType, TupleTypes...>;
5293
5294 template<typename FuncType, typename... TupleTypes>
5296 enable_if_all_apply_t< apply_return_array_t<FuncType, TupleTypes...>, FuncType, TupleTypes...>;
5297
5298 template<typename FuncType, typename... TupleTypes>
5300 enable_if_all_apply_t< apply_return_vector_t<FuncType, TupleTypes...>, FuncType, TupleTypes...>;
5301
5302 template<typename FuncType, typename... TupleTypes>
5304 std::common_type_t<apply_return_t<FuncType, TupleTypes>...>>;
5305
5306 template<typename FuncType, typename... ArgTypes>
5307 types::tuple_if_all_apply_t<FuncType, ArgTypes...>
5308 apply_tuple(FuncType&& f, ArgTypes&&... args)
5309 {
5310 return { std::apply(f, args) ... };
5311 }
5312
5313 template<typename FuncType, typename... ArgTypes>
5314 types::vector_if_all_apply_t<FuncType, ArgTypes...>
5315 apply_vector(FuncType&& f, ArgTypes&&... args)
5316 {
5317 using ele_t = types::common_apply_t<FuncType, ArgTypes...>;
5318 return { (ele_t)std::apply(f, args) ... };
5319 }
5320
5321 template<typename FuncType, typename... ArgTypes>
5322 types::array_if_all_apply_t<FuncType, ArgTypes...>
5323 apply_array(FuncType&& f, ArgTypes&&... args)
5324 {
5325 using ele_t = types::common_apply_t<FuncType, ArgTypes...>;
5326 return { (ele_t)std::apply(f, args) ... };
5327 }
5328
5330
5331 template<typename Type>
5332 constexpr bool is_empty_available_v = hidden::is_empty_available_v<Type>;
5333
5334 template<typename Type>
5335 constexpr bool is_capacity_available_v = hidden::is_capacity_available_v<Type>;
5336
5337 template<typename Type>
5338 constexpr bool is_shrink_to_fit_available_v = hidden::is_shrink_to_fit_available_v<Type>;
5339
5340 template<typename Type>
5341 constexpr bool is_index_operator_available_v = hidden::is_index_operator_available_v<remove_cv_ref_t<Type>>;
5342
5343 template<typename Type>
5344 constexpr bool is_push_front_available_v = hidden::is_push_front_available_v<remove_cv_ref_t<Type>>;
5345
5346 template<typename Type>
5347 constexpr bool is_push_back_available_v = hidden::is_push_back_available_v<remove_cv_ref_t<Type>>;
5348
5349 template<typename Type>
5350 constexpr bool is_begin_available_v = hidden::is_begin_available_v<remove_cv_ref_t<Type>>;
5351
5352 template<typename Type>
5353 constexpr bool is_end_available_v = hidden::is_end_available_v<remove_cv_ref_t<Type>>;
5354
5355 template<typename Type>
5356 constexpr bool is_rbegin_available_v = hidden::is_rbegin_available_v<remove_cv_ref_t<Type>>;
5357
5358 template<typename Type>
5359 constexpr bool is_rend_available_v = hidden::is_rend_available_v<remove_cv_ref_t<Type>>;
5360
5361 template<typename Type>
5362 constexpr bool is_erase_available_v = hidden::is_erase_available_v<remove_cv_ref_t<Type>>;
5363
5364 template<typename Type>
5365 constexpr bool is_resize_available_v = hidden::is_resize_available_v<remove_cv_ref_t<Type>>;
5366
5367 template<typename Type>
5368 constexpr bool is_reserve_available_v = hidden::is_reserve_available_v<remove_cv_ref_t<Type>>;
5369
5370 template<typename Type>
5371 constexpr bool is_size_available_v = hidden::is_size_available_v<remove_cv_ref_t<Type>>;
5372
5373 template<typename Type>
5374 constexpr bool is_insert_available_v = hidden::is_insert_available_v<Type>;
5375
5376 template<typename Type>
5377 constexpr bool is_insert_iterator_available_v = hidden::is_insert_iterator_available_v<Type>;
5378
5379 template<typename Type>
5380 constexpr bool is_emplace_front_available_v = hidden::is_emplace_front_available_v<remove_cv_ref_t<Type>>;
5381
5382 template<typename Type>
5383 constexpr bool is_emplace_back_available_v = hidden::is_emplace_back_available_v<remove_cv_ref_t<Type>>;
5384
5385 template<typename Type>
5386 constexpr bool is_emplace_available_v = hidden::is_emplace_available_v<remove_cv_ref_t<Type>>;
5387
5388 template<typename Type>
5389 constexpr bool is_front_available_v = hidden::is_front_available_v<remove_cv_ref_t<Type>>;
5390
5391 template<typename Type>
5392 constexpr bool is_back_available_v = hidden::is_back_available_v<remove_cv_ref_t<Type>>;
5393
5394 template<typename Type>
5395 constexpr bool is_pop_front_available_v = hidden::is_pop_front_available_v<remove_cv_ref_t<Type>>;
5396
5397 template<typename Type>
5398 constexpr bool is_pop_back_available_v = hidden::is_pop_back_available_v<remove_cv_ref_t<Type>>;
5399
5400 template<typename Type>
5401 constexpr bool is_container_type_v = hidden::is_container_type_v<remove_cv_ref_t<Type>>;
5402
5403 namespace hidden
5404 {
5405 template<typename FuncType, typename... ArgTypes>
5406 auto function_return_type_fn(FuncType&& func, ArgTypes&&... args) -> decltype(func(args...));
5408
5409 template<typename FuncType, typename... ArgTypes>
5412
5413 template<typename FuncType, typename... ArgTypes>
5414 constexpr bool is_callable_v = !is_no_type_v<function_return_type_t<FuncType, ArgTypes...>>;
5415
5416 template<typename FuncType, typename... ArgTypes>
5417 constexpr bool is_void_return_type_v = is_callable_v<FuncType, ArgTypes...>
5418 && std::is_void_v<function_return_type_t<FuncType, ArgTypes...>>;
5419 }
5420 // end of namespace hidden
5421
5422 template<typename FuncType, typename... ArgTypes>
5423 constexpr bool is_callable_v = hidden::is_callable_v<FuncType, ArgTypes...>;
5424
5425 template<typename FuncType, typename... ArgTypes>
5427
5428 template<typename FuncType, typename... ArgTypes>
5429 constexpr bool is_void_return_type_v = hidden::is_void_return_type_v<FuncType, ArgTypes...>;
5430
5432 namespace hidden
5433 {
5434 template<typename T, typename... Types>
5436
5437 template<typename T>
5439 {
5440 static constexpr bool value = false;
5441 };
5442
5443 template<typename T, typename S>
5445 {
5446 static constexpr bool value = common_type_v<T, S>;
5447 };
5448
5449 template<typename T, typename S, typename... Types>
5450 struct st_pairwise_common<T, S, Types...>
5451 {
5452 static constexpr bool value = common_type_v<T, S> && st_pairwise_common<T, Types...>::value;
5453 };
5454
5455 template<typename... ArgTypes1, typename... ArgTypes2>
5456 auto tuple_addition_operator(const std::tuple<ArgTypes1...>& tuple_a,
5457 const std::tuple<ArgTypes2...>& tuple_b);
5458
5459 template<typename... ArgTypes1, typename... ArgTypes2, auto... Indices>
5460 auto tuple_addition(const std::tuple<ArgTypes1...>& tuple_a,
5461 const std::tuple<ArgTypes2...>& tuple_b, types::typed_sequence_t<Indices...>)
5462 {
5463 auto tuple_opr =[](auto a, auto b)
5464 {
5465 using type_a = types::remove_cvref_t<decltype(a)>;
5466 using type_b = types::remove_cvref_t<decltype(b)>;
5467
5468 if constexpr(types::is_tuple_v<type_a> && types::is_tuple_v<type_b>)
5469 {
5470 return tuple_addition_operator(a, b); // recursion
5471 }
5472 else
5473 {
5475 }
5476 };
5477
5478 return std::tuple{ tuple_opr(std::get<Indices>(tuple_a), std::get<Indices>(tuple_b))... };
5479 }
5480
5481 template<typename... ArgTypes1, typename... ArgTypes2>
5482 auto tuple_addition_operator(const std::tuple<ArgTypes1...>& tuple_a,
5483 const std::tuple<ArgTypes2...>& tuple_b)
5484 {
5485 constexpr auto Size1 = sizeof...(ArgTypes1);
5486 constexpr auto Size2 = sizeof...(ArgTypes2);
5487
5488 if constexpr(Size1 == Size2)
5489 {
5490 if constexpr(Size1 == 0)
5491 return tuple_a;
5492 else
5493 return tuple_addition(tuple_a, tuple_b, types::make_typed_sequence_t<Size1>{});
5494 }
5495 else
5496 {
5497 return std::tuple<no_type_t>{};
5498 }
5499 }
5500
5501 template<typename Type> // not tuple
5503 {
5504 static constexpr bool value = false;
5505 };
5506
5507 template<> // empty tuple
5509 {
5510 static constexpr bool value = false;
5511 };
5512
5513 template<typename Type> // single element tuple
5514 struct st_contain_no_type_in_tuple<std::tuple<Type>>
5515 {
5516 static constexpr bool value = (is_tuple_v<Type> ? st_contain_no_type_in_tuple<Type>::value : is_no_type_v<Type>);
5517 };
5518
5519 template<typename Type, typename... Types> // tuple with 1 or more element
5520 struct st_contain_no_type_in_tuple<std::tuple<Type, Types...>>
5521 {
5522 static constexpr bool value = (is_tuple_v<Type> ? st_contain_no_type_in_tuple<Type>::value : is_no_type_v<Type>)
5523 || st_contain_no_type_in_tuple<std::tuple<Types...>>::value;
5524 };
5525
5526 template<typename T, typename S>
5528 {
5529 static constexpr bool value = false;
5531 };
5532
5533 template<typename... ArgTypes1, typename... ArgTypes2>
5534 struct st_tuple_common_type<std::tuple<ArgTypes1...>, std::tuple<ArgTypes2...>>
5535 {
5536 using T = std::tuple<ArgTypes1...>;
5537 using S = std::tuple<ArgTypes2...>;
5538
5539 using type = decltype(tuple_addition_operator(std::declval<T>(), std::declval<S>()));
5540
5542 };
5543
5544 }
5545 // end of namespace hidden
5546
5547 template<typename T, typename... Types>
5549
5550 template<typename T, typename... Types>
5552
5553 template<typename T, typename S>
5555
5556 template<typename T, typename S>
5558
5559 template<typename T, typename S>
5560 using tuple_operation_valid_t = std::enable_if_t<tuple_common_type_v<T, S>, tuple_common_type_t<T, S>>;
5562
5563 template<typename Type, typename ReturnType = void>
5565
5566 template<typename... Types>
5568
5569 template<typename... Types>
5571
5572 template<typename... Types>
5574
5575 template<typename... Types>
5577
5578 template<typename... Types>
5580
5581 template<typename... Types>
5583
5584 template<auto SelectIndex, typename... Types>
5585 using select_nth_type_t = hidden::select_nth_type_t<SelectIndex, Types...>;
5586
5587 template<auto SelectIndex, typename... Types>
5588 using nth_type_t = hidden::nth_type_t<SelectIndex, Types...>;
5589
5590 template<typename Type>
5592
5593 template<typename Type>
5595
5596 template<auto SelectIndex, typename Type>
5598
5599 template<typename ArgType, typename... Types>
5601
5602 template<typename ArgType, typename... Types>
5603 using push_back_type_t = hidden::push_back_type_t<ArgType, Types...>;
5604
5605 template<typename... Types>
5607
5608 template<typename... Types>
5610
5611 template<size_t FirstN, typename... Types>
5612 using first_n_types_t = hidden::first_n_types_t<FirstN, Types...>;
5613
5614 template<size_t FirstN, typename... Types>
5616
5617 template<size_t LastN, typename... Types>
5618 using last_n_types_t = hidden::last_n_types_t<LastN, Types...>;
5619
5620 template<size_t LastN, typename... Types>
5622
5623 template<typename ArgType, typename... Types>
5624 constexpr auto is_type_in_list_v = hidden::is_type_in_list_v<ArgType, Types...>;
5625
5626 template<typename... Types>
5628
5629 template<typename Type, typename... Types>
5631
5632 template<typename TupleType>
5634
5635 template<template<typename, typename...> class Container, typename TupleType>
5636 using tuple_to_container_of_variants_t = Container<types::to_variant_t<remove_cvref_t<TupleType>>>;
5637
5638 template<typename... Types>
5640
5641 template<typename VarType>
5643
5644 template<typename ArgType, typename RightList>
5646
5647 template<typename ArgType, typename RightList>
5649
5650 template<typename LeftList, typename RightList>
5652
5653 template<typename LeftList, typename RightList>
5655
5656 template<typename ArgType, typename... Types>
5657 using remove_type_t = hidden::remove_type_t<ArgType, Types...>;
5658
5659 template<typename LeftList, typename RightList>
5661
5662 template<typename NewType, typename OldType, typename TypeList>
5664
5665 template<typename LeftList, typename RightList>
5667 hidden::is_type_list_equivalent_v<unique_types_t<LeftList>, unique_types_t<RightList>>;
5668
5669 namespace hidden
5670 {
5671 template<typename Type>
5673 {
5674 static constexpr bool value = false;
5675 };
5676
5677 template<typename... Types>
5678 struct st_has_tuple_common_type<std::tuple<Types...>>
5679 {
5680 using arg_types = type_list_t<Types...>;
5681 static constexpr bool value = common_type_v<arg_types>;
5683 };
5684
5685 template<typename TupleType>
5687
5688 template<typename TupleType>
5690
5691 template<typename TupleType>
5693 std::array< tuple_common_element_t<TupleType>, tuple_size_v<TupleType> >;
5694
5695 }
5696 // end of namespace hidden
5697
5698 template<typename TupleType>
5699 constexpr bool has_tuple_common_type_v = hidden::has_tuple_common_type_v<remove_cvref_t<TupleType>>;
5700
5701 template<typename TupleType>
5703
5704 template<typename TupleType>
5706
5707 namespace hidden
5708 {
5709 template<auto... Ints, typename FuncType>
5711 {
5712 using array_t = tuple_to_std_array_t<decltype(std::tuple{ f(indexer_t<Ints>{})... })>;
5713 using ele_t = std::tuple_element_t<0, array_t>;
5714
5715 return array_t{ smart_move<ele_t>(f(indexer_t<Ints>{}))... };
5716 }
5717
5718 template<auto... Ints, typename FuncType>
5720 {
5721 using array_t = tuple_to_std_array_t<decltype(std::tuple{ f(indexer_t<Ints>{})... })>;
5722 using ele_t = std::tuple_element_t<0, array_t>;
5723
5724 return array_t{ smart_move<ele_t>(f(indexer_t<Ints>{}))... };
5725 }
5726 }
5727 // end of namespace hidden
5728
5729 template<auto... RangeValues, typename FuncType>
5730 auto for_array(FuncType&& f)
5731 {
5733 }
5734
5735 template<typename Type, std::size_t N>
5736 auto reverse_array( std::array<Type, N> const& array)
5737 {
5738 std::array<Type, N> result = array;
5739
5740 std::reverse(result.begin(), result.end());
5741
5742 return result;
5743 }
5744
5745 namespace hidden
5746 {
5747 template<auto... Ints, typename FuncType>
5749 {
5750 auto tuple = std::tuple{ f(indexer_t<Ints>{})... };
5751 using ele_t = tuple_common_element_t<decltype(tuple)>;
5752
5753 return std::vector<ele_t>{ smart_move<ele_t>(std::get<Ints>(tuple))... };
5754 }
5755
5756 template<auto... Ints, typename FuncType>
5758 {
5759 auto tuple = std::tuple{ f(indexer_t<Ints>{})... };
5760 using ele_t = tuple_common_element_t<decltype(tuple)>;
5761
5762 return std::vector<ele_t>{ smart_move<ele_t>(std::get<Ints>(tuple))... };
5763 }
5764 }
5765 // end of namespace hidden
5766
5767 template<auto... RangeValues, typename FuncType>
5768 auto for_vector(FuncType&& f)
5769 {
5771 }
5772
5773
5774 namespace hidden
5775 {
5776 template<typename ArrayType, typename TupleType, auto...Indices>
5778 {
5779 constexpr auto Size = sizeof...(Indices);
5780
5781 ArrayType array;
5782 auto workhorse =[&array, &tuple](auto indexer)
5783 {
5784 array[indexer.Index] = std::get<indexer.Index>(tuple);
5785 };
5786
5787 for_workhorse<Size>(workhorse);
5788
5789 return array;
5790 }
5791
5792 template<typename ContainerType, typename TupleType, auto...Indices>
5794 {
5795 constexpr auto Size = sizeof...(Indices);
5796 ContainerType container;
5797
5798 auto workhorse = [&container, &tuple](auto indexer)
5799 {
5800 if constexpr(types::is_emplace_back_available_v<ContainerType>)
5801 {
5802 container.emplace_back(std::get<indexer.Index>(tuple));
5803 }
5804 else if constexpr(types::is_insert_available_v<ContainerType>)
5805 {
5806 container.insert(std::get<indexer.Index>(tuple));
5807 }
5808 };
5809
5810 for_workhorse<Size>(workhorse);
5811
5812 return container;
5813 }
5814
5815 template<typename T, size_t Size, auto... Indices>
5816 auto set_array_to_tuple(const std::array<T, Size>& array, typed_sequence_t<Indices...>)
5817 {
5818 return std::tuple{ (array[Indices])... };
5819 }
5820
5821 // template<typename ContainerType, typename T, size_t Size, auto... Indices>
5822 // auto set_array_to_container(const std::array<T, Size>& array, typed_sequence_t<Indices...>)
5823 // {
5824 // using ele_t = types::first_parameter_type_t<ContainerType>;
5825
5826 // return ContainerType{ ((ele_t)array[Indices])... };
5827 // }
5828 }
5829 // end of namespace hidden
5830
5831 template<typename Type, typename... Types,
5832 auto Size = sizeof...(Types) + 1,
5833 typename common_type = std::common_type_t<Type, Types...>,
5834 typename array_type = std::array<common_type, Size>>
5835 auto convert_to_array(const std::tuple<Type, Types...>& tuple)
5836 {
5837 return hidden::set_tuple_to_array<array_type>(tuple, make_typed_sequence_t<Size>{});
5838 }
5839
5840 template<template<typename, typename...>class ContainerType,
5841 typename Type, typename... Types,
5842 auto Size = sizeof...(Types) + 1,
5843 typename common_type = std::common_type_t<Type, Types...>,
5844 typename container_type = ContainerType<common_type>>
5845 auto convert_to_container(const std::tuple<Type, Types...>& tuple)
5846 {
5847 return hidden::set_tuple_to_container<container_type>(tuple, make_typed_sequence_t<Size>{});
5848 }
5849
5850 template<typename ContainerType,
5851 typename Type, typename... Types,
5852 auto Size = sizeof...(Types) + 1>
5853 auto convert_to_container(const std::tuple<Type, Types...>& tuple)
5854 {
5855 return hidden::set_tuple_to_container<ContainerType>(tuple, make_typed_sequence_t<Size>{});
5856 }
5857
5858 template<template<typename, typename...>class ContainerType,
5859 typename Type, typename... Types, size_t Size,
5860 typename container_type = ContainerType<Type, Types...>>
5861 auto convert_to_container(const std::array<Type, Size>& array)
5862 {
5863 // return hidden::set_array_to_container<container_type>(array, make_typed_sequence_t<Size>{});
5864
5865 container_type container;
5866
5867 for(size_t i = 0; i < Size; ++i)
5868 {
5869 if constexpr(types::is_emplace_back_available_v<container_type>)
5870 {
5871 container.emplace_back(array[i]);
5872 }
5873 else if constexpr(types::is_insert_available_v<container_type>)
5874 {
5875 container.insert(array[i]);
5876 }
5877 }
5878
5879 return container;
5880 }
5881
5882 template<typename T, size_t Size>
5883 auto convert_to_tuple(const std::array<T, Size>& array)
5884 {
5886 }
5887
5888 template<int ArgumentIndex, typename FuncType, typename ArgType, typename... ArgTypes,
5889 typename = std::enable_if_t< (ArgumentIndex < sizeof...(ArgTypes) + 1) >>
5890 auto freeze_parameter(FuncType&& func, ArgType arg, ArgTypes... args)
5891 {
5892 return [&func, arguments = std::tuple{ arg, args...}](auto&& x) mutable
5893 {
5894 std::get<ArgumentIndex>(arguments) = std::forward< decltype(x) >(x);
5895
5896 return std::apply(func, arguments);
5897 };
5898 }
5899
5900 template<int ArgumentIndex, typename FuncType, typename ArgType, typename... ArgTypes,
5901 typename = std::enable_if_t< (ArgumentIndex < sizeof...(ArgTypes) + 1) >>
5902 auto freeze_parameter(FuncType&& func, const std::tuple<ArgType, ArgTypes...>& arguments)
5903 {
5904 return [&func, arguments = arguments](auto&& x) mutable
5905 {
5906 std::get<ArgumentIndex>(arguments) = std::forward< decltype(x) >(x);
5907
5908 return std::apply(func, arguments);
5909 };
5910 }
5911
5912 template<int FuncIndex, int ArgumentIndex,
5913 typename FuncType, typename... FuncTypes, typename ArgFirst, typename... ArgTypes,
5914 typename = std::enable_if_t< ( FuncIndex < (sizeof...(FuncTypes) + 1) )
5915 && (ArgumentIndex < sizeof...(ArgTypes) + 1 )> >
5916 auto freeze_parameter(const std::tuple<FuncType, FuncTypes...>& func_tuple, ArgFirst arg, ArgTypes... args)
5917 {
5918 return [&func = std::get<FuncIndex>(func_tuple), arguments =
5919 std::tuple{arg, args...}](auto&& x) mutable
5920 {
5921 std::get<ArgumentIndex>(arguments) = std::forward<>(x);
5922
5923 return func(arguments);
5924 };
5925 }
5926
5927 template<int FuncIndex, int ArgumentIndex,
5928 typename FuncType, typename... FuncTypes, typename ArgFirst, typename... ArgTypes,
5929 typename = std::enable_if_t< ( FuncIndex < sizeof...(FuncTypes) + 1 )
5930 && (ArgumentIndex < sizeof...(ArgTypes)+1)>>
5931 auto freeze_parameter(const std::tuple<FuncType, FuncTypes...>& func_tuple,
5932 const std::tuple<ArgFirst, ArgTypes...>& arguments)
5933 {
5934 return [&func = std::get<FuncIndex>(func_tuple), arguments = arguments](auto&& x) mutable
5935 {
5936 std::get<ArgumentIndex>(arguments) = std::forward<>(x);
5937
5938 return func(arguments);
5939 };
5940 }
5941
5942 namespace hidden
5943 {
5944 template< template<typename, size_t> class ReturnClass,
5945 typename TupleType, auto... Indices, typename... ArgTypes>
5946 auto evaluate_lambdas(typed_sequence_t<Indices...>, TupleType&& tuple, ArgTypes&&... args)
5947 {
5948 return ReturnClass{ (std::get<Indices>(tuple)(std::forward<ArgTypes>(args)...))... };
5949 }
5950
5951 template< template<typename...> class ReturnClass,
5952 typename TupleType, auto... Indices, typename... ArgTypes>
5953 auto evaluate_lambdas(typed_sequence_t<Indices...>, TupleType&& tuple, ArgTypes&&... args)
5954 {
5955 return ReturnClass{ (std::get<Indices>(tuple)(std::forward<ArgTypes>(args)...))... };
5956 }
5957
5958 template< template<typename, size_t> class ReturnClass,
5959 typename TupleType, auto... Indices, typename ArgTuple>
5960 auto evaluate_lambdas_tuple(typed_sequence_t<Indices...>, TupleType&& tuple, ArgTuple&& arguments)
5961 {
5962 return ReturnClass{ std::apply(std::get<Indices>(tuple), std::forward<ArgTuple>(arguments))... };
5963 }
5964
5965 template< template<typename...> class ReturnClass,
5966 typename TupleType, auto... Indices, typename ArgTuple>
5967 auto evaluate_lambdas_tuple(typed_sequence_t<Indices...>, TupleType&& tuple, ArgTuple&& arguments)
5968 {
5969 return ReturnClass{ std::apply(std::get<Indices>(tuple), std::forward<ArgTuple>(arguments))... };
5970 }
5971
5972 }
5973 // end of namespace hidden
5974
5975 template< template<typename, size_t> class ReturnClass,
5976 typename FuncType, typename... FuncTypes, typename ArgFirst, typename... ArgTypes>
5977 auto evaluate_lambdas(const std::tuple<FuncType, FuncTypes...>& tuple, ArgFirst&& arg, ArgTypes&&... args)
5978 {
5979 constexpr auto Size = sizeof...(FuncTypes) + 1;
5980
5981 return hidden::evaluate_lambdas<ReturnClass>(make_typed_sequence_t<Size>{},
5982 tuple, std::forward<ArgFirst>(arg), std::forward<ArgTypes>(args)...);
5983 }
5984
5985 template< template<typename...> class ReturnClass,
5986 typename FuncType, typename... FuncTypes, typename ArgFirst, typename... ArgTypes>
5987 auto evaluate_lambdas(const std::tuple<FuncType, FuncTypes...>& tuple, ArgFirst&& arg, ArgTypes&&... args)
5988 {
5989 constexpr auto Size = sizeof...(FuncTypes) + 1;
5990
5991 return hidden::evaluate_lambdas<ReturnClass>(make_typed_sequence_t<Size>{},
5992 tuple, std::forward<ArgFirst>(arg), std::forward<ArgTypes>(args)...);
5993 }
5994
5995 template< template<typename, size_t> class ReturnClass,
5996 typename FuncType, typename... FuncTypes, typename ArgFirst>
5997 auto evaluate_lambdas(const std::tuple<FuncType, FuncTypes...>& tuple, ArgFirst&& arg)
5998 {
5999 constexpr auto Size = sizeof...(FuncTypes) + 1;
6000
6001 if constexpr(is_tuple_v<decltype(arg)>)
6002 {
6003 return hidden::evaluate_lambdas_tuple<ReturnClass>(make_typed_sequence_t<Size>{},
6004 tuple, std::forward<ArgFirst>(arg));
6005 }
6006 else
6007 {
6008 return hidden::evaluate_lambdas<ReturnClass>(make_typed_sequence_t<Size>{},
6009 tuple, std::forward<ArgFirst>(arg));
6010 }
6011 }
6012
6013 template< template<typename...> class ReturnClass,
6014 typename FuncType, typename... FuncTypes, typename ArgFirst>
6015 auto evaluate_lambdas(const std::tuple<FuncType, FuncTypes...>& tuple, ArgFirst&& arg)
6016 {
6017 constexpr auto Size = sizeof...(FuncTypes) + 1;
6018
6019 if constexpr(is_tuple_v<decltype(arg)>)
6020 {
6021 return hidden::evaluate_lambdas_tuple<ReturnClass>(make_typed_sequence_t<Size>{},
6022 tuple, std::forward<ArgFirst>(arg));
6023 }
6024 else
6025 {
6026 return hidden::evaluate_lambdas<ReturnClass>(make_typed_sequence_t<Size>{},
6027 tuple, std::forward<ArgFirst>(arg));
6028 }
6029 }
6030
6031 namespace hidden
6032 {
6033 template<typename... Types>
6034 struct arg_list{ };
6035
6036 template<typename T>
6038 {
6039 using type = T;
6040 };
6041
6042 template<typename... Ts>
6044 {
6045 using type = type_list_t<Ts...>;
6046 };
6047
6048 template<typename Type>
6050
6051 template<typename CallbackType, typename... ArgTypes> struct st_is_invocable;
6052
6053 template<typename CallbackType, typename... ArgTypes>
6054 struct st_is_invocable<CallbackType, arg_list<ArgTypes...>>
6055 {
6056 static constexpr bool value = std::is_invocable_v<CallbackType, ArgTypes...>;
6057 };
6058
6059 }
6060 // end of namespace hidden
6061
6062 template<typename CallbackType, typename... Types>
6063 constexpr bool is_invocable_v = hidden::st_is_invocable<CallbackType, Types...>::value;
6064
6065 namespace hidden
6066 {
6067 template<typename CallbackType, typename... Types> struct st_is_callable;
6068
6069 template<typename CallbackType, typename... CallableTypes, typename... NonCallableTypes>
6070 struct st_is_callable<CallbackType, type_list_t<CallableTypes...>, type_list_t<NonCallableTypes...>>
6071 {
6072 private:
6073 static constexpr bool value = is_invocable_v<CallbackType>;
6074
6075 using callable_list = type_list_t<CallableTypes...>;
6076 using non_callable_list = type_list_t<NonCallableTypes...>;
6077
6078 public:
6079
6080 using callables = std::conditional_t<value, types::push_back_type_t<void, callable_list>, callable_list>;
6081 using non_callables = std::conditional_t<!value, types::push_back_type_t<void, non_callable_list>, non_callable_list>;
6082 };
6083
6084 template<typename CallbackType, typename... CallableTypes, typename... NonCallableTypes, typename Type>
6085 struct st_is_callable<CallbackType, type_list_t<CallableTypes...>, type_list_t<NonCallableTypes...>, Type>
6086 {
6087 private:
6088 static constexpr bool value = is_invocable_v<CallbackType, Type>;
6089 using callable_list = type_list_t<CallableTypes...>;
6090 using non_callable_list = type_list_t<NonCallableTypes...>;
6091
6092 public:
6093
6094 using callables = std::conditional_t<value, types::push_back_type_t<Type, callable_list>, callable_list>;
6095 using non_callables = std::conditional_t<!value, types::push_back_type_t<Type, non_callable_list>, non_callable_list>;
6096 };
6097
6098 template<typename CallbackType, typename... CallableTypes, typename... NonCallableTypes, typename Type, typename... Types>
6099 struct st_is_callable<CallbackType, type_list_t<CallableTypes...>, type_list_t<NonCallableTypes...>, Type, Types...>
6100 {
6101 private:
6102 static constexpr bool value = is_invocable_v<CallbackType, Type>;
6103
6104 using callable_list = type_list_t<CallableTypes...>;
6105 using non_callable_list = type_list_t<NonCallableTypes...>;
6106
6107 using callables_tmp = std::conditional_t<value, types::push_back_type_t<Type, callable_list>, callable_list>;
6108 using non_callables_tmp = std::conditional_t<!value, types::push_back_type_t<Type, non_callable_list>, non_callable_list>;
6109
6110 using base_type = st_is_callable<CallbackType, callables_tmp, non_callables_tmp, Types...>;
6111 public:
6112
6113 using callables = typename base_type::callables;
6114 using non_callables = typename base_type::non_callables;
6115 };
6116
6117 template<typename CallbackType, typename... CallableTypes, typename... NonCallableTypes, typename... Types>
6118 struct st_is_callable<CallbackType, type_list_t<CallableTypes...>, type_list_t<NonCallableTypes...>, type_list_t<Types...>>
6119 {
6120 using base_type = st_is_callable<CallbackType, type_list_t<CallableTypes...>, type_list_t<NonCallableTypes...>, Types...>;
6121
6122 using callables = typename base_type::callables;
6123 using non_callables = typename base_type::non_callables;
6124 };
6125
6126 template<typename... Types> struct st_build_arg_types;
6127
6128 template<typename... Heads, typename... Tails>
6129 struct st_build_arg_types<type_list_t<Heads...>, type_list_t<Tails...>>
6130 {
6131 using type = type_list_t<hidden::arg_list<Heads, Tails...>...>;
6132 };
6133
6134 template<typename... Types> struct st_arg_to_type_list;
6135
6136 template<typename... Types>
6138 {
6139 using type = type_list_t<Types...>;
6140 };
6141
6142 template<typename... Types>
6144 {
6146 };
6147
6148 }
6149 // end of namespace hidden
6150
6151 template<typename... Types>
6152 using arg_to_type_list_t = typename hidden::st_arg_to_type_list<Types...>::type;
6153
6154 template<typename Heads, typename Tails>
6156
6157 template<typename CallbackType, typename... Types>
6159
6160 template<typename CallbackType, typename... Types>
6162
6163 template<typename CallbackType, typename... Types>
6164 constexpr bool is_all_callable_v = types::type_count_v<callable_list_t<CallbackType, Types...>> == types::type_count_v<Types...>;
6165
6166 template<typename CallbackType, typename... Types>
6167 constexpr bool is_any_callable_v = types::type_count_v<callable_list_t<CallbackType, Types...>> != 0;
6168
6170
6171 template<typename... Types>
6173
6174 template<> struct concate_type_st<>
6175 {
6177 };
6178
6179 template<> struct concate_type_st<type_list_t<>>
6180 {
6182 };
6183
6184 template<typename Type> struct concate_type_st<Type>
6185 {
6187 };
6188
6189 template<typename Type> struct concate_type_st<type_list_t<Type>>
6190 {
6192 };
6193
6194 template<typename Type, typename... Types>
6195 struct concate_type_st<Type, Types...>
6196 {
6197 using type = type_list_t<Type, Types...>;
6198 };
6199
6200 template<typename Type, typename... Types>
6202 {
6203 using type = type_list_t<Type, Types...>;
6204 };
6205
6206 template<typename Head, typename...Tails, typename... Types>
6207 struct concate_type_st<type_list_t<Head, Tails...>, Types...>
6208 {
6209 using type = type_list_t<Head, Tails..., Types...>;
6210 };
6211
6212 template<typename Type, typename Head2, typename... Tails2>
6213 struct concate_type_st<Type, type_list_t<Head2, Tails2...>>
6214 {
6215 using type = type_list_t<Type, Head2, Tails2...>;
6216 };
6217
6218 template<typename... Types1, typename... Types2>
6219 struct concate_type_st<type_list_t<Types1...>, type_list_t<Types2...>>
6220 {
6221 using type = type_list_t<Types1..., Types2...>;
6222 };
6223
6224 template<typename... Types>
6225 using concate_type_t = typename concate_type_st<Types...>::type;
6226
6227 template<typename Type>
6228 constexpr auto is_template_template_v = hidden::is_template_template_v<Type>;
6229
6230 template<bool OrAnd,
6231 bool LeftRight,
6232 typename Type,
6233 template<typename, typename...> class BinaryPredicate,
6234 typename ListHead, typename... ListTails>
6236
6237 template<bool LeftRight,
6238 typename Type,
6239 template<typename, typename...> class BinaryPredicate,
6240 typename ListHead, typename... ListTails>
6241 struct type_over_set_st<boolean::Or, LeftRight, Type, BinaryPredicate, ListHead, ListTails...>
6242 {
6243 static constexpr bool value =
6245 || type_over_set_st<boolean::Or, LeftRight, Type, BinaryPredicate, ListTails...>::value;
6246 };
6247
6248 template<bool LeftRight,
6249 typename Type,
6250 template<typename, typename...> class BinaryPredicate,
6251 typename ListHead, typename... ListTails>
6252 struct type_over_set_st<boolean::And, LeftRight, Type, BinaryPredicate, ListHead, ListTails...>
6253 {
6254 static constexpr bool value =
6256 && type_over_set_st<boolean::And, LeftRight, Type, BinaryPredicate, ListTails...>::value;
6257 };
6258
6259 template<typename Type,
6260 template<typename, typename...> class BinaryPredicate,
6261 typename ListHead, typename... ListTails>
6262 struct type_over_set_st<boolean::Or, boolean::Left, Type, BinaryPredicate, ListHead, ListTails...>
6263 {
6264 static constexpr bool value =
6266 || type_over_set_st<boolean::Or, boolean::Left, Type, BinaryPredicate, ListTails...>::value;
6267 };
6268
6269 template<typename Type,
6270 template<typename, typename...> class BinaryPredicate,
6271 typename ListHead, typename... ListTails>
6272 struct type_over_set_st<boolean::And, boolean::Left, Type, BinaryPredicate, ListHead, ListTails...>
6273 {
6274 static constexpr bool value =
6276 && type_over_set_st<boolean::And, boolean::Left, Type, BinaryPredicate, ListTails...>::value;
6277 };
6278
6279 template<typename Type,
6280 template<typename, typename...> class BinaryPredicate,
6281 typename ListHead, typename... ListTails>
6282 struct type_over_set_st<boolean::Or, boolean::Right, Type, BinaryPredicate, ListHead, ListTails...>
6283 {
6284 static constexpr bool value =
6286 || type_over_set_st<boolean::Or, boolean::Right, Type, BinaryPredicate, ListTails...>::value;
6287 };
6288
6289 template<typename Type,
6290 template<typename, typename...> class BinaryPredicate,
6291 typename ListHead, typename... ListTails>
6292 struct type_over_set_st<boolean::And, boolean::Right, Type, BinaryPredicate, ListHead, ListTails...>
6293 {
6294 static constexpr bool value =
6296 && type_over_set_st<boolean::And, boolean::Right, Type, BinaryPredicate, ListTails...>::value;
6297 };
6298
6299 template<typename Type, template<typename, typename...> class BinaryPredicate, typename ListHead>
6300 struct type_over_set_st<boolean::Or, boolean::Left, Type, BinaryPredicate, ListHead>
6301 {
6302 static constexpr bool value = BinaryPredicate<Type, ListHead>::value;
6303 };
6304
6305 template<typename Type, template<typename, typename...> class BinaryPredicate, typename ListHead>
6306 struct type_over_set_st<boolean::And, boolean::Left, Type, BinaryPredicate, ListHead>
6307 {
6308 static constexpr bool value = BinaryPredicate<Type, ListHead>::value;
6309 };
6310
6311 template<typename Type, template<typename, typename...> class BinaryPredicate, typename ListHead>
6312 struct type_over_set_st<boolean::Or, boolean::Right, Type, BinaryPredicate, ListHead>
6313 {
6314 static constexpr bool value = BinaryPredicate<ListHead, Type>::value;
6315 };
6316
6317 template<typename Type, template<typename, typename...> class BinaryPredicate, typename ListHead>
6318 struct type_over_set_st<boolean::And, boolean::Right, Type, BinaryPredicate, ListHead>
6319 {
6320 static constexpr bool value = BinaryPredicate<ListHead, Type>::value;
6321 };
6322
6323 template<bool OrAnd,
6324 bool LeftRight,
6325 typename Type,
6326 template<typename, typename...> class BinaryPredicate,
6327 typename ListHead, typename... ListTails>
6329 {
6330 static constexpr bool value =
6331 type_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate, ListHead, ListTails...>::value;
6332 };
6333
6334 template<bool OrAnd,
6335 bool LeftRight,
6336 typename Type,
6337 template<typename, typename...> class BinaryPredicate,
6338 typename ListHead, typename... ListTails>
6339 struct type_opr_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate,
6340 type_list_t<ListHead, ListTails...>>
6341 {
6342 static constexpr bool value =
6343 type_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate, ListHead, ListTails...>::value;
6344 };
6345
6346 template<bool OrAnd,
6347 bool LeftRight,
6348 typename Type,
6349 template<typename, typename...> class BinaryPredicate,
6350 typename Head, typename ListHead, typename... ListTails>
6351 struct type_opr_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate,
6352 Head, type_list_t<ListHead, ListTails...>>
6353 {
6354 static constexpr bool value =
6355 type_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate,
6356 Head, ListHead, ListTails...>::value;
6357 };
6358
6359 template<bool OrAnd,
6360 bool LeftRight,
6361 typename Type,
6362 template<typename, typename...> class BinaryPredicate,
6363 typename ListHead, typename... ListTails, typename Head, typename... Tails>
6364 struct type_opr_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate,
6365 type_list_t<ListHead, ListTails...>, Head, Tails...>
6366 {
6367 static constexpr bool value =
6368 type_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate,
6369 ListHead, ListTails..., Head, Tails...>::value;
6370 };
6371
6372 template<bool OrAnd,
6373 bool LeftRight,
6374 typename Type,
6375 template<typename, typename...> class BinaryPredicate,
6376 typename ListHead, typename... ListTails, typename Head, typename... Tails>
6377 struct type_opr_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate,
6378 type_list_t<ListHead, ListTails...>, type_list_t<Head, Tails...>>
6379 {
6380 static constexpr bool value =
6381 type_over_set_st<OrAnd, LeftRight, Type, BinaryPredicate,
6382 ListHead, ListTails..., Head, Tails...>::value;
6383 };
6384
6385 template<typename Type,
6386 typename ListHead, typename... ListTails>
6388 Type, std::is_same, ListHead, ListTails...>::value;
6389
6390 template<typename Type,
6391 typename ListHead, typename... ListTails>
6393 Type, std::is_constructible, ListHead, ListTails...>::value;
6394
6395 template<typename Type,
6396 typename ListHead, typename... ListTails>
6398 std::add_lvalue_reference_t<Type>, std::is_assignable, ListHead, ListTails...>::value;
6399
6400 template<typename Type,
6401 typename ListHead, typename... ListTails>
6403 std::add_lvalue_reference_t<Type>, std::is_assignable, ListHead, ListTails...>::value;
6404
6405 template<typename TestType, typename TypeList, typename ReturnType = TestType>
6407
6408 template<typename TestTypeList, typename TypeList, typename ReturnType = void>
6410
6411 namespace hidden
6412 {
6413 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6414 class container_of_variants_class: public ContainerType<std::variant<ElementTypes...>>
6415 {
6416 public:
6417 using base_type = ContainerType<std::variant<ElementTypes...>>;
6418 using base_type::base_type;
6419 using value_type = typename base_type::value_type;
6421 using element_types_t = type_list_t<ElementTypes...>;
6422
6423 decltype(auto) crbegin() const noexcept
6424 {
6425 return base_type::rcbegin();
6426 }
6427
6428 decltype(auto) crend() const noexcept
6429 {
6430 return base_type::crend();
6431 }
6432 };
6433
6434 template<typename KeyType, typename... ElementTypes>
6435 class container_of_variants_class<std::pair, KeyType, ElementTypes...>:
6436 public std::pair<KeyType, std::variant<ElementTypes...>>
6437 {
6438 public:
6439 using base_type = std::pair<KeyType, std::variant<ElementTypes...>>;
6440 using base_type::base_type;
6441
6442 using first_type = typename base_type::first_type;
6443 using second_type = typename base_type::second_type;
6444
6445 using element_types_t = type_list_t<ElementTypes...>;
6446 };
6447
6448 template<typename KeyType, typename... ElementTypes>
6449 class container_of_variants_class<std::map, KeyType, ElementTypes...>:
6450 public std::map<KeyType, std::variant<ElementTypes...>>
6451 {
6452 public:
6453 using base_type = std::map<KeyType, std::variant<ElementTypes...>>;
6454 using base_type::base_type;
6455 using value_type = typename base_type::value_type;
6457 using element_types_t = type_list_t<ElementTypes...>;
6458
6459 decltype(auto) crbegin() const noexcept
6460 {
6461 return base_type::rcbegin();
6462 }
6463
6464 decltype(auto) crend() const noexcept
6465 {
6466 return base_type::crend();
6467 }
6468 };
6469
6470 template<typename KeyType, typename... ElementTypes>
6471 class container_of_variants_class<std::multimap, KeyType, ElementTypes...>:
6472 public std::multimap<KeyType, std::variant<ElementTypes...>>
6473 {
6474 public:
6475 using base_type = std::multimap<KeyType, std::variant<ElementTypes...>>;
6476 using base_type::base_type;
6477 using value_type = typename base_type::value_type;
6479 using element_types_t = type_list_t<ElementTypes...>;
6480 };
6481
6482 template<typename KeyType, typename... ElementTypes>
6483 class container_of_variants_class<std::unordered_map, KeyType, ElementTypes...>:
6484 public std::unordered_map<KeyType, std::variant<ElementTypes...>>
6485 {
6486 public:
6487 using base_type = std::unordered_map<KeyType, std::variant<ElementTypes...>>;
6488 using base_type::base_type;
6489 using value_type = typename base_type::value_type;
6491 using element_types_t = type_list_t<ElementTypes...>;
6492 };
6493
6494 template<typename KeyType, typename... ElementTypes>
6495 class container_of_variants_class<std::unordered_multimap, KeyType, ElementTypes...>:
6496 public std::unordered_multimap<KeyType, std::variant<ElementTypes...>>
6497 {
6498 public:
6499 using base_type = std::unordered_multimap<KeyType, std::variant<ElementTypes...>>;
6500 using base_type::base_type;
6501 using value_type = typename base_type::value_type;
6503 using element_types_t = type_list_t<ElementTypes...>;
6504 };
6505
6506 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6508 {
6509 using type = container_of_variants_class<ContainerType, ElementTypes...>;
6510 };
6511
6512 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6513 struct container_of_variants_st<ContainerType, type_list_t<ElementTypes...>>
6514 {
6515 using type = container_of_variants_class<ContainerType, ElementTypes...>;
6516 };
6517
6518 template<typename KeyType, typename... ElementTypes>
6519 struct container_of_variants_st<std::pair, KeyType, type_list_t<ElementTypes...>>
6520 {
6521 using type = container_of_variants_class<std::pair, KeyType, ElementTypes...>;
6522 };
6523
6524 template<typename KeyType, typename... ElementTypes>
6525 struct container_of_variants_st<std::map, KeyType, type_list_t<ElementTypes...>>
6526 {
6527 using type = container_of_variants_class<std::map, KeyType, ElementTypes...>;
6528 };
6529
6530 template<typename KeyType, typename... ElementTypes>
6531 struct container_of_variants_st<std::multimap, KeyType, type_list_t<ElementTypes...>>
6532 {
6533 using type = container_of_variants_class<std::multimap, KeyType, ElementTypes...>;
6534 };
6535
6536 template<typename KeyType, typename... ElementTypes>
6537 struct container_of_variants_st<std::unordered_map, KeyType, type_list_t<ElementTypes...>>
6538 {
6539 using type = container_of_variants_class<std::unordered_map, KeyType, ElementTypes...>;
6540 };
6541
6542 template<typename KeyType, typename... ElementTypes>
6543 struct container_of_variants_st<std::unordered_multimap, KeyType, type_list_t<ElementTypes...>>
6544 {
6545 using type = container_of_variants_class<std::unordered_multimap, KeyType, ElementTypes...>;
6546 };
6547
6548 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6550 typename container_of_variants_st<ContainerType, unique_types_t<ElementTypes...>>::type;
6551
6552 template<template<typename, typename...> class ContainerType,
6553 typename KeyType, typename... ElementTypes>
6555 typename container_of_variants_st<ContainerType, KeyType, unique_types_t<ElementTypes...>>::type;
6556
6557 template<typename... ElementTypes>
6558 using vector_of_variants_t = container_of_variants_t<std::vector, ElementTypes...>;
6559
6560 template<typename... ElementTypes>
6561 using deque_of_variants_t = container_of_variants_t<std::deque, ElementTypes...>;
6562
6563 template<typename... ElementTypes>
6564 using list_of_variants_t = container_of_variants_t<std::list, ElementTypes...>;
6565
6566 template<typename... ElementTypes>
6567 using set_of_variants_t = container_of_variants_t<std::set, ElementTypes...>;
6568
6569 template<typename... ElementTypes>
6570 using multiset_of_variants_t = container_of_variants_t<std::multiset, ElementTypes...>;
6571
6572 template<typename... ElementTypes>
6573 using unordered_set_of_variants_t = container_of_variants_t<std::unordered_set, ElementTypes...>;
6574
6575 template<typename... ElementTypes>
6576 using unordered_multiset_of_variants_t = container_of_variants_t<std::unordered_multiset, ElementTypes...>;
6577
6578 template<typename... ElementTypes>
6579 using multiset_of_variants_t = container_of_variants_t<std::multiset, ElementTypes...>;
6580
6581 template<typename KeyType, typename... ElementTypes>
6582 using pair_of_variants_t = container_map_of_variants_t<std::pair, KeyType, ElementTypes...>;
6583
6584 template<typename KeyType, typename... ElementTypes>
6585 using map_of_variants_t = container_map_of_variants_t<std::map, KeyType, ElementTypes...>;
6586
6587 template<typename KeyType, typename... ElementTypes>
6588 using multimap_of_variants_t = container_map_of_variants_t<std::multimap, KeyType, ElementTypes...>;
6589
6590 template<typename KeyType, typename... ElementTypes>
6591 using unordered_map_of_variants_t = container_map_of_variants_t<std::unordered_map, KeyType, ElementTypes...>;
6592
6593 template<typename KeyType, typename... ElementTypes>
6594 using unordered_multimap_of_variants_t = container_map_of_variants_t<std::unordered_multimap, KeyType, ElementTypes...>;
6595
6596 }
6597 // end of namespace hidden
6598
6599 template<typename Type1, typename Type2,
6600 typename common_t = common_type_t<Type1, Type2>, // get the common type of type1_t and type2_t
6601 bool is_integral_type = is_integral_v<common_t>, // test if common_t is of integral type
6602 typename result_type = std::conditional_t<
6603 is_integral_type, // is common type integral?
6604 make_signed_t<common_t>, // if integral type, then get signed integeral type
6605 common_t> >
6606 using signed_common_t = result_type;
6607
6608 template<typename Type1, typename Type2,
6609 typename common_t = common_type_t<Type1, Type2>, // get the common type of type1_t and type2_t
6610 bool is_integral_type = is_integral_v<common_t>, // test if common_t is of integral type
6611 typename result_type = std::conditional_t<
6612 is_integral_type, // is common type integral?
6613 make_unsigned_t<common_t>, // if integral type, then get signed integeral type
6614 common_t> >
6615 using unsigned_common_t = result_type;
6616
6617 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6618 using container_of_variants_t = hidden::container_of_variants_t<ContainerType, ElementTypes...>;
6619
6620 template<typename... ElementTypes>
6622
6623 template<typename... ElementTypes>
6625
6626 template<typename... ElementTypes>
6628
6629 template<typename... ElementTypes>
6631
6632 template<typename... ElementTypes>
6634
6635 template<typename... ElementTypes>
6637
6638 template<typename... ElementTypes>
6640
6641 template<typename... ElementTypes>
6643
6644 template<typename KeyType, typename... ElementTypes>
6645 using map_of_variants_t = hidden::map_of_variants_t<KeyType, ElementTypes...>;
6646
6647 template<typename KeyType, typename... ElementTypes>
6649
6650 template<typename KeyType, typename... ElementTypes>
6652
6653 template<typename KeyType, typename... ElementTypes>
6655
6657 namespace hidden
6658 {
6659 template<typename Type, typename... Types>
6661 {
6663 };
6664
6665 template<template<typename...>class ClassTemplate,
6666 typename... InnerTypes, typename... Types>
6667 struct types_to_template_class_st<ClassTemplate<InnerTypes...>, Types...>
6668 {
6669 using type = ClassTemplate<Types...>;
6670 };
6671
6672 template<template<typename...>class ClassTemplate,
6673 typename... InnerTypes, typename... Types>
6674 struct types_to_template_class_st<ClassTemplate<InnerTypes...>,
6675 type_list_t<Types...>>
6676 {
6677 using type = ClassTemplate<Types...>;
6678 };
6679
6680 template<typename Type, typename... Types>
6682 {
6683 using type = typename
6685 };
6686
6687 template<template<typename...>class ClassTemplate,
6688 typename... InnerTypes, typename... Types>
6689 struct types_to_template_class_wrapper_st<ClassTemplate<InnerTypes...>, Types...>
6690 {
6691 using type = typename
6692 types_to_template_class_st<ClassTemplate<InnerTypes...>, Types...>::type;
6693 };
6694
6695 template<typename... InnerTypes, typename... Types>
6696 struct types_to_template_class_wrapper_st<std::variant<InnerTypes...>, Types...>
6697 {
6698 using type = typename
6699 types_to_template_class_st<std::variant<InnerTypes...>, unique_types_t<Types...>>::type;
6700 };
6701
6702 template<template<typename...>class ClassTemplate,
6703 typename... InnerTypes, typename... Types>
6704 struct types_to_template_class_wrapper_st<ClassTemplate<InnerTypes...>,
6705 type_list_t<Types...>>
6706 {
6707 using type =
6708 typename types_to_template_class_st<ClassTemplate<InnerTypes...>, Types...>::type;
6709 };
6710
6711 template<typename... InnerTypes, typename... Types>
6712 struct types_to_template_class_wrapper_st<std::variant<InnerTypes...>, type_list_t<Types...>>
6713 {
6714 using type =
6715 typename types_to_template_class_st<std::variant<InnerTypes...>, unique_types_t<Types...>>::type;
6716 };
6717
6718 template<typename Type, typename... Types>
6720 typename types_to_template_class_wrapper_st<Type, Types...>::type;
6721
6722 template<template<typename...>class ClassTemplate, typename... Types>
6724 {
6725 using type = ClassTemplate<Types...>;
6726 };
6727
6728 template<template<typename...>class ClassTemplate, typename... Types>
6729 struct type_list_to_template_class_st<ClassTemplate, type_list_t<Types...>>
6730 {
6731 using type = ClassTemplate<Types...>;
6732 };
6733
6734 template<template<typename...>class ClassTemplate, typename... Types>
6736 {
6737 using type = typename type_list_to_template_class_st<ClassTemplate, Types...>::type;
6738 };
6739
6740 template<template<typename...>class ClassTemplate, typename... Types>
6742 {
6743 using type = typename type_list_to_template_class_st<ClassTemplate, Types...>::type;
6744 };
6745
6746 template<typename... Types>
6748 {
6749 using type = typename type_list_to_template_class_st<std::variant,
6750 unique_types_t<Types...>>::type;
6751 };
6752
6753 template<typename... Types>
6755 {
6756 using type = typename type_list_to_template_class_st<std::variant,
6757 unique_types_t<Types...>>::type;
6758 };
6759
6760 template<template<typename...>class ClassTemplate, typename... Types>
6762 typename type_list_to_template_class_wrapper_st<ClassTemplate, Types...>::type;
6763
6765 template<size_t TypeIndex, typename TemplateClass, typename... Types>
6767
6768 template<size_t TypeIndex,
6769 template<typename...> class TemplateClass,
6770 typename... InnerTypes, typename... Types>
6771 struct nth_type_to_template_class_st<TypeIndex, TemplateClass<InnerTypes...>, Types...>
6772 {
6773 static_assert(TypeIndex < sizeof...(Types), "TypeIndex is out of range");
6774
6775 using nth_type = select_nth_type_t<TypeIndex, type_list_t<Types...>>;
6776 using type = std::conditional_t<is_valid_type_v<nth_type>, TemplateClass<nth_type>, nth_type>;
6777 };
6778
6779 template<size_t TypeIndex,
6780 template<typename...> class TemplateClass,
6781 typename... InnerTypes, typename... Types>
6782 struct nth_type_to_template_class_st<TypeIndex, TemplateClass<InnerTypes...>, type_list_t<Types...>>
6783 {
6784 static_assert(TypeIndex < sizeof...(Types), "TypeIndex is out of range");
6785
6786 using nth_type = select_nth_type_t<TypeIndex, type_list_t<Types...>>;
6787 using type = std::conditional_t<is_valid_type_v<nth_type>, TemplateClass<nth_type>, nth_type>;
6788 };
6789
6790 template<size_t TypeIndex, typename TemplateClass, typename... Types>
6792 typename nth_type_to_template_class_st<TypeIndex, TemplateClass, Types...>::type;
6793
6795 template<size_t FirstN,
6796 template<typename...> typename TemplateClass, typename... Types>
6798 {
6799 static_assert(FirstN <= sizeof...(Types), "FirstN is out of range");
6800 using n_types = first_n_types_t<FirstN, type_list_t<Types...>>;
6801
6802 using class_t = std::conditional_t<is_valid_type_v<n_types>,
6804
6805 using type = std::conditional_t<is_valid_type_v<class_t>, class_t, no_type_t>;
6806 };
6807
6808 template<size_t FirstN, template<typename...> class TemplateClass, typename... Types>
6809 struct first_n_types_list_to_template_class_st<FirstN, TemplateClass, type_list_t<Types...>>
6810 {
6811 static_assert(FirstN <= sizeof...(Types), "FirstN is out of range");
6812 using n_types = first_n_types_t<FirstN, type_list_t<Types...>>;
6813
6814 using class_t = std::conditional_t<is_valid_type_v<n_types>,
6816
6817 using type = std::conditional_t<is_valid_type_v<class_t>, class_t, no_type_t>;
6818 };
6819
6820 template<size_t FirstN, template<typename...> typename TemplateClass, typename... Types>
6822 typename first_n_types_list_to_template_class_st<FirstN, TemplateClass, Types...>::type;
6823
6825 template<size_t FirstN, typename TemplateClass, typename... Types>
6827
6828 template<size_t FirstN,
6829 template<typename...> class TemplateClass,
6830 typename... InnerTypes, typename... Types>
6831 struct first_n_types_to_template_class_st<FirstN, TemplateClass<InnerTypes...>, Types...>
6832 {
6833 static_assert(FirstN <= sizeof...(Types), "FirstN is out of range");
6834 using n_types = first_n_types_t<FirstN, type_list_t<Types...>>;
6835
6836 using class_t = std::conditional_t<is_valid_type_v<n_types>,
6838
6839 using type = std::conditional_t<is_valid_type_v<class_t>, class_t, no_type_t>;
6840 };
6841
6842 template<size_t FirstN,
6843 template<typename...> class TemplateClass,
6844 typename... InnerTypes, typename... Types>
6845 struct first_n_types_to_template_class_st<FirstN, TemplateClass<InnerTypes...>, type_list_t<Types...>>
6846 {
6847 static_assert(FirstN <= sizeof...(Types), "FirstN is out of range");
6848 using n_types = first_n_types_t<FirstN, type_list_t<Types...>>;
6849
6850 using class_t = std::conditional_t<is_valid_type_v<n_types>,
6852
6853 using type = std::conditional_t<is_valid_type_v<class_t>, class_t, no_type_t>;
6854 };
6855
6856 template<size_t FirstN, typename TemplateClass, typename... Types>
6858 typename first_n_types_to_template_class_st<FirstN, TemplateClass, Types...>::type;
6859
6861
6862
6863 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6864 class container_of_tuples_class : public ContainerType< std::tuple<ElementTypes...> >
6865 {
6866 public:
6867
6868 using base_type = ContainerType< std::tuple<ElementTypes...> >;
6869 using base_type::base_type;
6870
6871 using value_type = typename base_type::value_type;
6873
6874 using element_types_t = type_list_t<ElementTypes...>;
6875 };
6876
6877 template<typename KeyType, typename... ElementTypes>
6878 class container_of_tuples_class<std::map, KeyType, ElementTypes...>
6879 : public std::map<KeyType, std::tuple<ElementTypes...>>
6880 {
6881 public:
6882
6883 using base_type = std::map<KeyType, std::tuple<ElementTypes...>>;
6884 using base_type::base_type;
6885
6886 using value_type = typename base_type::value_type;
6887 using tuple_type = std::tuple<ElementTypes...>;
6888
6889 using element_types_t = type_list_t<ElementTypes...>;
6890 };
6891
6892 template<typename KeyType, typename... ElementTypes>
6893 class container_of_tuples_class<std::multimap, KeyType, ElementTypes...>
6894 : public std::multimap<KeyType, std::tuple<ElementTypes...>>
6895 {
6896 public:
6897
6898 using base_type = std::multimap<KeyType, std::tuple<ElementTypes...>>;
6899 using base_type::base_type;
6900
6901 using value_type = typename base_type::value_type;
6902 using tuple_type = std::tuple<ElementTypes...>;
6903
6904 using element_types_t = type_list_t<ElementTypes...>;
6905 };
6906
6907 template<typename KeyType, typename... ElementTypes>
6908 class container_of_tuples_class<std::unordered_map, KeyType, ElementTypes...>
6909 : public std::unordered_map<KeyType, std::tuple<ElementTypes...>>
6910 {
6911 public:
6912
6913 using base_type = std::unordered_map<KeyType, std::tuple<ElementTypes...>>;
6914 using base_type::base_type;
6915
6916 using value_type = typename base_type::value_type;
6917 using tuple_type = std::tuple<ElementTypes...>;
6918
6919 using element_types_t = type_list_t<ElementTypes...>;
6920 };
6921
6922 template<typename KeyType, typename... ElementTypes>
6923 class container_of_tuples_class<std::unordered_multimap, KeyType, ElementTypes...>
6924 : public std::unordered_multimap<KeyType, std::tuple<ElementTypes...>>
6925 {
6926 public:
6927
6928 using base_type = std::unordered_multimap<KeyType, std::tuple<ElementTypes...>>;
6929 using base_type::base_type;
6930
6931 using value_type = typename base_type::value_type;
6932 using tuple_type = std::tuple<ElementTypes...>;
6933
6934 using element_types_t = type_list_t<ElementTypes...>;
6935 };
6936
6937 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6939 {
6940 using type = container_of_tuples_class<ContainerType, ElementTypes...>;
6941 };
6942
6943 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6944 struct container_of_tuples_st<ContainerType, type_list_t<ElementTypes...>>
6945 {
6946 using type = container_of_tuples_class<ContainerType, ElementTypes...>;
6947 };
6948
6949 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6950 using container_of_tuples_t = typename container_of_tuples_st<ContainerType, ElementTypes...>::type;
6951
6952 template<typename... ElementTypes>
6953 using vector_of_tuples_t = container_of_tuples_t<std::vector, ElementTypes...>;
6954
6955 template<typename... ElementTypes>
6956 using deque_of_tuples_t = container_of_tuples_t<std::deque, ElementTypes...>;
6957
6958 template<typename... ElementTypes>
6959 using list_of_tuples_t = container_of_tuples_t<std::list, ElementTypes...>;
6960
6961 template<typename... ElementTypes>
6962 using set_of_tuples_t = container_of_tuples_t<std::set, ElementTypes...>;
6963
6964 template<typename KeyType, typename... ElementTypes>
6965 using map_of_tuples_t = container_of_tuples_t<std::map, KeyType, ElementTypes...>;
6966
6967 template<typename KeyType, typename... ElementTypes>
6968 using multimap_of_tuples_t = container_of_tuples_t<std::multimap, KeyType, ElementTypes...>;
6969
6970 template<typename KeyType, typename... ElementTypes>
6971 using unordered_map_of_tuples_t = container_of_tuples_t<std::unordered_map, KeyType, ElementTypes...>;
6972
6973 template<typename KeyType, typename... ElementTypes>
6974 using unordered_multimap_of_tuples_t = container_of_tuples_t<std::unordered_multimap, KeyType, ElementTypes...>;
6975
6976 }
6977 // end of namespace hidden
6978
6979 template<typename Type, typename... Types>
6981
6982 template<template<typename...> class ClassTemplate, typename... Types>
6984
6985 template<size_t SelectTypeIndex, typename TemplateClass, typename... Types>
6987 hidden::nth_type_to_template_class_t<SelectTypeIndex, TemplateClass, Types...>;
6988
6989 template<size_t FirstN, typename TemplateClass, typename... Types>
6991 hidden::first_n_types_to_template_class_t<FirstN, TemplateClass, Types...>;
6992
6993 template<size_t FirstN, template<typename...> typename TemplateClass, typename... Types>
6995 hidden::first_n_types_list_to_template_class_t<FirstN, TemplateClass, Types...>;
6996
6997 template<template<typename, typename...> class ContainerType, typename... ElementTypes>
6998 using container_of_tuples_t = hidden::container_of_tuples_t<ContainerType, ElementTypes...>;
6999
7000 template<typename... ElementTypes>
7002
7003 template<typename... ElementTypes>
7005
7006 template<typename... ElementTypes>
7008
7009 template<typename... ElementTypes>
7011
7012 template<typename KeyType, typename... ElementTypes>
7013 using map_of_tuples_t = hidden::map_of_tuples_t<KeyType, ElementTypes...>;
7014
7015 template<typename KeyType, typename... ElementTypes>
7016 using multimap_of_tuples_t = hidden::multimap_of_tuples_t<KeyType, ElementTypes...>;
7017
7018 template<typename KeyType, typename... ElementTypes>
7020
7021 template<typename KeyType, typename... ElementTypes>
7023
7024 template<template<typename, typename...> class ContainerType,
7025 typename EleType, typename... Types>
7026 auto erase(ContainerType<EleType, Types...>& container, size_t index)
7027 {
7028 auto itr = container.begin();
7029 std::advance(itr, index);
7030 return container.erase(itr);
7031 }
7032
7033 template<template<typename, typename...> class ContainerType, typename Type, typename... Types>
7034 auto pop_front(ContainerType<Type, Types...>& container)
7035 {
7036 if(container.empty())
7037 {
7038 Tpf_ThrowDebugException("container empty");
7039 }
7040
7041 if constexpr (is_front_available_v<decltype(container)>)
7042 {
7043 auto front = container.front();
7044
7045 if constexpr(is_pop_front_available_v<decltype(container)>)
7046 container.pop_front();
7047 else
7048 {
7049 auto front_itr = container.begin();
7050 container.erase(front_itr);
7051 }
7052
7053 return front;
7054 }
7055 else
7056 {
7057 if constexpr (is_pop_front_available_v<decltype(container)>)
7058 {
7059 auto front = *container.begin();
7060 container.pop_front();
7061 return front;
7062 }
7063 else
7064 {
7065 auto front_itr = container.begin();
7066 auto front = *front_itr;
7067 container.erase(front_itr);
7068 return front;
7069 }
7070 }
7071 }
7072
7073 template<template<typename, typename...> class ContainerType, typename Type, typename... Types>
7074 auto pop_back(ContainerType<Type, Types...>& container)
7075 {
7076 if(container.empty())
7077 {
7078 Tpf_ThrowDebugException("container empty");
7079 }
7080
7081 auto back = container.back();
7082 container.pop_back();
7083 return back;
7084 }
7085
7086 template<template<typename, typename...> class ContainerType,
7087 typename EleType, typename Type, typename... Types>
7088 void push_front(ContainerType<Type, Types...>& container, EleType&& ele)
7089 {
7090 if constexpr(is_push_front_available_v<decltype(container)>)
7091 {
7092 container.push_front(std::forward<EleType>(ele));
7093 }
7094 else if constexpr(is_insert_iterator_available_v<decltype(container)>)
7095 {
7096 container.insert(container.cbegin(), std::forward<EleType>(ele));
7097 }
7098 else if constexpr(is_insert_available_v<decltype(container)>)
7099 {
7100 container.insert(std::forward<EleType>(ele));
7101 }
7102 else
7103 {
7104 Tpf_ThrowDebugException("Cannot push front");
7105 }
7106 }
7107
7108 template<template<typename, typename...> class ContainerType,
7109 typename EleType, typename Type, typename... Types>
7110 void push_back(ContainerType<Type, Types...>& container, EleType&& ele)
7111 {
7112 if constexpr(is_push_back_available_v<decltype(container)>)
7113 {
7114 container.push_back(std::forward<EleType>(ele));
7115 }
7116 else if constexpr(is_insert_iterator_available_v<decltype(container)>)
7117 {
7118 container.insert(container.cend(), std::forward<EleType>(ele));
7119 }
7120 else if constexpr(is_insert_available_v<decltype(container)>)
7121 {
7122 container.insert(std::forward<EleType>(ele));
7123 }
7124 else
7125 {
7126 Tpf_ThrowDebugException("Cannot push back");
7127 }
7128 }
7129
7130 template<template<typename, typename...> class ContainerType,
7131 typename... EleTypes, typename Type, typename... Types>
7132 void emplace_front(ContainerType<Type, Types...>& container, EleTypes&&... eles)
7133 {
7134 if constexpr(is_emplace_front_available_v<decltype(container)>)
7135 {
7136 container.emplace_front(std::forward<EleTypes>(eles)...);
7137 }
7138 else if constexpr(is_emplace_available_v<decltype(container)>)
7139 {
7140 container.emplace(container.cbegin(), std::forward<EleTypes>(eles)...);
7141 }
7142 else
7143 {
7144 container.insert(container.cbegin(), std::forward<EleTypes>(eles)...);
7145 }
7146 }
7147
7148 template<template<typename, typename...> class ContainerType,
7149 typename... EleTypes, typename Type, typename... Types>
7150 void emplace_back(ContainerType<Type, Types...>& container, EleTypes&&... eles)
7151 {
7152 if constexpr(is_emplace_back_available_v<decltype(container)>)
7153 {
7154 container.emplace_back(std::forward<EleTypes>(eles)...);
7155 }
7156 else if constexpr(is_emplace_available_v<decltype(container)>)
7157 {
7158 container.emplace_back(container.cend(), std::forward<EleTypes>(eles)...);
7159 }
7160 else
7161 {
7162 container.insert(container.cend(), std::forward<EleTypes>(eles)...);
7163 }
7164 }
7165
7166 template<template<typename, typename...> class ContainerType, typename Type, typename... Types>
7167 ContainerType<Type, Types...> reverse_order(const ContainerType<Type, Types...>& container)
7168 {
7169 return {container.crbegin(), container.crend()};
7170 }
7171
7172 template<template<typename, typename...> class ContainerType, typename Type, typename... Types>
7173 void reverse_order_in_place(ContainerType<Type, Types...>& container)
7174 {
7175 container = ContainerType<Type, Types...>{container.crbegin(), container.crend()};
7176 }
7177
7178 template<bool bReverseOrder, typename TargetContainerType, typename SourceContainerType>
7179 void append_to_container(TargetContainerType& target_container, SourceContainerType&& source_container)
7180 {
7181 if constexpr(std::is_rvalue_reference_v<decltype(source_container)>)
7182 {
7183 if constexpr (bReverseOrder)
7184 {
7185 target_container.insert(target_container.cend(),
7186 std::make_move_iterator(source_container.rbegin()),
7187 std::make_move_iterator(source_container.rend()));
7188 }
7189 else
7190 {
7191 target_container.insert(target_container.cend(),
7192 std::make_move_iterator(source_container.begin()),
7193 std::make_move_iterator(source_container.end()));
7194 }
7195 }
7196 else
7197 {
7198 if constexpr(bReverseOrder)
7199 {
7200 target_container.insert(target_container.cend(),
7201 source_container.crbegin(),
7202 source_container.crend());
7203 }
7204 else
7205 {
7206 target_container.insert(target_container.cend(),
7207 source_container.cbegin(),
7208 source_container.cend());
7209 }
7210 }
7211 }
7212
7213 template<bool bReverseOrder, typename TargetContainerType, typename SourceContainerType>
7214 void prepend_to_container(TargetContainerType& target_container, SourceContainerType&& source_container)
7215 {
7216 if constexpr(std::is_rvalue_reference_v<decltype(source_container)>)
7217 {
7218 if constexpr(bReverseOrder)
7219 {
7220 target_container.insert(target_container.cbegin(),
7221 std::make_move_iterator(source_container.rbegin()),
7222 std::make_move_iterator(source_container.rend()));
7223 }
7224 else
7225 {
7226 target_container.insert(target_container.cbegin(),
7227 std::make_move_iterator(source_container.begin()),
7228 std::make_move_iterator(source_container.end()));
7229 }
7230 }
7231 else
7232 {
7233 if constexpr (bReverseOrder)
7234 {
7235 target_container.insert(target_container.cbegin(),
7236 source_container.crbegin(),
7237 source_container.crend());
7238 }
7239 else
7240 {
7241 target_container.insert(target_container.cbegin(),
7242 source_container.cbegin(),
7243 source_container.cend());
7244 }
7245 }
7246 }
7247
7248 template<template<typename, typename...> class ContainerType, typename Type, typename... Types>
7249 auto make_random_access_container(Type&& arg, Types&&... args)
7250 {
7251 using parameter_types = decay_remove_cv_ref_type_list_t<Type, Types...>;
7252 using common_type = common_type_t<parameter_types>;
7253
7254 static_assert(common_type_v<parameter_types>, "Common Type Does Not Exist");
7255
7256 if constexpr(is_same_v<parameter_types>)
7257 {
7258 using container_t = ContainerType<common_type>;
7259
7260 return container_t{ std::forward<Type>(arg), std::forward<Types>(args)... };
7261 }
7262 else if constexpr(tpf::types::is_integral_v<common_type>)
7263 {
7264 // test if all types are of unsigned integral types
7265 if constexpr (are_unsigned_integrals_v<parameter_types>)
7266 {
7267 using container_t = ContainerType<common_type>;
7268
7269 return container_t{ static_cast<common_type>(std::forward<Type>(arg) ),
7270 static_cast<common_type>( std::forward<Types>(args) )...};
7271 }
7272 else
7273 {
7274 using element_t = std::make_signed_t<common_type>;
7275 using container_t = ContainerType<element_t>;
7276
7277 return container_t{
7278 static_cast<element_t>(std::forward<Type>(arg)),
7279 static_cast<element_t>(std::forward<Types>(args))... };
7280 }
7281 }
7282 else
7283 {
7284 using element_t = common_type;
7285 using container_t = ContainerType<element_t>;
7286
7287 return container_t{ static_cast<element_t>(std::forward<Type>(arg)),
7288 static_cast<element_t>(std::forward<Types>(args))... };
7289 }
7290 }
7291
7292 template<typename Type, typename... Types>
7293 auto make_vector(Type&& arg, Types&&... args)
7294 {
7295 using parameter_types = decay_remove_cv_ref_type_list_t<Type, Types...>;
7296 using common_type = common_type_t<parameter_types>;
7297
7298 static_assert(common_type_v<parameter_types>, "Common Type Does Not Exist");
7299
7300 if constexpr(is_same_v<parameter_types>)
7301 {
7302 using container_t = std::vector<common_type>;
7303
7304 return container_t{ std::forward<Type>(arg), std::forward<Types>(args)... };
7305 }
7306 else if constexpr(tpf::types::is_integral_v<common_type>)
7307 {
7308 // test if all types are of unsigned integral types
7309 if constexpr (are_unsigned_integrals_v<parameter_types>)
7310 {
7311 using container_t = std::vector<common_type>;
7312
7313 return container_t{ static_cast<common_type>(std::forward<Type>(arg) ),
7314 static_cast<common_type>( std::forward<Types>(args) )...};
7315 }
7316 else
7317 {
7318 using element_t = std::make_signed_t<common_type>;
7319 using container_t = std::vector<element_t>;
7320
7321 return container_t{
7322 static_cast<element_t>(std::forward<Type>(arg)),
7323 static_cast<element_t>(std::forward<Types>(args))... };
7324 }
7325 }
7326 else
7327 {
7328 using element_t = common_type;
7329 using container_t = std::vector<element_t>;
7330
7331 return container_t{ static_cast<element_t>(std::forward<Type>(arg)),
7332 static_cast<element_t>(std::forward<Types>(args))... };
7333 }
7334 }
7335
7336 template<typename Type, typename... Types>
7337 auto make_deque(Type&& arg, Types&&... args)
7338 {
7339 using parameter_types = decay_remove_cv_ref_type_list_t<Type, Types...>;
7340 using common_type = common_type_t<parameter_types>;
7341
7342 static_assert(common_type_v<parameter_types>, "Common Type Does Not Exist");
7343
7344 if constexpr(is_same_v<parameter_types>)
7345 {
7346 using container_t = std::deque<common_type>;
7347
7348 return container_t{ std::forward<Type>(arg), std::forward<Types>(args)... };
7349 }
7350 else if constexpr(tpf::types::is_integral_v<common_type>)
7351 {
7352 // test if all types are of unsigned integral types
7353 if constexpr (are_unsigned_integrals_v<parameter_types>)
7354 {
7355 using container_t = std::deque<common_type>;
7356
7357 return container_t{ static_cast<common_type>(std::forward<Type>(arg) ),
7358 static_cast<common_type>( std::forward<Types>(args) )...};
7359 }
7360 else
7361 {
7362 using element_t = std::make_signed_t<common_type>;
7363 using container_t = std::deque<element_t>;
7364
7365 return container_t{
7366 static_cast<element_t>(std::forward<Type>(arg)),
7367 static_cast<element_t>(std::forward<Types>(args))... };
7368 }
7369 }
7370 else
7371 {
7372 using element_t = common_type;
7373 using container_t = std::deque<element_t>;
7374
7375 return container_t{ static_cast<element_t>(std::forward<Type>(arg)),
7376 static_cast<element_t>(std::forward<Types>(args))... };
7377 }
7378 }
7379
7389 template<typename ArgType, typename... ArgTypes>
7390 auto make_container(ArgType&& arg, ArgTypes&& ... args)
7391 {
7392 constexpr bool common_exisits =
7393 common_type_v< tpf::remove_cv_ref_t<ArgType>, tpf::remove_cv_ref_t<ArgTypes>... >;
7394
7395 if constexpr (common_exisits)
7396 {
7398
7399 return std::vector { smart_forward<ele_t, ArgType>(arg),
7400 smart_forward<ele_t, ArgTypes>(args)... };
7401 }
7402 else
7403 {
7404 return std::tuple{ std::forward<ArgType>(arg), std::forward<ArgTypes>(args)... };
7405 }
7406 }
7407
7408 template< template<typename, typename...> class ContainerType,
7409 typename ArgType, typename... ArgTypes>
7410 auto make_container(ArgType&& arg, ArgTypes&& ... args)
7411 {
7412 constexpr bool common_exisits =
7413 common_type_v< tpf::remove_cv_ref_t<ArgType>, tpf::remove_cv_ref_t<ArgTypes>... >;
7414
7415 if constexpr (common_exisits)
7416 {
7418
7419 return ContainerType{ smart_forward<ele_t, ArgType>(arg),
7420 smart_forward<ele_t, ArgTypes>(args)... };
7421 }
7422 else
7423 {
7424 return std::tuple{ std::forward<ArgType>(arg), std::forward<ArgTypes>(args)... };
7425 }
7426 }
7427
7428 template< template<typename, std::size_t> class ContainerType,
7429 typename ArgType, typename... ArgTypes>
7430 auto make_container(ArgType&& arg, ArgTypes&& ... args)
7431 {
7432 constexpr bool common_exisits =
7433 common_type_v< tpf::remove_cv_ref_t<ArgType>, tpf::remove_cv_ref_t<ArgTypes>... >;
7434
7435 if constexpr (common_exisits)
7436 {
7437 using ele_t = make_signed_t<common_type_t<tpf::remove_cv_ref_t<ArgType>, tpf::remove_cv_ref_t<ArgTypes>...>>;
7438
7439 return ContainerType{ smart_forward<ele_t, ArgType>(arg),
7440 smart_forward<ele_t, ArgTypes>(args)... };
7441 }
7442 else
7443 {
7444 return std::tuple{ std::forward<ArgType>(arg), std::forward<ArgTypes>(args)... };
7445 }
7446 }
7447
7457 template<typename ArgType, typename... ArgTypes>
7458 auto create_container(ArgType&& arg, ArgTypes&& ... args)
7459 {
7460 constexpr bool common_exisits =
7461 common_type_v< tpf::remove_cv_ref_t<ArgType>, tpf::remove_cv_ref_t<ArgTypes>... >;
7462
7463 if constexpr (common_exisits)
7464 {
7466
7467 return std::array { smart_forward<ele_t, ArgType>(arg),
7468 smart_forward<ele_t, ArgTypes>(args)... };
7469 }
7470 else
7471 {
7472 return std::tuple{ std::forward<ArgType>(arg), std::forward<ArgTypes>(args)... };
7473 }
7474 }
7475
7476 #if !defined(__clang_major__)
7477
7478 template<typename Type, typename... Types>
7479 auto make_variants(Type&& arg, Types&&... args)
7480 {
7481 using parameter_types = decay_remove_cv_ref_type_list_t<Type, Types...>;
7482
7483 if constexpr(is_same_v<parameter_types> || common_type_v<parameter_types>)
7484 {
7485 return make_vector(std::forward<Type>(arg), std::forward<Types>(args)...);
7486 }
7487 else
7488 {
7490
7491 return std::vector<element_t>{ element_t{ std::forward<Type>(arg) },
7492 element_t{ std::forward<Types>(args) }... };
7493 }
7494 }
7495
7496 #endif
7497
7498 template<typename ContainerType>
7500 {
7501 private:
7502 ContainerType m_container;
7503
7504 public:
7505
7506 reverse_st(ContainerType container):
7507 m_container{ container } { }
7508
7509 auto empty() const noexcept { return m_container.empty(); }
7510 auto size() const noexcept { return m_container.size(); }
7511
7512 decltype(auto) begin() noexcept //(noexcept(m_container.rbegin()))
7513 {
7514 static_assert(!is_const_reference_v<ContainerType>, "--- use const auto&");
7515
7516 return m_container.rbegin();
7517 }
7518
7519 decltype(auto) end() noexcept // (noexcept(m_container.rend()))
7520 {
7521 static_assert(!is_const_reference_v<ContainerType>, "--- use const auto&");
7522 return m_container.rend();
7523 }
7524
7525 decltype(auto) cbegin() const noexcept //(noexcept(m_container.crbegin()))
7526 {
7527 return m_container.crbegin();
7528 }
7529
7530 decltype(auto) cend() const noexcept // (noexcept(m_container.crend()))
7531 {
7532 return m_container.crend();
7533 }
7534
7535 auto clone() const
7536 {
7537 using container_type = tpf::remove_cv_ref_t<ContainerType>;
7538
7539 return container_type{ m_container.crbegin(), m_container.crend() };
7540 }
7541 };
7542
7543 template<typename ElementType, size_t ElementCount>
7544 class reverse_st<ElementType(&)[ElementCount]>
7545 {
7546 private:
7547 using ContainerType = ElementType(&)[ElementCount];
7548
7549 ContainerType m_container;
7550 public:
7551
7552 auto empty() const noexcept { return false; }
7553 auto size() const noexcept { return ElementCount; }
7554
7555 reverse_st(ContainerType container): m_container{container} { }
7556
7557 using reverse_iterator = std::reverse_iterator<ElementType*>;
7558
7559 decltype(auto) begin() noexcept
7560 {
7561 return reverse_iterator{&m_container[ElementCount]};
7562 }
7563
7564 decltype(auto) end() noexcept
7565 {
7566 return reverse_iterator{&m_container[0]};
7567 }
7568
7569 decltype(auto) cbegin() const noexcept
7570 {
7571 return reverse_iterator{&m_container[ElementCount]};
7572 }
7573
7574 decltype(auto) cend() const noexcept
7575 {
7576 return reverse_iterator{&m_container[0]};
7577 }
7578
7579 auto clone() const
7580 {
7581 using element_t = std::remove_cv_t<ElementType>;
7582 return std::vector<element_t>{ cbegin(), cend() };
7583 }
7584 };
7585
7586 template<typename ContainerType>
7587 auto reverse(ContainerType&& container)
7588 {
7589 using reserve_t = reverse_st<ContainerType>;
7590
7591 return reserve_t{ std::forward<ContainerType>(container) };
7592 }
7593
7594 template<typename ElementType, size_t ElementCount>
7595 auto reverse(ElementType(&array)[ElementCount])
7596 {
7597 using array_type = ElementType(&)[ElementCount];
7598
7599 using reverse_t = reverse_st<array_type>;
7600
7601 return reverse_t{array};
7602 }
7603
7604 template<typename Type, typename... Types>
7605 auto reverse(Type&& arg, Types&&... args)
7606 {
7607 using parameter_types = decay_remove_cv_ref_type_list_t<Type, Types...>;
7608
7609 static_assert(common_type_v<parameter_types>, "Common Type Does Not Exist");
7610
7611 auto v = make_vector(std::forward<Type>(arg), std::forward<Types>(args)...);
7612
7613 return reverse_st<decltype(v)>{ std::move(v) };
7614 }
7615
7616 template<typename ContainerType, typename IndexType>
7617 decltype(auto) get_element(ContainerType container, IndexType index)
7618 {
7619 using container_t = tpf::remove_cv_ref_t<ContainerType>;
7620
7621 if constexpr(tpf::types::is_index_operator_available_v<container_t>)
7622 {
7623 return container[(size_t)index];
7624 }
7625 else
7626 {
7627 if constexpr(std::is_const_v<ContainerType>)
7628 {
7629 auto itr = container.cbegin();
7630 std::advance(itr, index);
7631 return *itr;
7632 }
7633 else
7634 {
7635 auto itr = container.begin();
7636 std::advance(itr, index);
7637 return *itr;
7638 }
7639 }
7640 }
7641
7642 template<size_t StartIndex, size_t EndIndex>
7644 {
7646 template<typename VisitorType, typename PairType>
7647 static std::enable_if_t<is_pair_of_variant_v<remove_cv_ref_t<PairType>>>
7648 visit_variant(VisitorType&& visitors, PairType&& vpr)
7649 {
7650 if constexpr(StartIndex < EndIndex)
7651 {
7652 auto& [key, vt] = vpr;
7653
7654 if(auto ptr = std::get_if<StartIndex>(&vt))
7655 {
7656 std::get<StartIndex>(visitors.m_visitors)(key, *ptr);
7657 return;
7658 }
7659 }
7660
7661 if constexpr(StartIndex + 1 < EndIndex)
7662 {
7664 template visit_variant(std::forward<VisitorType>(visitors),
7665 std::forward<PairType>(vpr));
7666 }
7667 }
7668
7669 template<typename VisitorType, typename VariantType>
7670 static std::enable_if_t<is_variant_v<remove_cv_ref_t<VariantType>>>
7671 visit_variant(VisitorType&& visitors, VariantType&& vpr)
7672 {
7673 if constexpr(StartIndex < EndIndex)
7674 {
7675 if(auto ptr = std::get_if<StartIndex>(&vpr))
7676 {
7677 std::get<StartIndex>(visitors.m_visitors)(*ptr);
7678 return;
7679 }
7680 }
7681
7682 if constexpr(StartIndex + 1 < EndIndex)
7683 {
7685 template visit_variant(std::forward<VisitorType>(visitors),
7686 std::forward<VariantType>(vpr));
7687 }
7688 }
7689
7692 template<typename VisitorType, typename IteratorType, typename PairType>
7693 static std::enable_if_t<is_pair_of_variant_v<remove_cv_ref_t<PairType>>>
7694 visit_variant(VisitorType&& visitors, IteratorType&& itr, PairType&& vpr)
7695 {
7696 if constexpr(StartIndex < EndIndex)
7697 {
7698 auto& [key, vt] = vpr;
7699
7700 if(auto ptr = std::get_if<StartIndex>(&vt))
7701 {
7702 std::get<StartIndex>(visitors.m_visitors)(std::forward<IteratorType>(itr), key, *ptr);
7703 return;
7704 }
7705 }
7706
7707 if constexpr(StartIndex + 1 < EndIndex)
7708 {
7710 template visit_variant(std::forward<VisitorType>(visitors),
7711 std::forward<IteratorType>(itr), std::forward<PairType>(vpr));
7712 }
7713 }
7714
7715 template<typename VisitorType, typename IteratorType, typename VariantType>
7716 static std::enable_if_t<is_variant_v<remove_cv_ref_t<VariantType>>>
7717 visit_variant(VisitorType&& visitors, IteratorType&& itr, VariantType&& vpr)
7718 {
7719 if constexpr(StartIndex < EndIndex)
7720 {
7721 if(auto ptr = std::get_if<StartIndex>(&vpr))
7722 {
7723 std::get<StartIndex>(visitors.m_visitors)(std::forward<IteratorType>(itr), *ptr);
7724 return;
7725 }
7726 }
7727
7728 if constexpr(StartIndex + 1 < EndIndex)
7729 {
7731 template visit_variant(std::forward<VisitorType>(visitors),
7732 std::forward<IteratorType>(itr), std::forward<VariantType>(vpr));
7733 }
7734 }
7735
7736 }; // end of static_loop_struct
7737
7738 template<typename VisitorType, typename PairType>
7739 std::enable_if_t<is_pair_of_variant_v<remove_cv_ref_t<PairType>>>
7740 visit_variant(VisitorType&& visit, PairType&& vpr)
7741 {
7742 using pair_t = remove_cv_ref_t<PairType>;
7743 using second_type = typename pair_t::second_type;
7744
7746 visit_variant(std::forward<VisitorType>(visit), std::forward<PairType>(vpr));
7747 }
7748
7749 template<typename VisitorType, typename VariantType>
7750 std::enable_if_t<is_variant_v<remove_cv_ref_t<VariantType>>>
7751 visit_variant(VisitorType&& visit, VariantType&& vt)
7752 {
7753 using variant_t = remove_cv_ref_t<VariantType>;
7754
7756 visit_variant(std::forward<VisitorType>(visit),
7757 std::forward<VariantType>(vt));
7758 }
7759
7760 template<typename VisitorType, typename IteratorType, typename PairType>
7761 std::enable_if_t<is_pair_of_variant_v<remove_cv_ref_t<PairType>>>
7762 visit_variant(VisitorType&& visit, IteratorType&& itr, PairType&& vpr)
7763 {
7764 using pair_t = remove_cv_ref_t<PairType>;
7765 using second_type = typename pair_t::second_type;
7766
7768 visit_variant(std::forward<VisitorType>(visit),
7769 std::forward<IteratorType>(itr), std::forward<PairType>(vpr));
7770 }
7771
7772 template<typename VisitorType, typename IteratorType, typename VariantType>
7773 std::enable_if_t<is_variant_v<remove_cv_ref_t<VariantType>>>
7774 visit_variant(VisitorType&& visit, IteratorType&& itr, VariantType&& vt)
7775 {
7776 using variant_t = remove_cv_ref_t<VariantType>;
7777
7779 visit_variant(std::forward<VisitorType>(visit),
7780 std::forward<IteratorType>(itr), std::forward<VariantType>(vt));
7781 }
7782
7784 template<typename... CallbackTypes>
7786 {
7787 using visitors_t = std::tuple<CallbackTypes...>;
7788
7790
7791 variant_visitors(CallbackTypes... visitors):
7792 m_visitors{ std::move(visitors)... } { }
7793
7794 template<typename Type>
7795 decltype(auto) handle (Type&& item)
7796 {
7797 return visit_variant(*this, std::forward<Type>(item));
7798 }
7799
7800 template<typename ContainerType>
7801 void for_each(ContainerType&& container)
7802 {
7803 for(decltype(auto) item: std::forward<ContainerType>(container))
7804 {
7805 visit_variant(*this, std::forward<decltype(item)>(item));
7806 }
7807 }
7808
7809 template<typename ContainerType>
7810 void for_each_reverse(ContainerType&& container)
7811 {
7812 for(decltype(auto) item: reverse(std::forward<ContainerType>(container)))
7813 {
7814 visit_variant(*this, std::forward<decltype(item)>(item));
7815 }
7816 }
7817
7819 template<typename ContainerType>
7820 void for_each_iterator(ContainerType&& container)
7821 {
7822 if constexpr (is_const_reference_v<ContainerType>)
7823 {
7824 for(auto itr = container.cbegin(); itr != container.cend(); ++itr)
7825 visit_variant(*this, std::forward<decltype(itr)>(itr),
7826 std::forward<decltype(*itr)>(*itr));
7827 }
7828 else
7829 {
7830 for(auto itr = container.begin(); itr != container.end(); ++itr)
7831 visit_variant(*this, std::forward<decltype(itr)>(itr),
7832 std::forward<decltype(*itr)>(*itr));
7833 }
7834 }
7835
7837 template<typename ContainerType>
7838 void for_each_index(ContainerType&& container)
7839 {
7840 if constexpr (is_const_reference_v<ContainerType>)
7841 {
7842 for(auto itr = container.cbegin(); itr != container.cend(); ++itr)
7843 {
7844 auto index = std::distance(container.cbegin(), itr);
7845 visit_variant(*this, index, std::forward<decltype(*itr)>(*itr));
7846 }
7847 }
7848 else
7849 {
7850 for(auto itr = container.begin(); itr != container.end(); ++itr)
7851 {
7852 auto index = std::distance(container.begin(), itr);
7853 visit_variant(*this, index, std::forward<decltype(*itr)>(*itr));
7854 }
7855 }
7856 }
7857
7858 template<typename ContainerType>
7859 void for_each_reverse_iterator(ContainerType&& container)
7860 {
7861 for_each_iterator(types::reverse(std::forward<ContainerType>(container)));
7862 }
7863
7864 template<typename ContainerType>
7865 void for_each_reverse_index(ContainerType&& container)
7866 {
7867 for_each_index(types::reverse(std::forward<ContainerType>(container)));
7868 }
7869
7871 template<typename VariantType>
7872 std::enable_if_t<is_variant_v<remove_cv_ref_t<VariantType>>>
7873 operator()(VariantType&& vt)
7874 {
7875 visit_variant(*this, std::forward<VariantType>(vt));
7876 }
7877
7878 template<typename PairType>
7879 std::enable_if_t<is_pair_of_variant_v<remove_cv_ref_t<PairType>>>
7880 operator()(PairType&& vt)
7881 {
7882 visit_variant(*this, std::forward<PairType>(vt));
7883 }
7884 };
7885
7886 template<typename... CallbackTypes>
7887 variant_visitors(CallbackTypes...) -> variant_visitors<CallbackTypes...>;
7888
7889 template<typename... CallbackTypes>
7891 make_variant_visitors(CallbackTypes&& ... visitors)
7892 {
7893 return { std::forward<CallbackTypes>(visitors)... };
7894 }
7895
7896 } // end of namespace types
7897
7898 template<typename ContainerType, typename IndexType>
7899 decltype(auto) get_element(ContainerType container, IndexType index)
7900 {
7901 return tpf::types::get_element<ContainerType, IndexType>(container, index);
7902 }
7903
7904 template<template<typename, typename...> class ContainerType, typename Type, typename... Types>
7905 decltype(auto) make_random_access_container(Type&& arg, Types&&... args)
7906 {
7907 return types::make_random_access_container<ContainerType>(std::forward<Type>(arg), std::forward<Types>(args)...);
7908 }
7909
7910 template<typename Type, typename... Types>
7911 decltype(auto) make_vector(Type&& arg, Types&&... args)
7912 {
7913 return types::make_vector(std::forward<Type>(arg), std::forward<Types>(args)...);
7914 }
7915
7916 template<typename Type, typename... Types>
7917 decltype(auto) make_deque(Type&& arg, Types&&... args)
7918 {
7919 return types::make_deque(std::forward<Type>(arg), std::forward<Types>(args)...);
7920 }
7921
7922 template<typename Type, typename... Types>
7923 decltype(auto) make_container(Type&& arg, Types&&... args)
7924 {
7925 return types::make_container(std::forward<Type>(arg), std::forward<Types>(args)...);
7926 }
7927
7928 template< template<typename, typename...> class ContainerType,
7929 typename Type, typename... Types>
7930 decltype(auto) make_container(Type&& arg, Types&&... args)
7931 {
7932 return types::make_container<ContainerType>(std::forward<Type>(arg), std::forward<Types>(args)...);
7933 }
7934
7935 template< template<typename, std::size_t> class ContainerType,
7936 typename Type, typename... Types>
7937 decltype(auto) make_container(Type&& arg, Types&&... args)
7938 {
7939 return types::make_container<ContainerType>(std::forward<Type>(arg), std::forward<Types>(args)...);
7940 }
7941
7942 template<typename Type, typename... Types>
7943 decltype(auto) create_container(Type&& arg, Types&&... args)
7944 {
7945 return types::create_container(std::forward<Type>(arg), std::forward<Types>(args)...);
7946 }
7947
7948 #if !defined(__clang_major__)
7949
7950 template<typename Type, typename... Types>
7951 decltype(auto) make_variants(Type&& arg, Types&&... args)
7952 {
7953 return types::make_variants(std::forward<Type>(arg), std::forward<Types>(args)...);
7954 }
7955
7956 #endif
7957
7958 template<typename ContainerType>
7959 decltype(auto) reverse(ContainerType&& container)
7960 {
7961 return types::reverse(std::forward<ContainerType>(container));
7962 }
7963
7964 template<typename ElementType, size_t ElementCount>
7965 decltype(auto) reverse(ElementType(&array)[ElementCount])
7966 {
7967 return types::reverse(array);
7968 }
7969
7970 template<typename Type, typename... Types>
7971 decltype(auto) reverse(Type&& arg, Types&&... args)
7972 {
7973 return types::reverse(std::forward<Type>(arg), std::forward<Types>(args)...);
7974 }
7975
7976 template<typename IndexType, typename ContainerType, typename iterator_type>
7977 inline auto index_to_iterator(ContainerType&& cntr, IndexType&& index)
7978 {
7979 using offset_t = tpf::remove_cv_ref_t<IndexType>;
7980 using diff_t = typename iterator_type::difference_type;
7981 auto pos = cntr.begin(); std::advance(pos, (diff_t)index);
7982 return pos;
7983 }
7984
7985 template<typename IndexType, typename ContainerType, typename reverse_iterator_type>
7986 inline auto index_to_reverse_iterator(ContainerType&& cntr, IndexType&& index)
7987 {
7988 using offset_t = tpf::remove_cv_ref_t<IndexType>;
7989 using diff_t = typename reverse_iterator_type::difference_type;
7990 auto pos = cntr.begin(); std::advance(pos, (diff_t)index);
7991
7992 return reverse_iterator_type{ pos };
7993 }
7994
7995 template<typename ContainerType, typename iterator_type>
7996 inline auto iterator_to_index(ContainerType&& cntr, iterator_type&& itr)
7997 {
7998 return (size_t)std::distance(cntr.begin(), itr);
7999 }
8000
8001 template<typename ContainerType, typename reverse_iterator_type>
8002 inline auto reverse_iterator_to_index(ContainerType&& cntr, reverse_iterator_type&& rev_itr)
8003 {
8004 auto itr = typename ContainerType::iterator_type{ rev_itr.base() };
8005 return (size_t)std::distance(cntr.begin(), itr);
8006 }
8007
8008 template<direction_t direction,
8009 typename ContainerType,
8010 typename container_t,
8011 typename iterator_type,
8012 typename reverse_iterator_type>
8013 auto make_rotator(ContainerType&& cntr)
8014 {
8015 using container_type = decltype(cntr);
8016
8017 if constexpr(direction == direction_t::left)
8018 {
8019 return [](iterator_type begin, auto&& offset, iterator_type end)
8020 {
8021 using offset_t = tpf::remove_cv_ref_t<decltype(offset)>;
8022
8023 if constexpr(tpf::types::is_integral_v<offset_t>)
8024 {
8025 using diff_t = typename iterator_type::difference_type;
8026 auto offset_pos = begin; std::advance(offset_pos, (diff_t)offset);
8027
8028 return std::rotate(begin, offset_pos, end);
8029 }
8030 else if constexpr(std::is_same_v<reverse_iterator_type, offset_t>)
8031 {
8032 return std::rotate(begin, offset.base()-1, end);
8033 }
8034 else
8035 return std::rotate(begin, offset, end);
8036 };
8037 }
8038 else
8039 {
8040 return [](iterator_type begin, auto&& offset, iterator_type end)
8041 {
8042 using offset_t = tpf::remove_cv_ref_t<decltype(offset)>;
8043
8044 if constexpr(tpf::types::is_integral_v<offset_t>)
8045 {
8046 using diff_t = typename reverse_iterator_type::difference_type;
8047
8048 auto offset_pos = reverse_iterator_type{end};
8049 std::advance(offset_pos, (diff_t)offset);
8050
8051 return std::rotate(reverse_iterator_type{end},
8052 offset_pos, reverse_iterator_type{begin});
8053 }
8054 else if constexpr(std::is_same_v<reverse_iterator_type, offset_t>)
8055 return std::rotate(reverse_iterator_type{end}, offset, reverse_iterator_type{begin});
8056 else
8057 return std::rotate(reverse_iterator_type{end},
8058 reverse_iterator_type{offset}, reverse_iterator_type{begin});
8059 };
8060 }
8061 }
8062
8063 template<direction_t direction,
8064 typename ContainerType,
8065 typename container_t,
8066 typename iterator_type,
8067 typename reverse_iterator_type,
8068 typename execution_policy_type>
8069 auto make_rotator(ContainerType&& cntr, execution_policy_type policy)
8070 {
8071 using container_type = decltype(cntr);
8072
8073 if constexpr(direction == direction_t::left)
8074 {
8075 return [policy](iterator_type begin, auto&& offset, iterator_type end)
8076 {
8077 using offset_t = tpf::remove_cv_ref_t<decltype(offset)>;
8078
8079 if constexpr(tpf::types::is_integral_v<offset_t>)
8080 {
8081 using diff_t = typename iterator_type::difference_type;
8082 auto offset_pos = begin; std::advance(offset_pos, (diff_t)offset);
8083
8084 return std::rotate(policy, begin, offset_pos, end);
8085 }
8086 else if constexpr(std::is_same_v<reverse_iterator_type, offset_t>)
8087 {
8088 return std::rotate(policy, begin, offset.base()-1, end);
8089 }
8090 else
8091 return std::rotate(policy, begin, offset, end);
8092 };
8093 }
8094 else
8095 {
8096 return [policy](iterator_type begin, auto&& offset, iterator_type end)
8097 {
8098 using offset_t = tpf::remove_cv_ref_t<decltype(offset)>;
8099
8100 if constexpr(tpf::types::is_integral_v<offset_t>)
8101 {
8102 using diff_t = typename reverse_iterator_type::difference_type;
8103
8104 auto offset_pos = reverse_iterator_type{end};
8105 std::advance(offset_pos, (diff_t)offset);
8106
8107 return std::rotate(policy, reverse_iterator_type{end},
8108 offset_pos, reverse_iterator_type{begin});
8109 }
8110 else if constexpr(std::is_same_v<reverse_iterator_type, offset_t>)
8111 return std::rotate(policy, reverse_iterator_type{end}, offset, reverse_iterator_type{begin});
8112 else
8113 return std::rotate(policy, reverse_iterator_type{end},
8114 reverse_iterator_type{offset}, reverse_iterator_type{begin});
8115 };
8116 }
8117 }
8118
8119}
8120// end of namespace tpf
8121
8126#define Tpf_IsTemplateV(type_arg) tpf::types::is_template_v<type_arg>
8127
8132#define Tpf_IsTemplateInstanceV(instance_arg) tpf::types::is_template_v<decltype(instance_arg)>
8133
8134#endif // end of file _TPF_TYPES_HPP
reference_wrapper< Type > ref(Type &val) noexcept
std::mutex mutex
Definition: 022-mutex.cpp:12
std::deque< set_t > sets_t
Definition: 061-subsets.cpp:10
typename enable_if< predicate, ReturnType >::type enable_if_t
Definition: 12_sfinae.cpp:23
This class implements all debugging requirements for C++ Library Extension.
Definition: tpf_types.hpp:224
virtual const char * what() const noexcept override
Definition: tpf_types.hpp:246
debug_exception(std::string message, int lineno, std::string file_name)
Definition: tpf_types.hpp:232
std::unordered_map< KeyType, std::tuple< ElementTypes... > > base_type
Definition: tpf_types.hpp:6913
std::unordered_multimap< KeyType, std::tuple< ElementTypes... > > base_type
Definition: tpf_types.hpp:6928
typename base_type::value_type value_type
Definition: tpf_types.hpp:6871
ContainerType< std::tuple< ElementTypes... > > base_type
Definition: tpf_types.hpp:6868
std::unordered_map< KeyType, std::variant< ElementTypes... > > base_type
Definition: tpf_types.hpp:6487
std::unordered_multimap< KeyType, std::variant< ElementTypes... > > base_type
Definition: tpf_types.hpp:6499
typename base_type::value_type value_type
Definition: tpf_types.hpp:6419
ContainerType< std::variant< ElementTypes... > > base_type
Definition: tpf_types.hpp:6417
decltype(auto) crend() const noexcept
Definition: tpf_types.hpp:6428
decltype(auto) crbegin() const noexcept
Definition: tpf_types.hpp:6423
std::reverse_iterator< ElementType * > reverse_iterator
Definition: tpf_types.hpp:7557
decltype(auto) begin() noexcept
Definition: tpf_types.hpp:7512
decltype(auto) cbegin() const noexcept
Definition: tpf_types.hpp:7525
reverse_st(ContainerType container)
Definition: tpf_types.hpp:7506
auto empty() const noexcept
Definition: tpf_types.hpp:7509
auto size() const noexcept
Definition: tpf_types.hpp:7510
decltype(auto) cend() const noexcept
Definition: tpf_types.hpp:7530
decltype(auto) end() noexcept
Definition: tpf_types.hpp:7519
static constexpr Type tag
Definition: tpf_types.hpp:306
const Type & get() const noexcept
Definition: tpf_types.hpp:325
tag_type(const tag_type &) noexcept=default
tag_type(Type v=Type{}) noexcept
Definition: tpf_types.hpp:313
tag_type(tag_type &&) noexcept=default
tag_type(ArgType arg, ArgTypes... args) noexcept
Definition: tpf_types.hpp:316
tag_type & operator=(const tag_type &) noexcept=default
Type & get() noexcept
Definition: tpf_types.hpp:326
std::common_type_t< S, T > common_t
Definition: cpg_bitwise.hpp:79
constexpr auto make_tuple(ArgTypes &&... args) noexcept
Definition: cpg_types.hpp:2704
constexpr decltype(auto) apply(F &&f, T(&&c_array)[N])
constexpr decltype(auto) get(T(&c_array)[N]) noexcept
Implements set operations.
Definition: tpf_set.hpp:52
range< size_t > range_t
constexpr auto is_signed_integral_v
Definition: tpf_types.hpp:3905
typename st_is_arg_list< Type >::type arg_to_type_t
Definition: tpf_types.hpp:6049
constexpr auto is_same_template_v
Definition: tpf_types.hpp:3375
constexpr bool is_tag_type_v
Definition: tpf_types.hpp:347
no_type_t safe_apply(...)
container_of_tuples_t< std::vector, ElementTypes... > vector_of_tuples_t
Definition: tpf_types.hpp:6953
constexpr bool is_division_valid_v
Definition: tpf_types.hpp:2074
typename push_back_type_st< ArgType, Types... >::type push_back_type_t
Definition: tpf_types.hpp:4325
constexpr auto sequence_span_v
Definition: tpf_types.hpp:2483
typename union_type_st< LeftList, RightList >::type union_type_t
Definition: tpf_types.hpp:4734
typename st_reverse_sequence< SequenceType >::type reverse_sequence_t
Definition: tpf_types.hpp:2451
typename replace_type_st< NewType, OldType, TypeList >::type replace_type_t
Definition: tpf_types.hpp:4933
constexpr auto is_same_v
Definition: tpf_types.hpp:3793
constexpr bool is_reserve_available_v
Definition: tpf_types.hpp:3630
constexpr bool is_pop_back_available_v
Definition: tpf_types.hpp:3738
typename container_of_variants_st< ContainerType, KeyType, unique_types_t< ElementTypes... > >::type container_map_of_variants_t
Definition: tpf_types.hpp:6555
no_type_t subtraction_vaild_fn(...)
decltype(iterator_value_type_fn(std::declval< T >())) iterator_value_type_t
Definition: tpf_types.hpp:3126
container_of_tuples_t< std::unordered_map, KeyType, ElementTypes... > unordered_map_of_tuples_t
Definition: tpf_types.hpp:6971
container_of_variants_t< std::unordered_set, ElementTypes... > unordered_set_of_variants_t
Definition: tpf_types.hpp:6573
constexpr auto is_index_operator_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.operator[]((size_t) 1))
constexpr bool is_emplace_back_available_v
Definition: tpf_types.hpp:3703
std::enable_if_t<!is_integer_v< Type >, ReturnType > enable_if_not_integer_t
Definition: tpf_types.hpp:3955
container_of_tuples_t< std::multimap, KeyType, ElementTypes... > multimap_of_tuples_t
Definition: tpf_types.hpp:6968
auto for_tuple(FuncType &&f, typed_sequence_t< Ints... >)
Definition: tpf_types.hpp:3046
typename make_unsigned_integral_st< Type, is_integral_v< Type > >::type make_unsigned_integral_t
Definition: tpf_types.hpp:4031
constexpr auto is_shrink_to_fit_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.shrink_to_fit())
constexpr auto are_real_numbers_v
Definition: tpf_types.hpp:3932
constexpr auto is_signed_integer_v
Definition: tpf_types.hpp:3896
constexpr auto is_emplace_front_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.emplace_front(std::declval< Type >()))
constexpr auto is_any_v
Definition: tpf_types.hpp:1830
constexpr auto is_pair_of_variant_v
Definition: tpf_types.hpp:1737
constexpr auto is_back_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.back())
no_type_t fn_apply(...)
typename select_first_type_st< Types... >::type select_first_type_t
Definition: tpf_types.hpp:4164
auto for_array(FuncType &&f, typed_sequence_t< Ints... >)
Definition: tpf_types.hpp:5710
std::enable_if_t< is_signed_integral_v< Type >, ReturnType > enable_if_signed_integral_t
Definition: tpf_types.hpp:3943
constexpr auto compute_span()
Definition: tpf_types.hpp:2343
constexpr auto is_insert_iterator_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.insert(arg.cend(), std::declval< Type >()))
typename append_type_st< ArgType, RightList >::type append_type_t
Definition: tpf_types.hpp:4678
constexpr bool is_integer_sequence_v
Definition: tpf_types.hpp:992
typename st_has_tuple_common_type< TupleType >::type tuple_common_element_t
Definition: tpf_types.hpp:5689
constexpr bool is_rbegin_available_v
Definition: tpf_types.hpp:3557
container_of_tuples_t< std::unordered_multimap, KeyType, ElementTypes... > unordered_multimap_of_tuples_t
Definition: tpf_types.hpp:6974
constexpr auto sequence_nth_element_v
Definition: tpf_types.hpp:2405
typename st_tuple_to_type_list< TupleType >::type tuple_to_type_list_t
Definition: tpf_types.hpp:1150
constexpr auto is_rbegin_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.rbegin())
constexpr bool is_empty_available_v
Definition: tpf_types.hpp:3475
constexpr auto is_end_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.end())
typename return_type_st< Type >::type return_type_t
Definition: tpf_types.hpp:2118
constexpr bool is_subtraction_valid_v
Definition: tpf_types.hpp:2058
std::enable_if_t< is_iterator_type_v< Type >, ReturnType > enable_if_iterator_type_t
Definition: tpf_types.hpp:3131
container_map_of_variants_t< std::unordered_multimap, KeyType, ElementTypes... > unordered_multimap_of_variants_t
Definition: tpf_types.hpp:6594
constexpr auto is_emplace_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.emplace(arg.cbegin(), std::declval< Type >()))
constexpr auto is_same_template_type_v
Definition: tpf_types.hpp:3323
constexpr bool is_index_operator_available_v
Definition: tpf_types.hpp:3592
constexpr auto is_reference_wrapper_v
Definition: tpf_types.hpp:4276
constexpr bool is_template_type_v
Definition: tpf_types.hpp:1113
constexpr auto are_unsigned_integrals_v
Definition: tpf_types.hpp:3926
container_of_variants_t< std::unordered_multiset, ElementTypes... > unordered_multiset_of_variants_t
Definition: tpf_types.hpp:6576
typename st_type_list_to_tuple< TypeList >::type type_list_to_tuple_t
Definition: tpf_types.hpp:1162
constexpr bool is_arithmetic_valid_v
Definition: tpf_types.hpp:2078
constexpr bool is_in_list_v
Definition: tpf_types.hpp:3841
constexpr bool is_addition_valid_v
Definition: tpf_types.hpp:2050
auto set_tuple_to_container(TupleType &&tuple, typed_sequence_t< Indices... >)
Definition: tpf_types.hpp:5793
typename first_n_types_st< FirstN, type_list_t<>, RightTypes... >::type first_n_types_t
Definition: tpf_types.hpp:4454
constexpr auto template_parameter_count
Definition: tpf_types.hpp:3274
constexpr bool is_begin_available_v
Definition: tpf_types.hpp:3535
typename push_front_type_st< ArgType, Types... >::type push_front_type_t
Definition: tpf_types.hpp:4310
typename nth_type_to_template_class_st< TypeIndex, TemplateClass, Types... >::type nth_type_to_template_class_t
Definition: tpf_types.hpp:6792
constexpr auto is_resize_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.resize(std::declval< size_t >()))
container_map_of_variants_t< std::unordered_map, KeyType, ElementTypes... > unordered_map_of_variants_t
Definition: tpf_types.hpp:6591
constexpr bool is_rend_available_v
Definition: tpf_types.hpp:3568
typename container_of_variants_st< ContainerType, unique_types_t< ElementTypes... > >::type container_of_variants_t
Definition: tpf_types.hpp:6550
constexpr auto is_push_front_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.push_front(std::declval< Type >()))
auto set_array_to_tuple(const std::array< T, Size > &array, typed_sequence_t< Indices... >)
Definition: tpf_types.hpp:5816
container_of_tuples_t< std::deque, ElementTypes... > deque_of_tuples_t
Definition: tpf_types.hpp:6956
typename last_n_types_st< LastN, LeftTypes... >::type last_n_types_t
Definition: tpf_types.hpp:4523
std::enable_if_t< is_type_in_list_v< TestType, TypeList >, ReturnType > enable_if_in_list_t
Definition: tpf_types.hpp:4560
constexpr auto common_type_v
Definition: tpf_types.hpp:4122
constexpr bool is_container_type_v
Definition: tpf_types.hpp:3744
constexpr auto is_basic_string_v
Definition: tpf_types.hpp:1851
std::enable_if_t< is_integral_v< Type >, ReturnType > enable_if_integral_t
Definition: tpf_types.hpp:3939
constexpr auto is_tuple_empty_v
Definition: tpf_types.hpp:1815
typename make_signed_st< Type, is_integer_v< Type > >::type make_signed_t
Definition: tpf_types.hpp:3986
container_map_of_variants_t< std::pair, KeyType, ElementTypes... > pair_of_variants_t
Definition: tpf_types.hpp:6582
constexpr auto sequence_first_element_v
Definition: tpf_types.hpp:2369
constexpr auto is_unique_ptr_v
Definition: tpf_types.hpp:1705
typename st_sequence_element_type< T >::type sequence_element_t
Definition: tpf_types.hpp:2466
container_map_of_variants_t< std::multimap, KeyType, ElementTypes... > multimap_of_variants_t
Definition: tpf_types.hpp:6588
container_of_tuples_t< std::map, KeyType, ElementTypes... > map_of_tuples_t
Definition: tpf_types.hpp:6965
void drive_workhorse(WorkhorseType &&workhorse, typed_sequence_t< Indices... >)
Definition: tpf_types.hpp:2813
constexpr bool is_insert_available_v
Definition: tpf_types.hpp:3642
typename pop_back_type_wrapper_st< Types... >::type pop_back_type_t
Definition: tpf_types.hpp:4389
typename make_unsigned_st< Type, is_integer_v< Type > >::type make_unsigned_t
Definition: tpf_types.hpp:4001
std::remove_reference_t< decltype(is_operable_fn(std::declval< Type1 >(), std::declval< Type2 >()))> is_operable_t
Definition: tpf_types.hpp:3462
typename to_tuple_st< Types... >::type to_tuple_t
Definition: tpf_types.hpp:4642
constexpr bool is_capacity_available_v
Definition: tpf_types.hpp:3485
container_of_variants_t< std::set, ElementTypes... > set_of_variants_t
Definition: tpf_types.hpp:6567
std::enable_if_t< is_iterator_type_v< T >, iterator_value_type_t< T > > enable_if_iterator_value_type_t
Definition: tpf_types.hpp:3136
std::enable_if_t< std::is_invocable_v< remove_cvref_t< WorkhorseType >, indexer_t< 0 > > > run_workhorse(WorkhorseType &&workhorse, typed_sequence_t< Indices... >)
Definition: tpf_types.hpp:2988
constexpr auto is_operable_fn(Type1 &&arg1, Type2 &&arg2) noexcept(noexcept(std::declval< remove_cv_ref_t< Type1 > >()) &&noexcept(std::declval< remove_cv_ref_t< Type2 > >())) -> decltype(true ? arg1 :arg2)
last_type_t< template_parameter_type_list_t< Type > > last_parameter_type_t
Definition: tpf_types.hpp:4292
auto tuple_addition_operator(const std::tuple< ArgTypes1... > &tuple_a, const std::tuple< ArgTypes2... > &tuple_b)
Definition: tpf_types.hpp:5482
constexpr auto is_emplace_back_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.emplace_back(std::declval< Type >()))
typename st_recursive_type_list< T >::type to_recursive_type_list_t
Definition: tpf_types.hpp:1022
constexpr auto is_integer_v
Definition: tpf_types.hpp:3890
constexpr bool is_emplace_front_available_v
Definition: tpf_types.hpp:3691
typename remove_type_wrapper_st< ArgType, Types... >::type remove_type_t
Definition: tpf_types.hpp:4842
select_nth_type_t< SelectIndex, Types... > nth_type_t
Definition: tpf_types.hpp:4283
void process_arguments(ArgTypes &&...)
Definition: tpf_types.hpp:2807
no_type_t array_apply(...)
constexpr auto are_unsigned_integers_v
Definition: tpf_types.hpp:3917
auto set_tuple_to_array(TupleType &&tuple, typed_sequence_t< Indices... >)
Definition: tpf_types.hpp:5777
constexpr auto are_numerical_numbers_v
Definition: tpf_types.hpp:3935
constexpr auto is_map_or_unordered_map_v
Definition: tpf_types.hpp:1761
constexpr auto is_integral_v
Definition: tpf_types.hpp:3899
std::enable_if_t< is_container_type_v< remove_cv_ref_t< Type > >, ReturnType > enable_if_container_type_t
Definition: tpf_types.hpp:3749
constexpr auto is_pop_back_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.pop_back())
constexpr bool is_resize_available_v
Definition: tpf_types.hpp:3679
typename st_unique_ptr_wrapper_deleter< deleter, ArgTypes... >::type make_unique_ptr_deleter_wrapper_t
Definition: tpf_types.hpp:5209
constexpr bool is_void_return_type_v
Definition: tpf_types.hpp:5417
typename is_map_or_unordered_map_st< remove_cv_ref_t< Type > >::type map_or_unordered_map_pair_t
Definition: tpf_types.hpp:1764
constexpr auto sequence_last_element_v
Definition: tpf_types.hpp:2387
select_first_type_t< Types... > first_type_t
Definition: tpf_types.hpp:4167
constexpr bool is_push_back_available_v
Definition: tpf_types.hpp:3604
typename types_to_template_class_wrapper_st< Type, Types... >::type types_to_template_class_t
Definition: tpf_types.hpp:6720
constexpr auto is_variant_v
Definition: tpf_types.hpp:1690
auto tuple_addition(const std::tuple< ArgTypes1... > &tuple_a, const std::tuple< ArgTypes2... > &tuple_b, types::typed_sequence_t< Indices... >)
Definition: tpf_types.hpp:5460
typename st_common_type_solver< Types... >::type common_type_t
Definition: tpf_types.hpp:4119
constexpr bool is_callable_v
Definition: tpf_types.hpp:5414
no_type_t addition_vaild_fn(...)
constexpr auto is_operable_v
Definition: tpf_types.hpp:3465
select_first_type_t< Types... > front_type_t
Definition: tpf_types.hpp:4170
constexpr auto type_count_v
Definition: tpf_types.hpp:3099
typename first_n_types_to_template_class_st< FirstN, TemplateClass, Types... >::type first_n_types_to_template_class_t
Definition: tpf_types.hpp:6858
constexpr auto is_template_template_v
Definition: tpf_types.hpp:4289
constexpr bool is_char_v
Definition: tpf_types.hpp:1872
std::enable_if_t< is_numerical_number_v< Type >, ReturnType > enable_if_numerical_number_t
Definition: tpf_types.hpp:3971
constexpr bool is_end_available_v
Definition: tpf_types.hpp:3546
typename unique_types_st< type_list_t<>, Types... >::type unique_types_t
Definition: tpf_types.hpp:4598
container_of_variants_t< std::list, ElementTypes... > list_of_variants_t
Definition: tpf_types.hpp:6564
container_of_tuples_t< std::set, ElementTypes... > set_of_tuples_t
Definition: tpf_types.hpp:6962
typename pop_front_wrapper_st< Types... >::type pop_front_type_t
Definition: tpf_types.hpp:4355
constexpr auto are_signed_integrals_v
Definition: tpf_types.hpp:3929
select_last_type_t< Types... > back_type_t
Definition: tpf_types.hpp:4220
no_type_t function_return_type_fn(...)
constexpr auto are_integers_v
Definition: tpf_types.hpp:3914
constexpr bool has_tuple_common_type_v
Definition: tpf_types.hpp:5686
constexpr auto is_type_list_equivalent_v
Definition: tpf_types.hpp:4969
std::enable_if_t< is_unsigned_integral_v< Type >, ReturnType > enable_if_unsigned_integral_t
Definition: tpf_types.hpp:3947
constexpr auto is_tuple_v
Definition: tpf_types.hpp:1812
constexpr auto are_signed_integers_v
Definition: tpf_types.hpp:3920
typename intersection_type_st< LeftList, RightList >::type intersection_type_t
Definition: tpf_types.hpp:4783
std::enable_if_t< is_unsigned_integer_v< Type >, ReturnType > enable_if_unsigned_integer_t
Definition: tpf_types.hpp:3963
constexpr bool is_insert_iterator_available_v
Definition: tpf_types.hpp:3667
constexpr auto fn_create_sequence_in_order(std::integer_sequence< T, Indices... >, st_workhorse_range< T, Begin, End, Increment >)
Definition: tpf_types.hpp:2554
typename is_template_st< Type >::type template_parameter_type_list_t
Definition: tpf_types.hpp:3277
container_of_tuples_t< std::list, ElementTypes... > list_of_tuples_t
Definition: tpf_types.hpp:6959
constexpr auto is_reserve_valid_fn(ContainerType< Type, Types... > &&arg) -> decltype(arg.reserve((size_t) 0))
std::enable_if_t< is_real_number_v< Type >, ReturnType > enable_if_real_number_t
Definition: tpf_types.hpp:3967
constexpr auto is_unsigned_integral_v
Definition: tpf_types.hpp:3902
auto evaluate_lambdas_tuple(typed_sequence_t< Indices... >, TupleType &&tuple, ArgTuple &&arguments)
Definition: tpf_types.hpp:5960
typename make_signed_integral_st< Type, is_integral_v< Type > >::type make_signed_integral_t
Definition: tpf_types.hpp:4016
first_n_types_t< FirstN, RightTypes... > select_first_n_types_t
Definition: tpf_types.hpp:4457
typename to_variant_st< Type, Types... >::type to_variant_t
Definition: tpf_types.hpp:4621
select_last_type_t< Types... > last_type_t
Definition: tpf_types.hpp:4217
constexpr bool is_type_list_v
Definition: tpf_types.hpp:1007
no_type_t division_vaild_fn(...)
container_map_of_variants_t< std::map, KeyType, ElementTypes... > map_of_variants_t
Definition: tpf_types.hpp:6585
constexpr auto is_capacity_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.capacity())
constexpr auto is_pop_front_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.pop_front())
typename type_list_to_template_class_wrapper_st< ClassTemplate, Types... >::type type_list_to_template_class_t
Definition: tpf_types.hpp:6762
container_of_variants_t< std::vector, ElementTypes... > vector_of_variants_t
Definition: tpf_types.hpp:6558
constexpr bool is_iterator_excluding_pointer_v
Definition: tpf_types.hpp:3120
constexpr auto is_size_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.size())
constexpr bool is_push_front_available_v
Definition: tpf_types.hpp:3580
typename difference_type_st< LeftList, RightList >::type difference_type_t
Definition: tpf_types.hpp:4887
constexpr auto is_unsigned_integer_v
Definition: tpf_types.hpp:3893
constexpr auto is_erase_valid_fn(ContainerType< Type, Types... > &&arg) -> decltype(arg.erase(arg.cbegin()))
constexpr bool is_emplace_available_v
Definition: tpf_types.hpp:3716
last_n_types_t< LastN, LeftTypes... > select_last_n_types_t
Definition: tpf_types.hpp:4526
typename first_n_types_list_to_template_class_st< FirstN, TemplateClass, Types... >::type first_n_types_list_to_template_class_t
Definition: tpf_types.hpp:6822
constexpr auto sequence_element_count_v
Definition: tpf_types.hpp:2420
constexpr auto is_push_back_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.push_back(std::declval< Type >()))
first_type_t< template_parameter_type_list_t< Type > > first_parameter_type_t
Definition: tpf_types.hpp:4286
constexpr auto is_template_v
Definition: tpf_types.hpp:3271
constexpr auto is_empty_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.empty())
constexpr auto is_pair_v
Definition: tpf_types.hpp:1720
std::enable_if_t< are_all_in_list_v< TypeList, TestTypeList >, ReturnType > enable_if_all_in_list_t
Definition: tpf_types.hpp:4563
constexpr auto is_set_or_unordered_set_v
Definition: tpf_types.hpp:1788
constexpr auto is_numerical_number_v
Definition: tpf_types.hpp:3911
typename std::conditional< is_iterator_type_v< T >, iterator_value_type_t< T >, T >::type conditional_iterator_value_type_t
Definition: tpf_types.hpp:3142
typename select_nth_type_st< SelectIndex, Types... >::type select_nth_type_t
Definition: tpf_types.hpp:4280
remove_cvref_t< decltype(function_return_type_fn(std::declval< FuncType >(), std::declval< ArgTypes >()...))> function_return_type_t
Definition: tpf_types.hpp:5411
constexpr auto tuple_size_v
Definition: tpf_types.hpp:1913
constexpr bool is_front_available_v
Definition: tpf_types.hpp:3515
auto for_vector(FuncType &&f, typed_sequence_t< Ints... >)
Definition: tpf_types.hpp:5748
typename prepend_type_st< ArgType, RightList >::type prepend_type_t
Definition: tpf_types.hpp:4660
nth_type_t< SelectIndex, template_parameter_type_list_t< Type > > nth_parameter_type_t
Definition: tpf_types.hpp:4295
constexpr auto is_string_v
Definition: tpf_types.hpp:3432
constexpr auto are_integrals_v
Definition: tpf_types.hpp:3923
constexpr bool is_size_available_v
Definition: tpf_types.hpp:3505
typename st_make_non_class_wrapper< Type, Tag, std::is_class_v< Type > >::type non_class_wrapper_t
Definition: tpf_types.hpp:401
constexpr auto is_insert_valid_fn(ContainerType< Type, Types... > &&arg) noexcept(noexcept(std::declval< ContainerType< Type, Types... > >())) -> decltype(arg.insert(std::declval< Type >()))
constexpr auto is_front_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.front())
typename container_of_tuples_st< ContainerType, ElementTypes... >::type container_of_tuples_t
Definition: tpf_types.hpp:6950
constexpr auto fn_create_sequence_reverse_order(std::integer_sequence< T, Indices... >, st_workhorse_range< T, Begin, End, Increment >)
Definition: tpf_types.hpp:2588
std::enable_if_t< is_signed_integer_v< Type >, ReturnType > enable_if_signed_integer_t
Definition: tpf_types.hpp:3959
constexpr std::enable_if_t< true, typename std::iterator_traits< T >::value_type > iterator_value_type_fn(T &&)
constexpr auto is_real_number_v
Definition: tpf_types.hpp:3908
constexpr bool is_multiplication_valid_v
Definition: tpf_types.hpp:2066
typename st_variant_to_type_list< VarType >::type variant_to_type_list_t
Definition: tpf_types.hpp:1174
constexpr bool is_pop_front_available_v
Definition: tpf_types.hpp:3728
typename st_unique_ptr_wrapper< ArgTypes... >::type make_unique_ptr_wrapper_t
Definition: tpf_types.hpp:5194
constexpr auto is_rend_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.rend())
constexpr auto is_type_in_list_v
Definition: tpf_types.hpp:4557
constexpr auto is_begin_available_fn(Type &&arg) noexcept(noexcept(std::declval< remove_cv_ref_t< Type > >())) -> decltype(arg.begin())
container_of_variants_t< std::deque, ElementTypes... > deque_of_variants_t
Definition: tpf_types.hpp:6561
no_type_t multiplication_vaild_fn(...)
constexpr bool is_iterator_type_v
Definition: tpf_types.hpp:3116
constexpr bool is_back_available_v
Definition: tpf_types.hpp:3525
typename select_last_type_st< Types... >::type select_last_type_t
Definition: tpf_types.hpp:4214
constexpr bool is_shrink_to_fit_available_v
Definition: tpf_types.hpp:3495
std::array< tuple_common_element_t< TupleType >, tuple_size_v< TupleType > > tuple_to_std_array_t
Definition: tpf_types.hpp:5693
constexpr auto are_all_in_list_v
Definition: tpf_types.hpp:3887
std::enable_if_t< is_integer_v< Type >, ReturnType > enable_if_integer_t
Definition: tpf_types.hpp:3951
constexpr bool is_erase_available_v
Definition: tpf_types.hpp:3617
container_of_variants_t< std::multiset, ElementTypes... > multiset_of_variants_t
Definition: tpf_types.hpp:6570
Type to string name conversions are defined.
Definition: 31-visit.cpp:7
hidden::append_type_t< ArgType, RightList > append_type_t
Definition: tpf_types.hpp:5648
constexpr bool is_valid_type_v
Definition: tpf_types.hpp:2127
constexpr bool operator!=(no_type_t, no_type_t) noexcept
Definition: tpf_types.hpp:2135
constexpr bool is_arithmetic_valid_v
Definition: tpf_types.hpp:2100
auto seq_to_array(std::integer_sequence< T, Id, Ids... >)
Definition: tpf_types.hpp:2298
hidden::unordered_set_of_variants_t< ElementTypes... > unordered_set_of_variants_t
Definition: tpf_types.hpp:6636
type_list_t< unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long > unsigned_integral_list_t
Type list of unsigned integral type INCLUDING character type, but EXCLUDING boolean type.
Definition: tpf_types.hpp:3205
hidden::enable_if_signed_integer_t< Type, ReturnType > enable_if_signed_integer_t
Definition: tpf_types.hpp:5095
hidden::push_back_type_t< ArgType, Types... > push_back_type_t
Definition: tpf_types.hpp:5603
auto erase(ContainerType< EleType, Types... > &container, size_t index)
Definition: tpf_types.hpp:7026
typename hidden::st_create_workhorse_range< SequenceInOrder, RangeValues... >::type make_sequence_t
Definition: tpf_types.hpp:2668
constexpr auto common_type_v
Definition: tpf_types.hpp:5137
constexpr no_type_t operator/(no_type_t, no_type_t) noexcept
Definition: tpf_types.hpp:2132
constexpr bool InOrderSequence
Definition: tpf_types.hpp:2336
variant_visitors(CallbackTypes...) -> variant_visitors< CallbackTypes... >
hidden::first_n_types_list_to_template_class_t< FirstN, TemplateClass, Types... > first_n_types_list_to_template_class_t
Definition: tpf_types.hpp:6995
std::vector< std::common_type_t< apply_return_t< FuncType, TupleTypes >... > > apply_return_vector_t
Definition: tpf_types.hpp:5285
hidden::map_or_unordered_map_pair_t< Type > map_or_unordered_map_pair_t
Definition: tpf_types.hpp:1927
constexpr bool is_numbers_type_v
Definition: tpf_types.hpp:368
constexpr auto sequence_nth_element_v
Definition: tpf_types.hpp:2528
constexpr bool is_integer_sequence_v
Definition: tpf_types.hpp:1031
make_unsigned_t< common_type_t< Types... > > common_unsigned_t
Definition: tpf_types.hpp:5128
std::array< std::common_type_t< apply_return_t< FuncType, TupleTypes >... >, sizeof...(TupleTypes)> apply_return_array_t
Definition: tpf_types.hpp:5281
constexpr bool is_reserve_available_v
Definition: tpf_types.hpp:5368
constexpr auto is_same_template_type_v
Definition: tpf_types.hpp:3396
constexpr auto is_integral_v
Definition: tpf_types.hpp:5038
decltype(auto) tuple_reader(TupleType &&tuple)
Definition: tpf_types.hpp:2755
constexpr auto is_template_v
Test whether the type parameter is a template type.
Definition: tpf_types.hpp:3387
constexpr bool is_front_available_v
Definition: tpf_types.hpp:5389
constexpr bool is_pop_back_available_v
Definition: tpf_types.hpp:5398
std::enable_if_t< is_same_v< Type, Types... > > void_if_same_t
Definition: tpf_types.hpp:5007
constexpr bool is_char_v
Definition: tpf_types.hpp:1878
hidden::select_first_type_t< Types... > select_first_type_t
Definition: tpf_types.hpp:5567
hidden::to_variant_t< TupleType > tuple_to_variant_t
Definition: tpf_types.hpp:5633
std::enable_if_t< all_apply_v< FuncType, TupleTypes... >, ReturnType > enable_if_all_apply_t
Definition: tpf_types.hpp:5274
hidden::last_n_types_t< LastN, Types... > last_n_types_t
Definition: tpf_types.hpp:5618
std::enable_if_t< is_same_v< Types... > > void_if_all_the_same_t
Definition: tpf_types.hpp:5010
hidden::enable_if_iterator_type_t< remove_cv_ref_t< Type >, ReturnType > enable_if_iterator_type_t
Definition: tpf_types.hpp:3155
decltype(auto) array_indexer(ArrayType &&array)
Definition: tpf_types.hpp:2684
std::enable_if_t< common_type_v< remove_cvref_t< ArgTypes >... > > void_if_common_exisits_t
Definition: tpf_types.hpp:5145
std::enable_if_t< std::is_invocable_v< WorkhorseType, indexer_t< 0 > > > drive_workhorse(WorkhorseType &&workhorse)
Definition: tpf_types.hpp:2946
constexpr bool is_insert_available_v
Definition: tpf_types.hpp:5374
void reverse_order_in_place(ContainerType< Type, Types... > &container)
Definition: tpf_types.hpp:7173
constexpr bool is_rend_available_v
Definition: tpf_types.hpp:5359
std::enable_if_t< is_same_v< Type, Types... >, ReturnType > enable_if_same_t
Definition: tpf_types.hpp:4994
constexpr no_type_t operator-(no_type_t, no_type_t) noexcept
Definition: tpf_types.hpp:2130
constexpr bool is_std_array_v
Definition: tpf_types.hpp:2208
constexpr bool is_type_list_v
Definition: tpf_types.hpp:1034
ContainerType< Type, Types... > reverse_order(const ContainerType< Type, Types... > &container)
Definition: tpf_types.hpp:7167
hidden::multiset_of_variants_t< ElementTypes... > multiset_of_variants_t
Definition: tpf_types.hpp:6633
hidden::nth_type_to_template_class_t< SelectTypeIndex, TemplateClass, Types... > nth_type_to_template_class_t
Definition: tpf_types.hpp:6987
hidden::make_signed_integral_t< Type > make_signed_integral_t
Definition: tpf_types.hpp:5116
hidden::first_type_t< Types... > first_type_t
Definition: tpf_types.hpp:5570
typename hidden::st_arg_to_type_list< Types... >::type arg_to_type_list_t
Definition: tpf_types.hpp:6152
hidden::replace_type_t< NewType, OldType, TypeList > replace_type_t
Definition: tpf_types.hpp:5663
constexpr auto is_signed_integer_v
Definition: tpf_types.hpp:5032
types::vector_if_all_apply_t< FuncType, ArgTypes... > apply_vector(FuncType &&f, ArgTypes &&... args)
Definition: tpf_types.hpp:5315
constexpr bool is_erase_available_v
Definition: tpf_types.hpp:5362
constexpr auto is_reference_wrapper_v
Definition: tpf_types.hpp:4975
constexpr auto is_map_or_unordered_map_v
Definition: tpf_types.hpp:1924
typename hidden::st_tuple_common_type< remove_cvref_t< T >, remove_cvref_t< S > >::type tuple_common_type_t
Definition: tpf_types.hpp:5554
std::basic_ostream< CharType > & operator>>(std::basic_ostream< CharType > &os, const no_type_t &)
Definition: tpf_types.hpp:2038
hidden::function_return_type_t< FuncType, ArgTypes... > function_return_type_t
Definition: tpf_types.hpp:5426
hidden::last_type_t< Types... > last_type_t
Definition: tpf_types.hpp:5579
hidden::unordered_multimap_of_variants_t< KeyType, ElementTypes... > unordered_multimap_of_variants_t
Definition: tpf_types.hpp:6654
hidden::enable_if_in_list_t< TestType, TypeList, ReturnType > enable_if_in_list_t
Definition: tpf_types.hpp:6406
std::enable_if_t< tuple_common_type_v< T, S >, tuple_common_type_t< T, S > > tuple_operation_valid_t
Definition: tpf_types.hpp:5560
types::array_if_all_apply_t< FuncType, ArgTypes... > apply_array(FuncType &&f, ArgTypes &&... args)
Definition: tpf_types.hpp:5323
range(Type, Type) -> range< Type >
hidden::sequence_element_t< remove_cvref_t< SequenceType > > sequence_element_t
Definition: tpf_types.hpp:2534
hidden::non_class_wrapper_t< Type, Tag > non_class_wrapper_t
Definition: tpf_types.hpp:407
constexpr no_type_t operator+(no_type_t, no_type_t) noexcept
Definition: tpf_types.hpp:2129
constexpr bool is_no_type_v
Definition: tpf_types.hpp:2027
hidden::enable_if_not_integer_t< Type, ReturnType > enable_if_not_integer_t
Definition: tpf_types.hpp:5092
auto reverse_tuple(std::tuple< Types... > const &tuple)
Definition: tpf_types.hpp:3066
make_signed_t< common_type_t< Types... > > common_signed_t
Definition: tpf_types.hpp:5134
auto reverse_array(std::array< Type, N > const &array)
Definition: tpf_types.hpp:5736
hidden::enable_if_container_type_t< Type, ReturnType > enable_if_container_type_t
Definition: tpf_types.hpp:5564
hidden::tuple_to_type_list_t< remove_cvref_t< TupleType > > tuple_to_type_list_t
Definition: tpf_types.hpp:1180
hidden::prepend_type_t< ArgType, RightList > prepend_type_t
Definition: tpf_types.hpp:5645
hidden::vector_of_tuples_t< ElementTypes... > vector_of_tuples_t
Definition: tpf_types.hpp:7001
decltype(hidden::fn_apply(std::declval< FuncType >(), std::declval< TupleType >())) apply_return_t
Definition: tpf_types.hpp:5257
decltype(auto) get_value(Type &&arg)
Definition: tpf_types.hpp:371
constexpr bool is_capacity_available_v
Definition: tpf_types.hpp:5335
auto convert_to_array(const std::tuple< Type, Types... > &tuple)
Definition: tpf_types.hpp:5835
constexpr bool is_tag_type_v
Definition: tpf_types.hpp:365
auto make_random_access_container(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7249
typename hidden::sequence_info_t< StackOrder, remove_cvref_t< SequenceType > > sequence_info_t
Definition: tpf_types.hpp:2540
Container< types::to_variant_t< remove_cvref_t< TupleType > > > tuple_to_container_of_variants_t
Definition: tpf_types.hpp:5636
hidden::vector_of_variants_t< ElementTypes... > vector_of_variants_t
Definition: tpf_types.hpp:6621
constexpr bool is_emplace_available_v
Definition: tpf_types.hpp:5386
constexpr bool StackInOrder
Definition: tpf_types.hpp:2334
void append_to_container(TargetContainerType &target_container, SourceContainerType &&source_container)
Definition: tpf_types.hpp:7179
constexpr auto are_numerical_numbers_v
Definition: tpf_types.hpp:5077
constexpr bool is_iterator_type_v
Definition: tpf_types.hpp:3148
constexpr auto is_operable_v
Definition: tpf_types.hpp:5119
type_list_t< unsigned short, unsigned int, unsigned long, unsigned long long > unsigned_integer_list_t
Unsigned integers EXCLUDING unsigned char and boolean.
Definition: tpf_types.hpp:3190
typename hidden::st_std_array_element< remove_cv_ref_t< Type > >::type std_array_element_t
Definition: tpf_types.hpp:2214
hidden::unique_types_t< Types... > unique_types_t
Definition: tpf_types.hpp:5627
array_wrapper_t(ElementType(&)[ElementCount]) -> array_wrapper_t< ElementType *, size_t >
constexpr bool is_vector_v
Definition: tpf_types.hpp:1028
bool is_stack_reversed()
Definition: tpf_types.hpp:2319
hidden::enable_if_integral_t< Type, ReturnType > enable_if_integral_t
Definition: tpf_types.hpp:5080
hidden::map_of_variants_t< KeyType, ElementTypes... > map_of_variants_t
Definition: tpf_types.hpp:6645
enable_if_all_apply_t< apply_return_tuple_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > tuple_if_all_apply_t
Definition: tpf_types.hpp:5292
hidden::union_type_t< unique_types_t< LeftList >, unique_types_t< RightList > > union_type_t
Definition: tpf_types.hpp:5651
constexpr bool is_apply_v
Definition: tpf_types.hpp:5263
constexpr T fn_seq_element(std::integer_sequence< T, Id, Ids... >)
Definition: tpf_types.hpp:2289
void emplace_back(ContainerType< Type, Types... > &container, EleTypes &&... eles)
Definition: tpf_types.hpp:7150
hidden::reverse_sequence_t< remove_cvref_t< SequenceType > > reverse_sequence_t
Definition: tpf_types.hpp:2519
std::make_integer_sequence< remove_cvref_t< decltype(Size)>, Size > make_typed_sequence_t
Definition: tpf_types.hpp:2285
constexpr bool is_constructible_over_the_set_v
Definition: tpf_types.hpp:6392
constexpr bool is_callable_v
Definition: tpf_types.hpp:5423
hidden::multimap_of_variants_t< KeyType, ElementTypes... > multimap_of_variants_t
Definition: tpf_types.hpp:6648
hidden::map_of_tuples_t< KeyType, ElementTypes... > map_of_tuples_t
Definition: tpf_types.hpp:7013
auto create_container(ArgType &&arg, ArgTypes &&... args)
Create a container object.
Definition: tpf_types.hpp:7458
type_list_t< char, short, int, long int, long long int > signed_integral_list_t
Type list of signed integral type INCLUDING character type, but EXCLUDING boolean type.
Definition: tpf_types.hpp:3212
auto to_ref(const Type &value)
Definition: tpf_types.hpp:1234
hidden::enable_if_integer_t< Type, ReturnType > enable_if_integer_t
Definition: tpf_types.hpp:5089
hidden::push_front_type_t< ArgType, Types... > push_front_type_t
Definition: tpf_types.hpp:5600
std::enable_if_t< is_same_flat_v< Type, Types... >, ReturnType > enable_if_same_flat_t
Definition: tpf_types.hpp:5000
hidden::type_list_to_template_class_t< ClassTemplate, Types... > type_list_to_template_class_t
Definition: tpf_types.hpp:6983
decltype(auto) tuple_reader_row_column(TupleType &&tuple)
Definition: tpf_types.hpp:2768
constexpr auto template_parameter_count
Definition: tpf_types.hpp:3390
constexpr auto are_all_in_list_v
Definition: tpf_types.hpp:5053
constexpr bool is_rbegin_available_v
Definition: tpf_types.hpp:5356
typename hidden::st_is_callable< CallbackType, type_list_t<>, type_list_t<>, Types... >::non_callables non_callable_list_t
Definition: tpf_types.hpp:6161
constexpr auto are_signed_integers_v
Definition: tpf_types.hpp:5059
auto make_deque(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7337
constexpr bool is_assignable_from_the_set_v
Definition: tpf_types.hpp:6402
decltype(auto) array_reader_row_column(ArrayType &&array)
Definition: tpf_types.hpp:2744
constexpr bool is_multiplication_valid_v
Definition: tpf_types.hpp:2092
std::array< IntType, N > seq_indices(IdType i, std::array< IntType, N > const &powers)
Definition: tpf_types.hpp:2305
hidden::front_type_t< Types... > front_type_t
Definition: tpf_types.hpp:5573
decltype(auto) get_nth_argument(ArgTypes &&... args)
Definition: tpf_types.hpp:942
constexpr bool has_tuple_common_type_v
Definition: tpf_types.hpp:5699
hidden::template_parameter_type_list_t< Type > template_parameter_type_list_t
Definition: tpf_types.hpp:3393
std::common_type_t< apply_return_t< FuncType, TupleTypes >... > common_apply_t
Definition: tpf_types.hpp:5260
auto pop_front(ContainerType< Type, Types... > &container)
Definition: tpf_types.hpp:7034
constexpr auto are_real_numbers_v
Definition: tpf_types.hpp:5074
decltype(auto) array_writer_row_column(ArrayType &&array)
Definition: tpf_types.hpp:2720
constexpr bool pairwise_common_type_v
Definition: tpf_types.hpp:5548
hidden::select_last_n_types_t< LastN, Types... > select_last_n_types_t
Definition: tpf_types.hpp:5621
hidden::tuple_to_std_array_t< remove_cvref_t< TupleType > > tuple_to_std_array_t
Definition: tpf_types.hpp:5705
constexpr bool ReverseSequence
Definition: tpf_types.hpp:2337
constexpr no_type_t operator*(no_type_t, no_type_t) noexcept
Definition: tpf_types.hpp:2131
result_type signed_common_t
Definition: tpf_types.hpp:6606
constexpr auto is_any_v
Definition: tpf_types.hpp:1921
hidden::last_type_t< Type > last_parameter_type_t
Definition: tpf_types.hpp:5594
types::tuple_if_all_apply_t< FuncType, ArgTypes... > apply_tuple(FuncType &&f, ArgTypes &&... args)
Definition: tpf_types.hpp:5308
make_unsigned_t< common_type_t< Types... > > make_common_unsigned_t
Definition: tpf_types.hpp:5125
constexpr bool all_apply_v
Definition: tpf_types.hpp:5266
hidden::pop_back_type_t< Types... > pop_back_type_t
Definition: tpf_types.hpp:5609
decltype(auto) tuple_writer(TupleType &&tuple)
Definition: tpf_types.hpp:2781
constexpr auto is_integer_v
Definition: tpf_types.hpp:5029
std::integer_sequence< std::common_type_t< remove_cvref_t< decltype(Indices)>... >, Indices... > typed_sequence_t
Definition: tpf_types.hpp:2281
hidden::enable_if_signed_integral_t< Type, ReturnType > enable_if_signed_integral_t
Definition: tpf_types.hpp:5083
bool is_stack_in_order()
Definition: tpf_types.hpp:2329
hidden::common_type_t< Types... > common_type_t
Definition: tpf_types.hpp:5122
auto convert_to_tuple(const std::array< T, Size > &array)
Definition: tpf_types.hpp:5883
constexpr auto sequence_first_element_v
Definition: tpf_types.hpp:2522
void prepend_to_container(TargetContainerType &target_container, SourceContainerType &&source_container)
Definition: tpf_types.hpp:7214
constexpr bool is_push_back_available_v
Definition: tpf_types.hpp:5347
constexpr bool is_empty_available_v
Definition: tpf_types.hpp:5332
constexpr bool is_size_available_v
Definition: tpf_types.hpp:5371
constexpr auto is_set_or_unordered_set_v
Definition: tpf_types.hpp:1933
hidden::intersection_type_t< unique_types_t< LeftList >, unique_types_t< RightList > > intersection_type_t
Definition: tpf_types.hpp:5654
constexpr auto type_max_v
Definition: tpf_types.hpp:267
hidden::select_last_type_t< Types... > select_last_type_t
Definition: tpf_types.hpp:5576
constexpr size_t SelectAll
Definition: tpf_types.hpp:270
typename concate_type_st< Types... >::type concate_type_t
Definition: tpf_types.hpp:6225
std::make_index_sequence< sizeof...(Types)> index_for
Definition: tpf_types.hpp:295
hidden::enable_if_unsigned_integer_t< Type, ReturnType > enable_if_unsigned_integer_t
Definition: tpf_types.hpp:5098
hidden::back_type_t< Types... > back_type_t
Definition: tpf_types.hpp:5582
decltype(types::convert_to_tuple(std::array< Type, Size >{})) create_tuple_t
Definition: tpf_types.hpp:963
auto make_vector(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7293
constexpr bool is_shrink_to_fit_available_v
Definition: tpf_types.hpp:5338
constexpr auto is_type_list_equivalent_v
Definition: tpf_types.hpp:5666
hidden::enable_if_unsigned_integral_t< Type, ReturnType > enable_if_unsigned_integral_t
Definition: tpf_types.hpp:5086
auto for_tuple(FuncType &&f)
Definition: tpf_types.hpp:3060
constexpr auto are_integrals_v
Definition: tpf_types.hpp:5065
constexpr auto get_nth_value(std::integer_sequence< Type, Index, Indices... >) noexcept
Definition: tpf_types.hpp:276
hidden::return_type_t< Type > return_type_t
Definition: tpf_types.hpp:2124
constexpr bool is_resize_available_v
Definition: tpf_types.hpp:5365
std::enable_if_t< is_same_flat_v< Types... >, ReturnType > enable_if_all_the_same_flat_t
Definition: tpf_types.hpp:5003
hidden::difference_type_t< LeftList, RightList > difference_type_t
Definition: tpf_types.hpp:5660
hidden::to_tuple_t< VarType > variant_to_tuple_t
Definition: tpf_types.hpp:5642
auto for_vector(FuncType &&f)
Definition: tpf_types.hpp:5768
std::enable_if_t< std::is_invocable_v< remove_cvref_t< WorkhorseType >, indexer_t< 0 > >||std::is_invocable_v< remove_cvref_t< WorkhorseType >, indexer_t< 0 >, sequence_info > > for_workhorse(WorkhorseType &&workhorse)
Definition: tpf_types.hpp:3026
auto convert_to_container(const std::tuple< Type, Types... > &tuple)
Definition: tpf_types.hpp:5845
std::index_sequence<(std::size_t) Id,(std::size_t) Ids... > index_t
Definition: tpf_types.hpp:289
constexpr auto is_noexcept_v
Test if a function is specified with the keyword noexcept.
Definition: tpf_types.hpp:1673
decltype(auto) array_reader(ArrayType &&array)
Definition: tpf_types.hpp:2733
constexpr bool is_template_type_v
Definition: tpf_types.hpp:1118
constexpr auto is_variant_v
Definition: tpf_types.hpp:1881
hidden::first_parameter_type_t< Type > first_parameter_type_t
Definition: tpf_types.hpp:5591
constexpr auto is_unsigned_integral_v
Definition: tpf_types.hpp:5044
constexpr bool is_any_callable_v
Definition: tpf_types.hpp:6167
constexpr auto is_unsigned_integer_v
Definition: tpf_types.hpp:5035
constexpr bool is_pop_front_available_v
Definition: tpf_types.hpp:5395
typename hidden::st_index_tuple_vector< std::make_index_sequence< N > >::type index_tuple_vector_t
Definition: tpf_types.hpp:1211
hidden::tuple_common_element_t< remove_cvref_t< TupleType > > tuple_common_element_t
Definition: tpf_types.hpp:5702
hidden::types_to_template_class_t< Type, Types... > types_to_template_class_t
Definition: tpf_types.hpp:6980
constexpr size_t array_size(ElementType(&array)[ElementSize]) noexcept
Definition: tpf_types.hpp:1240
constexpr auto sequence_last_element_v
Definition: tpf_types.hpp:2525
constexpr bool is_assignable_to_the_set_v
Definition: tpf_types.hpp:6397
void emplace_front(ContainerType< Type, Types... > &container, EleTypes &&... eles)
Definition: tpf_types.hpp:7132
constexpr auto is_signed_integral_v
Definition: tpf_types.hpp:5041
constexpr auto template_category()
Definition: tpf_types.hpp:1066
decltype(auto) array_writer(ArrayType &&array)
Definition: tpf_types.hpp:2707
constexpr auto is_basic_string_v
Definition: tpf_types.hpp:1930
constexpr auto is_type_in_list_v
Definition: tpf_types.hpp:5624
constexpr auto is_same_template_v
Definition: tpf_types.hpp:3399
enable_if_variant_t< VariantType > visit(VisitorType &&visitor, VariantType &&vt)
Definition: 31-visit.cpp:118
enable_if_all_apply_t< void, FuncType, TupleTypes... > void_if_all_apply_t
Definition: tpf_types.hpp:5288
bool is_parameter_stack_order_reversed()
Definition: tpf_types.hpp:2670
constexpr bool is_all_callable_v
Definition: tpf_types.hpp:6164
hidden::to_variant_t< Type, Types... > to_variant_t
Definition: tpf_types.hpp:5630
constexpr auto sequence_span_v
Definition: tpf_types.hpp:2537
auto pop_back(ContainerType< Type, Types... > &container)
Definition: tpf_types.hpp:7074
constexpr bool is_back_available_v
Definition: tpf_types.hpp:5392
hidden::make_signed_t< Type > make_signed_t
Definition: tpf_types.hpp:5110
remove_cv_ref_t< Type > remove_cvref_t
Definition: tpf_types.hpp:298
auto cast_array(T(&array)[N]) noexcept
Definition: tpf_types.hpp:865
hidden::set_of_variants_t< ElementTypes... > set_of_variants_t
Definition: tpf_types.hpp:6630
constexpr bool is_container_type_v
Definition: tpf_types.hpp:5401
type_list_t< float, double, long double > real_number_list_t
Type list of real numbers (floating-point numbers).
Definition: tpf_types.hpp:3218
auto evaluate_lambdas(const std::tuple< FuncType, FuncTypes... > &tuple, ArgFirst &&arg, ArgTypes &&... args)
Definition: tpf_types.hpp:5977
constexpr size_t InvalidIndex
Definition: tpf_types.hpp:269
auto make_variants(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7479
hidden::to_recursive_type_list_t< remove_cv_ref_t< T > > to_recursive_type_list_t
Definition: tpf_types.hpp:1037
auto array_wrapper(ElementType(&array)[ElementSize]) noexcept
Definition: tpf_types.hpp:1228
decltype(auto) array_indexer_row_column(ArrayType &&array)
Definition: tpf_types.hpp:2695
constexpr auto is_numerical_number_v
Definition: tpf_types.hpp:5050
std::make_index_sequence<(std::size_t) N > make_index_t
Definition: tpf_types.hpp:292
hidden::nth_type_t< SelectIndex, Type > nth_parameter_type_t
Definition: tpf_types.hpp:5597
constexpr auto is_tuple_v
Definition: tpf_types.hpp:1893
make_signed_t< common_type_t< Types... > > make_common_signed_t
Definition: tpf_types.hpp:5131
hidden::deque_of_variants_t< ElementTypes... > deque_of_variants_t
Definition: tpf_types.hpp:6624
hidden::type_list_to_tuple_t< remove_cvref_t< TypeList > > type_list_to_tuple_t
Definition: tpf_types.hpp:1183
long long big_integer_t
Definition: tpf_types.hpp:272
hidden::unordered_multimap_of_tuples_t< KeyType, ElementTypes... > unordered_multimap_of_tuples_t
Definition: tpf_types.hpp:7022
constexpr std::enable_if_t< std::is_same_v< std::remove_reference_t< TargetType >, std::remove_reference_t< _Ty > >, _Ty && > smart_forward(std::remove_reference_t< _Ty > &_Arg) noexcept
Definition: tpf_types.hpp:412
constexpr bool is_push_front_available_v
Definition: tpf_types.hpp:5344
constexpr bool is_iterator_excluding_pointer_v
Definition: tpf_types.hpp:3151
constexpr bool is_array_v
Definition: tpf_types.hpp:1237
constexpr size_t std_array_size_v
Definition: tpf_types.hpp:2211
hidden::make_unsigned_t< Type > make_unsigned_t
Definition: tpf_types.hpp:5107
result_type unsigned_common_t
Definition: tpf_types.hpp:6615
constexpr auto sequence_element_count_v
Definition: tpf_types.hpp:2531
auto freeze_parameter(FuncType &&func, ArgType arg, ArgTypes... args)
Definition: tpf_types.hpp:5890
std::enable_if_t< is_same_flat_v< Types... > > void_if_all_the_same_flat_t
Definition: tpf_types.hpp:5016
constexpr bool is_type_in_the_set_v
Definition: tpf_types.hpp:6387
enable_if_all_apply_t< apply_return_vector_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > vector_if_all_apply_t
Definition: tpf_types.hpp:5300
constexpr auto is_in_list_v
test if TestType exists in Types...
Definition: tpf_types.hpp:5026
constexpr auto are_unsigned_integrals_v
Definition: tpf_types.hpp:5071
void push_front(ContainerType< Type, Types... > &container, EleType &&ele)
Definition: tpf_types.hpp:7088
constexpr auto is_pair_v
Definition: tpf_types.hpp:1887
std::enable_if_t< is_same_v< Types... >, ReturnType > enable_if_all_the_same_t
Definition: tpf_types.hpp:4997
constexpr auto is_pair_of_variant_v
Definition: tpf_types.hpp:1890
hidden::deque_of_tuples_t< ElementTypes... > deque_of_tuples_t
Definition: tpf_types.hpp:7004
hidden::multimap_of_tuples_t< KeyType, ElementTypes... > multimap_of_tuples_t
Definition: tpf_types.hpp:7016
constexpr auto are_integers_v
Definition: tpf_types.hpp:5056
hidden::to_tuple_t< Types... > to_tuple_t
Definition: tpf_types.hpp:5639
decltype(auto) get_element(ContainerType container, IndexType index)
Definition: tpf_types.hpp:7617
hidden::first_n_types_t< FirstN, Types... > first_n_types_t
Definition: tpf_types.hpp:5612
constexpr bool operator==(no_type_t, no_type_t) noexcept
Definition: tpf_types.hpp:2134
hidden::select_nth_type_t< SelectIndex, Types... > select_nth_type_t
Definition: tpf_types.hpp:5585
hidden::set_of_tuples_t< ElementTypes... > set_of_tuples_t
Definition: tpf_types.hpp:7010
std::enable_if_t< common_type_v< remove_cvref_t< ArgTypes >... >, ReturnType > enable_if_common_exisits_t
Definition: tpf_types.hpp:5141
hidden::unordered_multiset_of_variants_t< ElementTypes... > unordered_multiset_of_variants_t
Definition: tpf_types.hpp:6639
hidden::pop_front_type_t< Types... > pop_front_type_t
Definition: tpf_types.hpp:5606
constexpr auto is_real_number_v
Definition: tpf_types.hpp:5047
type_list_t< short, int, long, long long > signed_integer_list_t
Signed integers EXCLUDING char and boolean.
Definition: tpf_types.hpp:3184
variant_visitors< remove_cv_ref_t< CallbackTypes >... > make_variant_visitors(CallbackTypes &&... visitors)
Definition: tpf_types.hpp:7891
constexpr bool is_invocable_v
Definition: tpf_types.hpp:6063
type_list_t< short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long > integer_list_t
Type list of integers EXCLUSING character type and boolean type.
Definition: tpf_types.hpp:3178
enable_if_all_apply_t< apply_return_array_t< FuncType, TupleTypes... >, FuncType, TupleTypes... > array_if_all_apply_t
Definition: tpf_types.hpp:5296
hidden::enable_if_all_in_list_t< TestTypeList, TypeList, ReturnType > enable_if_all_in_list_t
Definition: tpf_types.hpp:6409
hidden::unordered_map_of_variants_t< KeyType, ElementTypes... > unordered_map_of_variants_t
Definition: tpf_types.hpp:6651
std::enable_if_t< pairwise_common_type_v< T, Types... > > enable_pairwise_common_type_t
Definition: tpf_types.hpp:5551
auto make_container(Type &&arg, Types &&... args)
constexpr bool is_begin_available_v
Definition: tpf_types.hpp:5350
constexpr auto tuple_size_v
Definition: tpf_types.hpp:1918
void push_back(ContainerType< Type, Types... > &container, EleType &&ele)
Definition: tpf_types.hpp:7110
hidden::unordered_map_of_tuples_t< KeyType, ElementTypes... > unordered_map_of_tuples_t
Definition: tpf_types.hpp:7019
type_list_t< char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long > integral_list_t
Type list of integral type INCLUDING character type, but EXCLUDING boolean type.
Definition: tpf_types.hpp:3198
constexpr bool is_end_available_v
Definition: tpf_types.hpp:5353
constexpr auto is_tuple_empty_v
Definition: tpf_types.hpp:1896
hidden::variant_to_type_list_t< remove_cvref_t< VarType > > variant_to_type_list_t
Definition: tpf_types.hpp:1186
std::tuple< apply_return_t< FuncType, TupleTypes > ... > apply_return_tuple_t
Definition: tpf_types.hpp:5277
hidden::enable_if_real_number_t< Type, ReturnType > enable_if_real_number_t
Definition: tpf_types.hpp:5101
constexpr auto is_string_v
Test is Type is of string type.
Definition: tpf_types.hpp:3446
typename hidden::st_type_list_to_tuple_of_vectors< Types... >::type tuple_of_vectors_t
Definition: tpf_types.hpp:1189
auto & cast_ref(std::unique_ptr< T[], Deleter > &uptr) noexcept
Definition: tpf_types.hpp:465
std::ostream & operator<<(std::ostream &os, range< Type > const &r)
Definition: tpf_types.hpp:1450
constexpr auto is_same_flat_v
Definition: tpf_types.hpp:4991
hidden::nth_type_t< SelectIndex, Types... > nth_type_t
Definition: tpf_types.hpp:5588
constexpr bool is_insert_iterator_available_v
Definition: tpf_types.hpp:5377
auto reverse(ContainerType &&container)
Definition: tpf_types.hpp:7587
hidden::container_of_variants_t< ContainerType, ElementTypes... > container_of_variants_t
Definition: tpf_types.hpp:6618
decltype(auto) tuple_writer_row_column(TupleType &&tuple)
Definition: tpf_types.hpp:2794
constexpr std::enable_if_t< std::is_same_v< std::remove_reference_t< TargetType >, std::remove_reference_t< _Ty > >, std::remove_reference_t< _Ty > && > smart_move(_Ty &&_Arg) noexcept
Definition: tpf_types.hpp:449
hidden::list_of_variants_t< ElementTypes... > list_of_variants_t
Definition: tpf_types.hpp:6627
range(Type) -> range< Type >
hidden::first_n_types_to_template_class_t< FirstN, TemplateClass, Types... > first_n_types_to_template_class_t
Definition: tpf_types.hpp:6991
typename hidden::st_is_callable< CallbackType, type_list_t<>, type_list_t<>, Types... >::callables callable_list_t
Definition: tpf_types.hpp:6158
std::string type_to_string()
Returns Type's string name.
Definition: tpf_types.hpp:1291
hidden::remove_type_t< ArgType, Types... > remove_type_t
Definition: tpf_types.hpp:5657
std::enable_if_t< common_apply_v< FuncType, TupleTypes... >, std::common_type_t< apply_return_t< FuncType, TupleTypes >... > > common_type_if_all_apply_t
Definition: tpf_types.hpp:5304
std::enable_if_t< is_pair_of_variant_v< remove_cv_ref_t< PairType > > > visit_variant(VisitorType &&visit, PairType &&vpr)
Definition: tpf_types.hpp:7740
constexpr bool is_emplace_front_available_v
Definition: tpf_types.hpp:5380
constexpr bool is_index_operator_available_v
Definition: tpf_types.hpp:5341
hidden::select_first_n_types_t< FirstN, Types... > select_first_n_types_t
Definition: tpf_types.hpp:5615
decltype(auto) decay(Type &&arg)
Definition: tpf_types.hpp:1267
constexpr bool common_apply_v
Definition: tpf_types.hpp:5269
typename hidden::st_build_arg_types< Heads, Tails >::type arg_list_t
Definition: tpf_types.hpp:6155
hidden::make_unsigned_integral_t< Type > make_unsigned_integral_t
Definition: tpf_types.hpp:5113
constexpr bool is_void_return_type_v
Definition: tpf_types.hpp:5429
constexpr auto is_unique_ptr_v
Definition: tpf_types.hpp:1884
constexpr bool is_subtraction_valid_v
Definition: tpf_types.hpp:2088
hidden::list_of_tuples_t< ElementTypes... > list_of_tuples_t
Definition: tpf_types.hpp:7007
constexpr bool tuple_common_type_v
Definition: tpf_types.hpp:5557
constexpr auto is_template_template_v
Definition: tpf_types.hpp:6228
constexpr auto type_count_v
Definition: tpf_types.hpp:3158
unsigned long long big_unsigned_t
Definition: tpf_types.hpp:273
constexpr auto are_signed_integrals_v
Definition: tpf_types.hpp:5068
constexpr auto are_unsigned_integers_v
Definition: tpf_types.hpp:5062
constexpr auto is_same_v
Test if all types are the same.
Definition: tpf_types.hpp:4985
type_list_t< char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long, float, double, long double > numerical_number_list_t
All numbers mathematical operations.
Definition: tpf_types.hpp:3225
std::enable_if_t< is_same_flat_v< Type, Types... > > void_if_same_flat_t
Definition: tpf_types.hpp:5013
hidden::enable_if_numerical_number_t< Type, ReturnType > enable_if_numerical_number_t
Definition: tpf_types.hpp:5104
constexpr bool is_addition_valid_v
Definition: tpf_types.hpp:2084
auto for_array(FuncType &&f)
Definition: tpf_types.hpp:5730
constexpr bool is_emplace_back_available_v
Definition: tpf_types.hpp:5383
constexpr bool is_division_valid_v
Definition: tpf_types.hpp:2096
Includes subnamespace conversion.
Definition: 31-visit.cpp:7
std::remove_reference_t< std::decay_t< Type > > decay_remove_ref_t
Decay, remove reference.
Definition: tpf_types.hpp:170
typename SetTagType::trio_set_t trio_set_t
Definition: tpf_types.hpp:1999
auto reverse_iterator_to_iterator(ReverseIteratorType &&itr)
Definition: tpf_types.hpp:1491
decltype(auto) make_container(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7923
typename SetTagType::trio_sets_of_sets_t trio_sets_of_sets_t
Definition: tpf_types.hpp:2008
typename SetTagType::trio_sets_t trio_sets_t
Definition: tpf_types.hpp:2002
auto find_range_iterators(ForwardIterator first, ForwardIterator last, const EleType &value, CompareCallbackType &&compare_callback=CompareCallbackType{})
Definition: tpf_types.hpp:1519
typename SetTagType::duet_set_of_sets_t duet_set_of_sets_t
Definition: tpf_types.hpp:1987
constexpr unsigned long long two_power_n(Type n)
Definition: tpf_types.hpp:254
auto minimum(Type_1 a, Type_2 b)
Definition: tpf_types.hpp:196
constexpr bool is_const_reference_v
Test if Type is reference to const object.
Definition: tpf_types.hpp:216
typename SetTagType::duet_sets_of_sets_t duet_sets_of_sets_t
Definition: tpf_types.hpp:1990
typename SetTagType::set_t set_t
Definition: tpf_types.hpp:1966
typename SetTagType::duet_sets_t duet_sets_t
Definition: tpf_types.hpp:1984
direction_t
Definition: tpf_types.hpp:143
typename SetTagType::sets_of_sets_t sets_of_sets_t
Definition: tpf_types.hpp:1975
auto reverse_iterator_to_index(ContainerType &&cntr, reverse_iterator_type &&offset)
constexpr bool is_const_v
Definition: tpf_types.hpp:154
typename SetTagType::duet_set_t duet_set_t
Definition: tpf_types.hpp:1981
decltype(auto) make_deque(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7917
auto binary_find_index(ForwardIterator first, ForwardIterator last, const EleType &value, CompareCallbackType &&compare_callback=CompareCallbackType{})
Definition: tpf_types.hpp:1565
decltype(auto) reverse(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7971
decltype(auto) reverse(ContainerType &&container)
Definition: tpf_types.hpp:7959
typename SetTagType::trio_set_of_sets_t trio_set_of_sets_t
Definition: tpf_types.hpp:2005
decltype(auto) make_vector(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7911
auto index_to_reverse_iterator(ContainerType &&cntr, IndexType &&offset)
auto iterator_to_index(ContainerType &&cntr, iterator_type &&offset)
auto binary_find_iterator(ForwardIterator first, ForwardIterator last, const EleType &value, CompareCallbackType &&compare_callback=CompareCallbackType{})
Definition: tpf_types.hpp:1556
std::remove_cv_t< std::remove_reference_t< Type > > remove_cv_ref_t
Remove const volatile reference from Type.
Definition: tpf_types.hpp:151
remove_cv_ref_t< std::remove_pointer_t< decay_remove_cv_ref_t< Type > > > primitive_type_t
Decay, remove const, volatile, reference, then remove pointer and remove const and volatile.
Definition: tpf_types.hpp:178
auto iterator_to_reverse_iterator(IteratorType &&itr)
Definition: tpf_types.hpp:1498
typename SetTagType::set_of_duets_t set_of_duets_t
Definition: tpf_types.hpp:1993
auto binary_find_bool_index_pair(ForwardIterator first, ForwardIterator last, const EleType &value, CompareCallbackType &&compare_callback=CompareCallbackType{})
Definition: tpf_types.hpp:1615
auto binary_find_bool_iterator_pair(ForwardIterator first, ForwardIterator last, const EleType &value, CompareCallbackType &&compare_callback=CompareCallbackType{})
Definition: tpf_types.hpp:1586
std::remove_cv_t< std::remove_reference_t< std::decay_t< Type > > > decay_remove_cv_ref_t
Decay, remove const, volatile, reference.
Definition: tpf_types.hpp:162
typename SetTagType::trio_set_element_t trio_set_element_t
Definition: tpf_types.hpp:1996
typename SetTagType::duet_set_element_t duet_set_element_t
Definition: tpf_types.hpp:1978
auto maximum(Type_1 a, Type_2 b)
Definition: tpf_types.hpp:181
auto make_rotator(ContainerType &&cntr)
Definition: tpf_types.hpp:8013
decltype(auto) make_random_access_container(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7905
typename SetTagType::set_element_t set_element_t
Definition: tpf_types.hpp:1963
typename SetTagType::set_of_sets_t set_of_sets_t
Definition: tpf_types.hpp:1972
decltype(auto) create_container(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7943
auto find_range_indices(ForwardIterator first, ForwardIterator last, const EleType &value, CompareCallbackType &&compare_callback=CompareCallbackType{})
Definition: tpf_types.hpp:1528
auto index_to_iterator(ContainerType &&cntr, IndexType &&index)
decltype(auto) make_variants(Type &&arg, Types &&... args)
Definition: tpf_types.hpp:7951
decltype(auto) get_element(ContainerType container, IndexType index)
Definition: tpf_types.hpp:7899
typename SetTagType::sets_t sets_t
Definition: tpf_types.hpp:1969
static constexpr bool Before
Definition: tpf_types.hpp:1657
static constexpr bool After
Definition: tpf_types.hpp:1658
static constexpr bool Append
Definition: tpf_types.hpp:1661
static constexpr bool True
Definition: tpf_types.hpp:1655
static constexpr bool Yes
Definition: tpf_types.hpp:1652
static constexpr bool False
Definition: tpf_types.hpp:1654
static constexpr bool Left
Definition: tpf_types.hpp:1645
static constexpr bool Or
Definition: tpf_types.hpp:1648
static constexpr bool Prepend
Definition: tpf_types.hpp:1660
static constexpr bool No
Definition: tpf_types.hpp:1651
static constexpr bool Right
Definition: tpf_types.hpp:1646
static constexpr bool And
Definition: tpf_types.hpp:1649
ContainerType< EleType, Types... > set_t
Definition: tpf_types.hpp:1942
EleType set_element_t
Definition: tpf_types.hpp:1940
ContainerType< ContainerType< ContainerType< EleType, Types... > > > set_of_sets_t
Definition: tpf_types.hpp:1944
std::tuple< set_t, set_t, set_t > trio_set_t
Definition: tpf_types.hpp:1956
std::tuple< set_element_t, set_element_t, set_element_t > trio_set_element_t
Definition: tpf_types.hpp:1955
ContainerType< ContainerType< EleType, Types... > > sets_t
Definition: tpf_types.hpp:1943
std::tuple< sets_of_sets_t, sets_of_sets_t, sets_of_sets_t > trio_sets_of_sets_t
Definition: tpf_types.hpp:1959
ContainerType< ContainerType< ContainerType< ContainerType< EleType, Types... > > > > sets_of_sets_t
Definition: tpf_types.hpp:1945
std::tuple< sets_t, sets_t, sets_t > trio_sets_t
Definition: tpf_types.hpp:1957
std::tuple< set_of_sets_t, set_of_sets_t, set_of_sets_t > trio_set_of_sets_t
Definition: tpf_types.hpp:1958
std::tuple< set_of_sets_t, set_of_sets_t > duet_set_of_sets_t
Definition: tpf_types.hpp:1950
std::tuple< sets_of_sets_t, sets_of_sets_t > duet_sets_of_sets_t
Definition: tpf_types.hpp:1951
std::tuple< set_t, set_t > duet_set_t
Definition: tpf_types.hpp:1948
std::tuple< sets_t, sets_t > duet_sets_t
Definition: tpf_types.hpp:1949
std::tuple< set_element_t, set_element_t > duet_set_element_t
Definition: tpf_types.hpp:1947
ContainerType< duet_set_t > set_of_duets_t
Definition: tpf_types.hpp:1953
std::atomic< int > thread_count
Definition: tpf_types.hpp:1639
array_wrapper_t(ElementType(&array)[ElementCount]) noexcept
Definition: tpf_types.hpp:1220
std::pair< PointerType, SizeType > base_type
Definition: tpf_types.hpp:1217
is_operable_t< typename common_type_st< Type1, Type2 >::type, typename common_type_st< Type2, Types... >::type > type
Definition: tpf_types.hpp:4052
typename common_type_st< Type1, Type2, Types... >::type type
Definition: tpf_types.hpp:4076
typename common_type_st< Type1, Type2 >::type type
Definition: tpf_types.hpp:4070
typename difference_type_st< type_list_t< Types... >, Type, RightTypes... >::type type
Definition: tpf_types.hpp:4883
std::conditional_t< sizeof...(RightTypes)==0, list, typename difference_type_st< list, RightTypes... >::type > type
Definition: tpf_types.hpp:4865
typename difference_type_st< type_list_t< Types... >, Type >::type list
Definition: tpf_types.hpp:4862
typename difference_type_st< type_list_t< Types... >, Type >::type type
Definition: tpf_types.hpp:4877
std::conditional_t< FirstN==1, type_list_t< LeftTypes..., RightType >, typename first_n_types_list_st< FirstN-1, type_list_t< LeftTypes..., RightType >, type_list_t< RightTypes... > >::type > type_list_1
Definition: tpf_types.hpp:4426
std::conditional_t< is_valid_type_v< n_types >, type_list_to_template_class_t< TemplateClass, n_types >, no_type_t > class_t
Definition: tpf_types.hpp:6815
first_n_types_t< FirstN, type_list_t< Types... > > n_types
Definition: tpf_types.hpp:6800
std::conditional_t< is_valid_type_v< n_types >, type_list_to_template_class_t< TemplateClass, n_types >, no_type_t > class_t
Definition: tpf_types.hpp:6803
std::conditional_t< is_valid_type_v< class_t >, class_t, no_type_t > type
Definition: tpf_types.hpp:6805
std::conditional_t< FirstN==0, type_list_t<>, std::conditional_t< FirstN >=sizeof...(RightTypes), type_list_t< RightTypes... >, typename first_n_types_list_st< FirstN, type_list_t<>, type_list_t< RightTypes... > >::type > > type
Definition: tpf_types.hpp:4440
std::conditional_t< FirstN==0, type_list_t<>, std::conditional_t< FirstN >=sizeof...(RightTypes), type_list_t< RightTypes... >, typename first_n_types_list_st< FirstN, type_list_t<>, type_list_t< RightTypes... > >::type > > type
Definition: tpf_types.hpp:4450
std::conditional_t< is_valid_type_v< n_types >, type_list_to_template_class_t< TemplateClass, n_types >, no_type_t > class_t
Definition: tpf_types.hpp:6837
std::conditional_t< is_valid_type_v< n_types >, type_list_to_template_class_t< TemplateClass, n_types >, no_type_t > class_t
Definition: tpf_types.hpp:6851
typename intersection_type_st< type_list_t< Types... >, Type, RightTypes... >::type type
Definition: tpf_types.hpp:4779
std::conditional_t< is_type_in_list_v< Type, list >, type_list_t< Type >, type_list_t<> > type
Definition: tpf_types.hpp:4751
std::conditional_t< sizeof...(RightTypes)==0, list, append_type_t< list, typename intersection_type_st< left_list, RightTypes... >::type > > type
Definition: tpf_types.hpp:4761
typename intersection_type_st< type_list_t< Types... >, Type >::type type
Definition: tpf_types.hpp:4773
static constexpr bool value
Definition: tpf_types.hpp:1820
static constexpr bool value
Definition: tpf_types.hpp:1856
static constexpr bool value
Definition: tpf_types.hpp:3799
static constexpr bool value
Definition: tpf_types.hpp:1710
static constexpr bool value
Definition: tpf_types.hpp:3410
static constexpr size_t count
Definition: tpf_types.hpp:3250
static constexpr bool value
Definition: tpf_types.hpp:1793
static constexpr bool empty
Definition: tpf_types.hpp:1794
static constexpr bool value
Definition: tpf_types.hpp:1680
std::conditional_t< LastN==1, new_right, typename last_n_types_list_st< LastN-1, new_left, new_right >::type > type1
Definition: tpf_types.hpp:4497
std::conditional_t< LastN==0, type_list_t<>, std::conditional_t< LastN >=sizeof...(LeftTypes), type_list_t< LeftTypes... >, typename last_n_types_list_st< LastN, type_list_t< LeftTypes... >, type_list_t<> >::type > > type
Definition: tpf_types.hpp:4519
std::conditional_t< LastN==0, type_list_t<>, std::conditional_t< LastN >=sizeof...(LeftTypes), type_list_t< LeftTypes... >, typename last_n_types_list_st< LastN, type_list_t< LeftTypes... >, type_list_t<> >::type > > type
Definition: tpf_types.hpp:4509
std::conditional_t< is_valid_type_v< nth_type >, TemplateClass< nth_type >, nth_type > type
Definition: tpf_types.hpp:6787
std::conditional_t< is_valid_type_v< nth_type >, TemplateClass< nth_type >, nth_type > type
Definition: tpf_types.hpp:6776
std::conditional_t< sizeof...(RightTypes)==0, type_list_t< LeftTypes... >, typename pop_back_type_st< left_list, right_list >::type > type
Definition: tpf_types.hpp:4373
typename pop_back_type_st< type_list_t<>, type_list_t< Types... > >::type type
Definition: tpf_types.hpp:4385
typename pop_back_type_st< type_list_t<>, type_list_t< Types... > >::type type
Definition: tpf_types.hpp:4379
typename pop_front_type_st< type_list_t< Types... > >::type type
Definition: tpf_types.hpp:4351
typename pop_front_type_st< type_list_t< Types... > >::type type
Definition: tpf_types.hpp:4345
std::conditional_t< sizeof...(RightTypes)==0, list, prepend_type_t< list, typename remove_type_st< ArgType, RightTypes... >::type > > type
Definition: tpf_types.hpp:4807
typename remove_type_st< ArgType, Type >::type list
Definition: tpf_types.hpp:4804
std::conditional_t< std::is_same_v< ArgType, Type >, type_list_t<>, type_list_t< Type > > type
Definition: tpf_types.hpp:4798
typename remove_type_st< ArgType, Type, RightTypes... >::type type
Definition: tpf_types.hpp:4825
typename remove_type_st< ArgType, Type >::type type
Definition: tpf_types.hpp:4819
typename remove_type_st< ArgType, type_list_t< Types... > >::type type
Definition: tpf_types.hpp:4837
typename remove_type_st< ArgType, type_list_t< Types... > >::type type
Definition: tpf_types.hpp:4831
typename replace_type_st< NewType, OldType, Type >::type list
Definition: tpf_types.hpp:4908
std::conditional_t< sizeof...(RightTypes), list, prepend_type_t< list, typename replace_type_st< NewType, OldType, RightTypes... >::type > > type
Definition: tpf_types.hpp:4911
std::conditional_t< std::is_same_v< OldType, Type >, type_list_t< NewType >, type_list_t< Type > > type
Definition: tpf_types.hpp:4902
typename replace_type_st< NewType, OldType, Type, RightTypes... >::type type
Definition: tpf_types.hpp:4929
typename replace_type_st< NewType, OldType, Type >::type type
Definition: tpf_types.hpp:4923
std::conditional_t< sizeof...(Types)==0, Type, typename select_last_type_st< Types... >::type > type
Definition: tpf_types.hpp:4191
std::conditional_t< sizeof...(Types)==0, Type, typename select_last_type_st< Types... >::type > type
Definition: tpf_types.hpp:4210
std::conditional_t< SelectIndex==0, Type, typename select_nth_type_st< SelectIndex-1, Types... >::type > type
Definition: tpf_types.hpp:4241
std::conditional_t< SelectIndex==0, Type, typename select_nth_type_st< SelectIndex-1, Types... >::type > type
Definition: tpf_types.hpp:4260
typename common_type_st< Type, Types... >::type type
Definition: tpf_types.hpp:4109
std::conditional_t< SequenceInOrder, remove_cvref_t< decltype(fn_create_sequence_in_order(std::integer_sequence< value_type >{}, workhorse_range_type{}))>, remove_cvref_t< decltype(fn_create_sequence_reverse_order(std::integer_sequence< value_type >{}, workhorse_range_type{}))> > type
Definition: tpf_types.hpp:2661
std::make_signed_t< remove_cvref_t< decltype(EndValue)> > value_type
Definition: tpf_types.hpp:2638
std::conditional_t< SequenceInOrder, remove_cvref_t< decltype(fn_create_sequence_in_order(std::integer_sequence< value_type >{}, workhorse_range_type{}))>, remove_cvref_t< decltype(fn_create_sequence_reverse_order(std::integer_sequence< value_type >{}, workhorse_range_type{}))> > type
Definition: tpf_types.hpp:2647
std::make_signed_t< remove_cvref_t< decltype(EndValue)> > value_type
Definition: tpf_types.hpp:2627
std::conditional_t< SequenceInOrder, remove_cvref_t< decltype(fn_create_sequence_in_order(std::integer_sequence< value_type >{}, workhorse_range_type{}))>, remove_cvref_t< decltype(fn_create_sequence_reverse_order(std::integer_sequence< value_type >{}, workhorse_range_type{}))> > type
Definition: tpf_types.hpp:2632
std::conditional_t<!value, types::push_back_type_t< void, non_callable_list >, non_callable_list > non_callables
Definition: tpf_types.hpp:6081
std::conditional_t< value, types::push_back_type_t< void, callable_list >, callable_list > callables
Definition: tpf_types.hpp:6080
std::conditional_t< value, types::push_back_type_t< Type, callable_list >, callable_list > callables
Definition: tpf_types.hpp:6094
std::conditional_t<!value, types::push_back_type_t< Type, non_callable_list >, non_callable_list > non_callables
Definition: tpf_types.hpp:6095
static constexpr bool value
Definition: tpf_types.hpp:970
typename st_revese_sequence_operation< std::integer_sequence< T >, std::integer_sequence< T, args... > >::type type
Definition: tpf_types.hpp:2447
static constexpr size_t Count
Definition: tpf_types.hpp:2494
decltype(tuple_addition_operator(std::declval< T >(), std::declval< S >())) type
Definition: tpf_types.hpp:5539
static constexpr size_t value
Definition: tpf_types.hpp:1903
std::tuple< std::vector< Types >... > type
Definition: tpf_types.hpp:1125
tpf::types::common_type_t< tpf::types::remove_cvref_t< ArgTypes >... > common_t
Definition: tpf_types.hpp:5202
static constexpr std::size_t N
Definition: tpf_types.hpp:5185
tpf::types::common_type_t< tpf::types::remove_cvref_t< ArgTypes >... > common_t
Definition: tpf_types.hpp:5188
std::vector< std::size_t > type
Definition: tpf_types.hpp:1196
std::tuple< Types... > type
Definition: tpf_types.hpp:4626
std::variant< Type, Types... > type
Definition: tpf_types.hpp:4604
static constexpr size_t value
Definition: tpf_types.hpp:3083
typename type_list_to_template_class_st< ClassTemplate, Types... >::type type
Definition: tpf_types.hpp:6743
typename type_list_to_template_class_st< std::variant, unique_types_t< Types... > >::type type
Definition: tpf_types.hpp:6750
typename type_list_to_template_class_st< std::variant, unique_types_t< Types... > >::type type
Definition: tpf_types.hpp:6757
typename type_list_to_template_class_st< ClassTemplate, Types... >::type type
Definition: tpf_types.hpp:6737
typename types_to_template_class_st< ClassTemplate< InnerTypes... >, Types... >::type type
Definition: tpf_types.hpp:6692
typename types_to_template_class_st< ClassTemplate< InnerTypes... >, Types... >::type type
Definition: tpf_types.hpp:6708
typename types_to_template_class_st< std::variant< InnerTypes... >, unique_types_t< Types... > >::type type
Definition: tpf_types.hpp:6699
typename types_to_template_class_st< std::variant< InnerTypes... >, unique_types_t< Types... > >::type type
Definition: tpf_types.hpp:6715
typename types_to_template_class_st< Type, Types... >::type type
Definition: tpf_types.hpp:6684
std::conditional_t< is_in_list_v< ArgType, list >, list, type_list_t< ArgType, Types... > > type
Definition: tpf_types.hpp:4712
typename union_type_st< type_list_t< Types... >, Type >::type list
Definition: tpf_types.hpp:4701
std::conditional_t< sizeof...(RightTypes)==0, list, typename union_type_st< list, RightTypes... >::type > type
Definition: tpf_types.hpp:4704
std::conditional_t< is_type_in_list_v< Type, list >, list, type_list_t< Types..., Type > > type
Definition: tpf_types.hpp:4695
typename union_type_st< type_list_t< Types... >, Type, RightTypes... >::type type
Definition: tpf_types.hpp:4730
typename union_type_st< type_list_t< Types... >, Type >::type type
Definition: tpf_types.hpp:4724
typename unique_types_st< type_list_t< Types... >, Type >::type list
Definition: tpf_types.hpp:4586
std::conditional_t< is_type_in_list_v< Type, list >, list, type_list_t< Types..., Type > > type
Definition: tpf_types.hpp:4580
typename unique_types_st< type_list_t< Types... >, RightTypes... >::type type
Definition: tpf_types.hpp:4594
static constexpr T Row
Definition: tpf_types.hpp:2232
static constexpr T RowSize
Definition: tpf_types.hpp:2233
static constexpr T ColumnSize
Definition: tpf_types.hpp:2235
static constexpr T Column
Definition: tpf_types.hpp:2234
constexpr auto operator()(indexer_t< RowIndex >, indexer_t< ColumnIndex >)
Definition: tpf_types.hpp:2242
constexpr auto operator()(indexer_t< HeightIndex >, indexer_t< RowIndex >, indexer_t< ColumnIndex >)
Definition: tpf_types.hpp:2268
static constexpr T RowSize
Definition: tpf_types.hpp:2260
static constexpr T HeightSize
Definition: tpf_types.hpp:2258
static constexpr T Column
Definition: tpf_types.hpp:2261
static constexpr T Row
Definition: tpf_types.hpp:2259
static constexpr T ColumnSize
Definition: tpf_types.hpp:2262
static constexpr T Height
Definition: tpf_types.hpp:2257
static constexpr T Index
Definition: tpf_types.hpp:2221
static constexpr T Size
Definition: tpf_types.hpp:2222
This type is used to test validity of a type.
Definition: tpf_types.hpp:2020
static std::enable_if_t< is_pair_of_variant_v< remove_cv_ref_t< PairType > > > visit_variant(VisitorType &&visitors, IteratorType &&itr, PairType &&vpr)
Definition: tpf_types.hpp:7694
static std::enable_if_t< is_variant_v< remove_cv_ref_t< VariantType > > > visit_variant(VisitorType &&visitors, VariantType &&vpr)
Definition: tpf_types.hpp:7671
static std::enable_if_t< is_variant_v< remove_cv_ref_t< VariantType > > > visit_variant(VisitorType &&visitors, IteratorType &&itr, VariantType &&vpr)
Definition: tpf_types.hpp:7717
static std::enable_if_t< is_pair_of_variant_v< remove_cv_ref_t< PairType > > > visit_variant(VisitorType &&visitors, PairType &&vpr)
Definition: tpf_types.hpp:7648
This type is used to manipulate type list.
Definition: tpf_types.hpp:956
static constexpr bool value
Definition: tpf_types.hpp:6330
T & operator[](IndexType n) noexcept
Definition: tpf_types.hpp:5167
static constexpr auto Count
Definition: tpf_types.hpp:5150
auto & ref() const noexcept
Definition: tpf_types.hpp:5161
std::unique_ptr< T[], deleter > uptr
Definition: tpf_types.hpp:5154
const T & operator[](IndexType n) const noexcept
Definition: tpf_types.hpp:5173
void for_each_reverse_iterator(ContainerType &&container)
Definition: tpf_types.hpp:7859
variant_visitors(CallbackTypes... visitors)
Definition: tpf_types.hpp:7791
std::enable_if_t< is_pair_of_variant_v< remove_cv_ref_t< PairType > > > operator()(PairType &&vt)
Definition: tpf_types.hpp:7880
void for_each_reverse_index(ContainerType &&container)
Definition: tpf_types.hpp:7865
std::tuple< CallbackTypes... > visitors_t
Definition: tpf_types.hpp:7787
void for_each(ContainerType &&container)
Definition: tpf_types.hpp:7801
void for_each_reverse(ContainerType &&container)
Definition: tpf_types.hpp:7810
std::enable_if_t< is_variant_v< remove_cv_ref_t< VariantType > > > operator()(VariantType &&vt)
Definition: tpf_types.hpp:7873
decltype(auto) handle(Type &&item)
Definition: tpf_types.hpp:7795
void for_each_iterator(ContainerType &&container)
Definition: tpf_types.hpp:7820
void for_each_index(ContainerType &&container)
Definition: tpf_types.hpp:7838
#define Tpf_ThrowDebugException(debug_message)
Throw a debug_exception with message as argument.
Definition: tpf_types.hpp:1416