astrotypes  0.0
TypeTraits.h
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2018 PulsarearchSoft, Chris Williams, and the SKA Organisation
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "oftware"), to deal
8  * in theoftware without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of theoftware, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of theoftware.
15  *
16  * THEOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIE OF MERCHANTABILITY,
18  * FITNES FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHOR OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWIE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THEOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  *OFTWARE.
23  */
24 #ifndef PS_ASTROTYPES_MULTIARRAY_TYPETRAITS_H
25 #define PS_ASTROTYPES_MULTIARRAY_TYPETRAITS_H
26 #include <type_traits>
27 #include <tuple>
28 
29 #include <type_traits>
30 
31 
32 namespace pss {
33 namespace astrotypes {
34 
38 template<typename T1, typename T2, typename... Ts>
39 struct logical_and : public logical_and<typename logical_and<T1, T2>::type, Ts...>::type
40 {};
41 
42 template<typename T>
43 struct logical_and<T, T> : public std::true_type
44 {};
45 
46 template<typename T1, typename T2>
47 struct logical_and<T1, T2> : public std::false_type
48 {};
49 
56 
70 template<typename T, typename Dimension>
71 struct has_dimension : public std::false_type
72 {
73 };
74 
75 template<typename T >
76 struct has_dimension<T, T> : public std::true_type
77 {
78 };
79 
83 template<typename T, typename Dimension, typename... Dimensions>
84 struct has_dimensions : public logical_and<typename has_dimension<T, Dimension>::type, typename has_dimensions<T, Dimensions...>::type>
85 {
86 };
87 
88 template<typename T, typename Dimension>
89 struct has_dimensions<T, Dimension> : public has_dimension<T, Dimension>
90 {
91 };
92 
106 template<typename T, typename... Dimensions>
107 struct has_exact_dimensions : public std::false_type
108 {
109 };
110 
114 template<typename T1, typename T2, typename... Ts>
115 struct list_has_type : public std::conditional<std::is_same<T1, T2>::value || list_has_type<T1, Ts...>::value, std::true_type, std::false_type>::type
116 { };
117 
118 template<typename T>
119 struct list_has_type<T, T> : public std::true_type
120 {};
121 
122 template<typename T1, typename T2>
123 struct list_has_type<T1, T2> : public std::false_type
124 {};
125 
129 template<typename Tuple, typename T2>
130 struct has_type : std::false_type
131 { };
132 
133 template<typename T, typename... Ts>
134 struct has_type<std::tuple<T, Ts...>, T> : public std::true_type
135 {};
136 
137 template<typename T, typename T2, typename... Ts>
138 struct has_type<std::tuple<T2, Ts...>, T> : public has_type<std::tuple<Ts...>, T>::type
139 {};
140 
141 template<typename T1, typename T2, typename... Ts>
142 struct has_types : public logical_and<typename has_type<T1, T2>::type, has_type<T1, Ts>...>::type
143 {
144 };
145 
146 template<typename T1, typename T2>
147 struct has_types<T1, T2> : public has_type<T1, T2>::type
148 {
149 };
150 
158 template<typename Tuple, typename T2>
159 struct find_type;
160 
161 template<typename T, typename... Ts>
162 struct find_type<std::tuple<T, Ts...>, T>
163 {
164  static const std::size_t value = 0;
165 };
166 
167 template<typename T, typename T2, typename... Ts>
168 struct find_type<std::tuple<T2, Ts...>, T>
169 {
170  static const std::size_t value = 1 + find_type<std::tuple<Ts...>, T>::value;
171 };
172 
182 template<typename Tuple, typename T, typename... Ts>
183 struct insert_type;
184 
185 template<typename... TupleTs, typename T1, typename T2, typename... Ts>
186 struct insert_type<std::tuple<TupleTs...>, T1, T2, Ts...>
187 {
188  inline
189  static void exec(std::tuple<TupleTs...>& tuple, T1 const& value, T2 const& value2, Ts const&... values)
190  {
191  insert_type<std::tuple<TupleTs...>, T1>::exec(tuple, value);
192  insert_type<std::tuple<TupleTs...>, T2, Ts...>::exec(tuple, value2, values...);
193  }
194 };
195 
196 template<typename... TupleTs, typename T>
197 struct insert_type<std::tuple<TupleTs...>, T>
198 {
199  inline
200  static void exec(std::tuple<TupleTs...>& tuple, T const& value)
201  {
202  static_assert(has_type<std::tuple<TupleTs...>, T>::value, "Type does not exist in tuple");
203  std::get<find_type<std::tuple<TupleTs...>, T>::value>(tuple) = value;
204  }
205 };
206 
207 template<typename... TupleTs, typename... Ts>
208 void tuple_insert_type(std::tuple<TupleTs...>& tuple, Ts const&...values)
209 {
210  insert_type<std::tuple<TupleTs...>, typename std::remove_reference<Ts>::type...>::exec(tuple, values...);
211 }
212 
219 template<typename Tuple, typename SrcTuple, std::size_t Index=std::tuple_size<SrcTuple>::value>
220 struct tuple_copy_helper : tuple_copy_helper<Tuple, SrcTuple, Index-1>
221 {
222  tuple_copy_helper(Tuple& tuple, SrcTuple const& src_tuple)
223  : tuple_copy_helper<Tuple, SrcTuple, Index-1>(tuple, src_tuple)
224  {
225  insert_type<Tuple, typename std::tuple_element<Index-1, SrcTuple>::type>::exec(tuple, std::get<Index-1>(src_tuple));
226  }
227 };
228 
229 template<typename Tuple, typename SrcTuple>
230 struct tuple_copy_helper<Tuple, SrcTuple, 0>
231 {
232  tuple_copy_helper(Tuple&, SrcTuple const&) {}
233 };
234 
235 template<typename... TupleTs, typename... Ts>
236 void tuple_copy(std::tuple<TupleTs...> const& src_tuple, std::tuple<Ts...>& dst_tuple)
237 {
238  tuple_copy_helper<std::tuple<Ts...>, std::tuple<TupleTs...>>(dst_tuple, src_tuple);
239 }
240 
245 template<typename Tuple1, typename Tuple2s>
247 
248 template<typename... Tuple1s>
249 struct unique_tuple<std::tuple<Tuple1s...>, std::tuple<>>
250 {
251  typedef std::tuple<Tuple1s...> type;
252 };
253 
254 template<typename... Tuple1s, typename T, typename... Tuple2s>
255 struct unique_tuple<std::tuple<Tuple1s...>, std::tuple<T, Tuple2s...>>
256 {
257  typedef typename unique_tuple<typename std::conditional<has_type<std::tuple<Tuple1s...>, T>::value
258  , std::tuple<Tuple1s...>, std::tuple<Tuple1s..., T>>::type
259  , std::tuple<Tuple2s...>>::type type;
260 };
261 
268 template<typename Tuple1, typename Tuple2>
270 {
272 
273  inline static
274  type exec(Tuple1 const& tuple1, Tuple2 const& tuple2)
275  {
276  type r;
277  tuple_copy(tuple2, r);
278  tuple_copy(tuple1, r);
279  return r;
280  }
281 };
282 
283 template<typename Tuple1, typename Tuple2>
284 typename merge_tuples_type<Tuple1, Tuple2>::type
285 merge_tuples(Tuple1 const& tuple1, Tuple2 const& tuple2)
286 {
287  return merge_tuples_type<Tuple1, Tuple2>::exec(tuple1, tuple2);
288 }
289 
293 template<typename Tuple1, typename... Tuples>
294 struct join_tuples;
295 
296 template<typename... Tuple1, typename... Tuple2>
297 struct join_tuples<std::tuple<Tuple1...>, std::tuple<Tuple2...>>
298 {
299  typedef std::tuple<Tuple1..., Tuple2...> type;
300 };
301 
302 template<typename... Tuple1, typename... Tuple2, typename... Tuples>
303 struct join_tuples<std::tuple<Tuple1...>, std::tuple<Tuple2...>, Tuples...>
304 {
305  typedef typename join_tuples<std::tuple<Tuple1...>, typename join_tuples<std::tuple<Tuple2...>, Tuples...>::type>::type type;
306 };
307 
309 // @brief produces a tuple that contains all elements in Tuple1 that are not in Tuple2
310 // --------------------------------------------------------------------
311 template<typename Tuple1, typename Tuple2>
312 struct tuple_diff;
313 
314 template<typename T, typename... Tuple2>
315 struct tuple_diff<std::tuple<T>, std::tuple<Tuple2...>>
316 {
317  typedef typename std::conditional<has_type<std::tuple<Tuple2...>, T>::value,
318  std::tuple<>,
319  std::tuple<T>>::type type;
320 };
321 
322 template<typename T, typename... Tuple1, typename... Tuple2>
323 struct tuple_diff<std::tuple<T, Tuple1...>, std::tuple<Tuple2...>>
324 {
325  private:
326  typedef tuple_diff<std::tuple<Tuple1...>, std::tuple<Tuple2...>> Next;
327 
328  public:
329  typedef typename std::conditional<has_type<std::tuple<Tuple2...>, T>::value,
330  typename Next::type,
331  typename join_tuples<std::tuple<T>, typename Next::type>::type>::type type;
332 };
333 
334 } // namespace astrotypes
335 } // namespace pss
336 
337 #endif // PS_ASTROTYPES_MULTIARRAY_TYPETRAITS_H
std::conditional< has_type< std::tuple< Tuple2...>, T >::value, typename Next::type, typename join_tuples< std::tuple< T >, typename Next::type >::type >::type type
Definition: TypeTraits.h:331
insert values into a tuple
Definition: TypeTraits.h:183
produces a tuple type with params form all provided Tuples
Definition: TypeTraits.h:294
unique_tuple< Tuple1, Tuple2 >::type type
Definition: TypeTraits.h:271
void tuple_insert_type(std::tuple< TupleTs...> &tuple, Ts const &...values)
Definition: TypeTraits.h:208
static type exec(Tuple1 const &tuple1, Tuple2 const &tuple2)
Definition: TypeTraits.h:274
produces an extended tuple type with params form all provided tuples All types must be unique...
Definition: TypeTraits.h:269
static void exec(std::tuple< TupleTs...> &tuple, T const &value)
Definition: TypeTraits.h:200
helper class to perform a logical and on all the arguments
Definition: TypeTraits.h:39
STL namespace.
join_tuples< std::tuple< Tuple1...>, typename join_tuples< std::tuple< Tuple2...>, Tuples...>::type >::type type
Definition: TypeTraits.h:305
create a tuple with types from both tuples, but guaranting that any type will appear only once ...
Definition: TypeTraits.h:246
std::conditional< has_type< std::tuple< Tuple2...>, T >::value, std::tuple<>, std::tuple< T > >::type type
Definition: TypeTraits.h:319
tuple_copy_helper(Tuple &tuple, SrcTuple const &src_tuple)
Definition: TypeTraits.h:222
copy the matching elements (by type) from one tuple into anothe
Definition: TypeTraits.h:220
return true if the Dimensions provided match exactly those of the structure T (including order) ...
Definition: TypeTraits.h:107
void tuple_copy(std::tuple< TupleTs...> const &src_tuple, std::tuple< Ts...> &dst_tuple)
Definition: TypeTraits.h:236
return true if the all Dimensions provided are represented in the structure
Definition: TypeTraits.h:84
unique_tuple< typename std::conditional< has_type< std::tuple< Tuple1s...>, T >::value, std::tuple< Tuple1s...>, std::tuple< Tuple1s..., T > >::type, std::tuple< Tuple2s...> >::type type
Definition: TypeTraits.h:259
return true if the Dimension is represented in the structure
Definition: TypeTraits.h:71
static void exec(std::tuple< TupleTs...> &tuple, T1 const &value, T2 const &value2, Ts const &...values)
Definition: TypeTraits.h:189
merge_tuples_type< Tuple1, Tuple2 >::type merge_tuples(Tuple1 const &tuple1, Tuple2 const &tuple2)
Definition: TypeTraits.h:285