1 #pragma once
2 
3 #include <type_traits>
4 #include <iterator>
5 #include <iostream>
6 #include <fstream>
7 #include <mutex>
8 #include <stack>
9 #include <queue>
10 #include <vector>
11 #include <algorithm>
12 #include <memory>
13 #include <atomic>
14 #include <thread>
15 #include <future>
16 #include <functional>
17 #include <map>
18 #include <set>
19 #include <unordered_map>
20 #include <unordered_set>
21 #include <sstream>
22 #include <list>
23 #include <forward_list>
24 #include <numeric>
25 #include <random>
26 #include <iomanip>
27 #include <cassert>
28 #include <cmath>
29 #include <array>
30 #include <cstring>
31 #include <variant>
32 #include <optional>
33 //#include <any>
34 
35 namespace tf {
36 
37 //-----------------------------------------------------------------------------
38 // Traits
39 //-----------------------------------------------------------------------------
40 
41 // Struct: dependent_false
42 template <typename... T>
43 struct dependent_false {
44   static constexpr bool value = false;
45 };
46 
47 template <typename... T>
48 constexpr auto dependent_false_v = dependent_false<T...>::value;
49 
50 //-----------------------------------------------------------------------------
51 // Move-On-Copy
52 //-----------------------------------------------------------------------------
53 
54 // Struct: MoveOnCopyWrapper
55 template <typename T>
56 struct MoC {
57 
MoCtf::MoC58   MoC(T&& rhs) : object(std::move(rhs)) {}
MoCtf::MoC59   MoC(const MoC& other) : object(std::move(other.object)) {}
60 
gettf::MoC61   T& get() { return object; }
62 
63   mutable T object;
64 };
65 
66 template <typename T>
make_moc(T && m)67 auto make_moc(T&& m) {
68   return MoC<T>(std::forward<T>(m));
69 }
70 
71 //-----------------------------------------------------------------------------
72 // Visitors.
73 //-----------------------------------------------------------------------------
74 
75 //// Overloadded.
76 //template <typename... Ts>
77 //struct Visitors : Ts... {
78 //  using Ts::operator()... ;
79 //};
80 //
81 //template <typename... Ts>
82 //Visitors(Ts...) -> Visitors<Ts...>;
83 
84 // ----------------------------------------------------------------------------
85 // std::variant
86 // ----------------------------------------------------------------------------
87 template <typename T, typename>
88 struct get_index;
89 
90 template <size_t I, typename... Ts>
91 struct get_index_impl {};
92 
93 template <size_t I, typename T, typename... Ts>
94 struct get_index_impl<I, T, T, Ts...> : std::integral_constant<size_t, I>{};
95 
96 template <size_t I, typename T, typename U, typename... Ts>
97 struct get_index_impl<I, T, U, Ts...> : get_index_impl<I+1, T, Ts...>{};
98 
99 template <typename T, typename... Ts>
100 struct get_index<T, std::variant<Ts...>> : get_index_impl<0, T, Ts...>{};
101 
102 template <typename T, typename... Ts>
103 constexpr auto get_index_v = get_index<T, Ts...>::value;
104 
105 // ----------------------------------------------------------------------------
106 // is_pod
107 //-----------------------------------------------------------------------------
108 template <typename T>
109 struct is_pod {
110   static const bool value = std::is_trivial_v<T> &&
111                             std::is_standard_layout_v<T>;
112 };
113 
114 template <typename T>
115 constexpr bool is_pod_v = is_pod<T>::value;
116 
117 // ----------------------------------------------------------------------------
118 // unwrap_reference
119 // ----------------------------------------------------------------------------
120 
121 template <class T>
122 struct unwrap_reference { using type = T; };
123 
124 template <class U>
125 struct unwrap_reference<std::reference_wrapper<U>> { using type = U&; };
126 
127 template<class T>
128 using unwrap_reference_t = typename unwrap_reference<T>::type;
129 
130 template< class T >
131 struct unwrap_ref_decay : unwrap_reference<std::decay_t<T>> {};
132 
133 template<class T>
134 using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
135 
136 // ----------------------------------------------------------------------------
137 // stateful iterators
138 // ----------------------------------------------------------------------------
139 
140 // STL-styled iterator
141 template <typename B, typename E>
142 struct stateful_iterator {
143 
144   using TB = std::decay_t<unwrap_ref_decay_t<B>>;
145   using TE = std::decay_t<unwrap_ref_decay_t<E>>;
146 
147   static_assert(std::is_same_v<TB, TE>, "decayed iterator types must match");
148 
149   using type = TB;
150 };
151 
152 template <typename B, typename E>
153 using stateful_iterator_t = typename stateful_iterator<B, E>::type;
154 
155 // raw integral index
156 template <typename B, typename E, typename S>
157 struct stateful_index {
158 
159   using TB = std::decay_t<unwrap_ref_decay_t<B>>;
160   using TE = std::decay_t<unwrap_ref_decay_t<E>>;
161   using TS = std::decay_t<unwrap_ref_decay_t<S>>;
162 
163   static_assert(
164     std::is_integral_v<TB>, "decayed beg index must be an integral type"
165   );
166 
167   static_assert(
168     std::is_integral_v<TE>, "decayed end index must be an integral type"
169   );
170 
171   static_assert(
172     std::is_integral_v<TS>, "decayed step must be an integral type"
173   );
174 
175   static_assert(
176     std::is_same_v<TB, TE> && std::is_same_v<TE, TS>,
177     "decayed index and step types must match"
178   );
179 
180   using type = TB;
181 };
182 
183 template <typename B, typename E, typename S>
184 using stateful_index_t = typename stateful_index<B, E, S>::type;
185 
186 
187 }  // end of namespace tf. ----------------------------------------------------
188 
189 
190 
191