DUNE-ACFEM (unstable)

compare.hh
1#ifndef __DUNE_ACFEM_MPL_COMPARE_HH__
2#define __DUNE_ACFEM_MPL_COMPARE_HH__
3
4#include <tuple>
5#include <array>
6
7#include "../common/types.hh"
8#include "accumulate.hh"
9#include "sort.hh"
10
11namespace Dune {
12
13 namespace ACFem {
14
28 template<class T0, T0 t0, class T1, T1 t1>
29 constexpr bool operator==(Constant<T0, t0>, Constant<T1, t1>)
30 {
31 return t0 == t1;
32 }
33
34 template<class T0, T0 t0, class T1, T1 t1>
35 constexpr bool operator!=(Constant<T0, t0>, Constant<T1, t1>)
36 {
37 return t0 != t1;
38 }
39
40 template<class T0, T0 t0, class T1, T1 t1>
41 constexpr bool operator<=(Constant<T0, t0>, Constant<T1, t1>)
42 {
43 return t0 <= t1;
44 }
45
46 template<class T0, T0 t0, class T1, T1 t1>
47 constexpr bool operator<(Constant<T0, t0>, Constant<T1, t1>)
48 {
49 return t0 < t1;
50 }
51
52 template<class T0, T0 t0, class T1, T1 t1>
53 constexpr bool operator>(Constant<T0, t0>, Constant<T1, t1>)
54 {
55 return t0 > t1;
56 }
57
58 template<class T0, T0 t0, class T1, T1 t1>
59 constexpr bool operator>=(Constant<T0, t0>, Constant<T1, t1>)
60 {
61 return t0 >= t1;
62 }
63
64 template<class T0, T0 V0, class T1, T1... V1>
65 constexpr bool operator==(Constant<T0, V0>, Sequence<T1, V1...>)
66 {
67 return (... && (V0 == V1));
68 }
69
70 template<class T0, T0 V0, class T1, T1... V1>
71 constexpr bool operator!=(Constant<T0, V0>, Sequence<T1, V1...>)
72 {
73 return (... || (V0 != V1));
74 }
75
76 template<class T0, T0 V0, class T1, T1... V1>
77 constexpr bool operator<=(Constant<T0, V0>, Sequence<T1, V1...>)
78 {
79 return (... && (V0 <= V1));
80 }
81
82 template<class T0, T0 V0, class T1, T1... V1>
83 constexpr bool operator<(Constant<T0, V0>, Sequence<T1, V1...>)
84 {
85 return (... && (V0 < V1));
86 }
87
88 template<class T0, T0 V0, class T1, T1... V1>
89 constexpr bool operator>=(Constant<T0, V0>, Sequence<T1, V1...>)
90 {
91 return (... && (V0 >= V1));
92 }
93
94 template<class T0, T0 V0, class T1, T1... V1>
95 constexpr bool operator>(Constant<T0, V0>, Sequence<T1, V1...>)
96 {
97 return (... && (V0 > V1));
98 }
99
100 template<class T0, T0... V0, class T1, T1 V1>
101 constexpr bool operator==(Sequence<T0, V0...>, Constant<T1, V1>)
102 {
103 return (... && (V0 == V1));
104 }
105
106 template<class T0, T0... V0, class T1, T1 V1>
107 constexpr bool operator!=(Sequence<T0, V0...>, Constant<T1, V1>)
108 {
109 return (... || (V0 != V1));
110 }
111
112 template<class T0, T0... V0, class T1, T1 V1>
113 constexpr bool operator<=(Sequence<T0, V0...>, Constant<T1, V1>)
114 {
115 return (... && (V0 <= V1));
116 }
117
118 template<class T0, T0... V0, class T1, T1 V1>
119 constexpr bool operator<(Sequence<T0, V0...>, Constant<T1, V1>)
120 {
121 return (... && (V0 < V1));
122 }
123
124 template<class T0, T0... V0, class T1>
125 constexpr bool operator<(Sequence<T0, V0...>, T1 t1)
126 {
127 return (... && (V0 < t1));
128 }
129
130 template<class T0, T0... V0, class T1, T1 V1>
131 constexpr bool operator>=(Sequence<T0, V0...>, Constant<T1, V1>)
132 {
133 return (... && (V0 >= V1));
134 }
135
136 template<class T0, T0... V0, class T1, T1 V1>
137 constexpr bool operator>(Sequence<T0, V0...>, Constant<T1, V1>)
138 {
139 return (... && (V0 > V1));
140 }
141
142 template<class T0, T0... V0, class T1, T1... V1,
143 std::enable_if_t<sizeof...(V0) == sizeof...(V1), int> = 0>
144 constexpr bool operator==(Sequence<T0, V0...>, Sequence<T1, V1...>)
145 {
146 return (... && (V0 == V1));
147 }
148
149 template<class T0, T0... V0, class T1, T1... V1,
150 std::enable_if_t<sizeof...(V0) == sizeof...(V1), int> = 0>
151 constexpr bool operator!=(Sequence<T0, V0...>, Sequence<T1, V1...>)
152 {
153 return (... || (V0 != V1));
154 }
155
156 template<class T0, T0... V0, class T1, T1... V1,
157 std::enable_if_t<sizeof...(V0) == sizeof...(V1), int> = 0>
158 constexpr bool operator<=(Sequence<T0, V0...>, Sequence<T1, V1...>)
159 {
160 return (... && (V0 <= V1));
161 }
162
163 template<class T0, T0... V0, class T1, T1... V1,
164 std::enable_if_t<sizeof...(V0) == sizeof...(V1), int> = 0>
165 constexpr bool operator<(Sequence<T0, V0...>, Sequence<T1, V1...>)
166 {
167 return (... && (V0 < V1));
168 }
169
170 template<class T0, T0... V0, class T1, T1... V1,
171 std::enable_if_t<sizeof...(V0) == sizeof...(V1), int> = 0>
172 constexpr bool operator>=(Sequence<T0, V0...>, Sequence<T1, V1...>)
173 {
174 return (... && (V0 >= V1));
175 }
176
177 template<class T0, T0... V0, class T1, T1... V1,
178 std::enable_if_t<sizeof...(V0) == sizeof...(V1), int> = 0>
179 constexpr bool operator>(Sequence<T0, V0...>, Sequence<T1, V1...>)
180 {
181 return (... && (V0 > V1));
182 }
183
184 template<class T0, T0... V0, class T1, T1... V1,
185 std::enable_if_t<sizeof...(V0) != sizeof...(V1), int> = 0>
186 constexpr bool operator==(Sequence<T0, V0...>, Sequence<T1, V1...>)
187 {
188 return false;
189 }
190
191 template<class T0, T0... V0, class T1, T1... V1,
192 std::enable_if_t<sizeof...(V0) != sizeof...(V1), int> = 0>
193 constexpr bool operator!=(Sequence<T0, V0...>, Sequence<T1, V1...>)
194 {
195 return true;
196 }
197
198 template<class T0, T0... V0, class T1, T1... V1,
199 std::enable_if_t<sizeof...(V0) != sizeof...(V1), int> = 0>
200 constexpr bool operator<=(Sequence<T0, V0...>, Sequence<T1, V1...>)
201 {
202 return false;
203 }
204
205 template<class T0, T0... V0, class T1, T1... V1,
206 std::enable_if_t<sizeof...(V0) != sizeof...(V1), int> = 0>
207 constexpr bool operator<(Sequence<T0, V0...>, Sequence<T1, V1...>)
208 {
209 return false;
210 }
211
212 template<class T0, T0... V0, class T1, T1... V1,
213 std::enable_if_t<sizeof...(V0) != sizeof...(V1), int> = 0>
214 constexpr bool operator>=(Sequence<T0, V0...>, Sequence<T1, V1...>)
215 {
216 return false;
217 }
218
219 template<class T0, T0... V0, class T1, T1... V1,
220 std::enable_if_t<sizeof...(V0) != sizeof...(V1), int> = 0>
221 constexpr bool operator>(Sequence<T0, V0...>, Sequence<T1, V1...>)
222 {
223 return false;
224 }
225
226 namespace {
227
229 template<class T1, class T2, class F, class S,
230 std::enable_if_t<size<T1>() != size<T2>(), int> = 0>
231 constexpr bool tupleCompareHelper(T1&&, T2&&, S, F&& f)
232 {
233 return false;
234 }
235
237 template<class T1, class T2, class F, std::size_t... I>
238 constexpr bool tupleCompareHelper(T1&& t1, T2&& t2, IndexSequence<I...>, F&& f)
239 {
240 return (... && f(get<I>(std::forward<T1>(t1)), get<I>(std::forward<T2>(t2))));
241 }
242
243 } // NS anonymous
244
245 template<class T1, class T2, std::enable_if_t<AllowsGet<T1>::value && AllowsGet<T2>::value, int> = 0>
246 constexpr bool operator==(T1&& t1, T2&& t2)
247 {
248 return tupleCompareHelper(std::forward<T1>(t1), std::forward<T2>(t2), MakeSequenceFor<T1>{}, [](auto&& a, auto&& b) { return a == b; });
249 }
250
251 template<class T1, class T2, std::enable_if_t<AllowsGet<T1>::value && AllowsGet<T2>::value, int> = 0>
252 constexpr bool operator!=(T1&& t1, T2&& t2)
253 {
254 return !(t1 == t2);
255 }
256
257 template<class T1, class T2, std::enable_if_t<AllowsGet<T1>::value && AllowsGet<T2>::value, int> = 0>
258 constexpr bool operator<=(T1&& t1, T2&& t2)
259 {
260 return tupleCompareHelper(std::forward<T1>(t1), std::forward<T2>(t2), MakeSequenceFor<T1>{}, [](auto&& a, auto&& b) { return a <= b; });
261 }
262
263 template<class T1, class T2, std::enable_if_t<AllowsGet<T1>::value && AllowsGet<T2>::value, int> = 0>
264 constexpr bool operator<(T1&& t1, T2&& t2)
265 {
266 return tupleCompareHelper(std::forward<T1>(t1), std::forward<T2>(t2), MakeSequenceFor<T1>{}, [](auto&& a, auto&& b) { return a < b; });
267 }
268
269 template<class T1, class T2, std::enable_if_t<AllowsGet<T1>::value && AllowsGet<T2>::value, int> = 0>
270 constexpr bool operator>=(T1&& t1, T2&& t2)
271 {
272 return tupleCompareHelper(std::forward<T1>(t1), std::forward<T2>(t2), MakeSequenceFor<T1>{}, [](auto&& a, auto&& b) { return a >= b; });
273 }
274
275 template<class T1, class T2, std::enable_if_t<AllowsGet<T1>::value && AllowsGet<T2>::value, int> = 0>
276 constexpr bool operator>(T1&& t1, T2&& t2)
277 {
278 return tupleCompareHelper(std::forward<T1>(t1), std::forward<T2>(t2), MakeSequenceFor<T1>{}, [](auto&& a, auto&& b) { return a > b; });
279 }
280
284 template<class T, T T0, T... Ts>
286 {
287 return (... && (T0 == Ts));
288 }
289
292 template<class T>
293 constexpr bool isConstant(Sequence<T>)
294 {
295 return true;
296 }
297
301 template<class T, T I, T... Rest>
303 {
304 return seq == MakeSequence<T, sizeof...(Rest)+1, I>{};
305 }
306
310 template<class T>
312 {
313 return true;
314 }
315
317 template<template<std::size_t, std::size_t> class DoSwap, class T, T... Ts>
319 {
320 return IsSortedV<Sequence<T, Ts...>, DoSwap>;
321 }
322
324 template<class T, T... Ts>
325 constexpr bool isSorted(Sequence<T, Ts...> seq)
326 {
327 return isSorted<DefaultDoSwap>(seq);
328 }
329
333 template<class T, T... V>
334 constexpr bool isSimple(Sequence<T, V...> seq)
335 {
336 return seq == MakeSequence<T, sizeof...(V)>{};
337 }
338
342 template<std::size_t Align, class T, T V0, T... V>
344 {
345 constexpr std::size_t start = V0/Align*Align;
346 constexpr std::size_t size = (1+sizeof...(V))/Align*Align;
347
348 return std::is_same<MakeSequence<T, size, start>, Sequence<T, V0, V...> >::value;
349 }
350
351 template<std::size_t Align, class T>
352 constexpr bool isAlignedBlock(Sequence<T>, IndexConstant<Align> = IndexConstant<Align>{})
353 {
354 return true;
355 }
356
357
361 template<std::size_t... Ind>
363 {
364 constexpr std::size_t size = sizeof...(Ind);
365 return (... &&(Ind >= 0)) && (... && (Ind < size)) && ((0 + ... + Ind) == (size-1)*size/2);
366 }
367
369 template<class... T>
370 constexpr auto isIntegralPack(T&&...)
371 {
372 return BoolConstant<(... && std::is_integral<std::decay_t<T> >{})>{};
373 }
374
376 template<class... T>
377 using IsIntegralPack = decltype(isIntegralPack(std::declval<T>()...));
378
380 template<class T, std::size_t N>
381 constexpr auto isIntegralTuple(const std::array<T, N>&)
382 {
383 return std::is_integral<T>{};
384 }
385
387 template<class T1, class T2>
388 constexpr auto isIntegralTuple(const std::pair<T1, T2>&)
389 {
390 return IsIntegralPack<T1, T2>{};
391 }
392
394 template<class... T>
395 constexpr auto isIntegralTuple(const std::tuple<T...>&)
396 {
397 return IsIntegralPack<T...>{};
398 }
399
401 template<class T>
402 using IsIntegralTuple = decltype(isIntegralTuple(std::declval<T>()));
403
404 namespace {
405 template<class Tuple>
406 constexpr bool isConstantTupleHelper(Tuple&&, IndexSequence<>)
407 {
408 return true;
409 }
410
411 template<class Tuple, std::size_t First, std::size_t... Rest>
412 constexpr bool isConstantTupleHelper(Tuple&& t, IndexSequence<First, Rest...>)
413 {
414 return (... && (0 == get<First>(std::forward<Tuple>(t)) - get<Rest>(std::forward<Tuple>(t))));
415 }
416
417 }
418
420 template<class Tuple, std::enable_if_t<IsTupleLike<Tuple>::value, int> = 0>
421 constexpr bool isConstant(Tuple&& t)
422 {
423 return isConstantTupleHelper(std::forward<Tuple>(t), MakeIndexSequence<size<Tuple>()>{});
424 }
425
426 namespace {
427
428 template<class Tuple, template<class...> class Predicate,
429 std::size_t start = 0,
430 std::size_t size = size<Tuple>()>
431 struct PredicateMatchHelper
432 : public ConditionalType<Predicate<TupleElement<start, Tuple> >::value,
433 TrueType,
434 PredicateMatchHelper<Tuple, Predicate, start+1> >
435 {
436 static constexpr std::ptrdiff_t index_ =
437 Predicate<TupleElement<start, Tuple> >::value ? start : PredicateMatchHelper<Tuple, Predicate, start+1>::index_;
438 };
439
440 template<class Tuple, template<class...> class Predicate, std::size_t size>
441 struct PredicateMatchHelper<Tuple, Predicate, size, size>
442 : FalseType
443 {
444 static constexpr std::ptrdiff_t index_ = -1;
445 };
446
447 }
448
453 template<class Tuple, template<class...> class Predicate, class... Rest>
454 using PredicateMatch = PredicateMatchHelper<std::decay_t<Tuple>, PredicateProxy<Predicate, Rest...>::template ForwardFirst>;
455
457 template<template<class...> class Predicate, class... T>
458 using IndexOfMatching = IndexConstant<PredicateMatch<std::tuple<T...>, Predicate>::index_>;
459
461 template<template<class...> class Predicate, class... T>
462 using AnyIs = BoolConstant<(... || Predicate<T>::value)>;
463
465 template<template<class...> class Predicate, class... T>
466 using AllAre = BoolConstant<(... && Predicate<T>::value)>;
467
469 template<std::size_t N, template<class...> class Predicate, class... T>
470 using NthIs = Predicate<TypePackElement<N, T...> >;
471
473
475
476 } // ACFem::
477
478} // Dune::
479
480#endif // __DUNE_ACFEM_MPL_COMPARE_HH__
constexpr std::size_t size()
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:73
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
typename BuildSequence< T, N, Offset, Stride, Repeat >::Type MakeSequence
Make an index sequence with an optional offset.
Definition: makesequence.hh:197
Predicate< TypePackElement< N, T... > > NthIs
Instantiates to Predicate applied to the N-th element of T...
Definition: compare.hh:470
decltype(isIntegralTuple(std::declval< T >())) IsIntegralTuple
Decide whether the given tuple contains only integral types.
Definition: compare.hh:402
constexpr auto isIntegralTuple(const std::array< T, N > &)
Decide whether the given tuple contains only integral types.
Definition: compare.hh:381
BoolConstant<(... &&Predicate< T >::value)> AllAre
TrueType if all types match the predicate.
Definition: compare.hh:466
constexpr bool isConsecutive(Sequence< T, I, Rest... > seq)
Definition: compare.hh:302
IndexConstant< PredicateMatch< std::tuple< T... >, Predicate >::index_ > IndexOfMatching
Obtain the index of the first matching tuple type.
Definition: compare.hh:458
constexpr bool isSimple(Sequence< T, V... > seq)
Definition: compare.hh:334
constexpr bool isPermutation(IndexSequence< Ind... >=IndexSequence< Ind... >{})
Definition: compare.hh:362
constexpr bool isConstant(Sequence< T, T0, Ts... >)
Definition: compare.hh:285
decltype(isIntegralPack(std::declval< T >()...)) IsIntegralPack
Decide whether the given parameter pack contains only integral types.
Definition: compare.hh:377
constexpr bool isAlignedBlock(Sequence< T, V0, V... >, IndexConstant< Align >=IndexConstant< Align >{})
Definition: compare.hh:343
BoolConstant<(...||Predicate< T >::value)> AnyIs
TrueType if any type matches the predicate.
Definition: compare.hh:462
constexpr auto isIntegralPack(T &&...)
Decide whether the given parameter pack contains only integral types.
Definition: compare.hh:370
constexpr bool isSorted(Sequence< T, Ts... >)
Definition: compare.hh:318
PredicateMatchHelper< std::decay_t< Tuple >, PredicateProxy< Predicate, Rest... >::template ForwardFirst > PredicateMatch
Apply the predicate to each tuple type in turn.
Definition: compare.hh:454
Sequence< std::size_t, V... > IndexSequence
Sequence of std::size_t values.
Definition: types.hh:64
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
std::integer_sequence< T, V... > Sequence
Sequence of any type of integer values.
Definition: types.hh:56
Constant< std::size_t, V > IndexConstant
Short-cut for integral constant of type std::size_t.
Definition: types.hh:44
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
Wrap the given predicate class F into another one with spcial requirements.
Definition: types.hh:218
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Jun 19, 23:17, 2026)