Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <functional>
7 : #include <limits>
8 : #include <pup.h>
9 : #include <type_traits>
10 : #include <utility>
11 :
12 : /// \ingroup TimeGroup
13 : /// Implementation of \ref evolution_less, \ref evolution_greater,
14 : /// \ref evolution_less_equal, and \ref evolution_greater_equal.
15 : ///
16 : /// This should only be used through the named aliases, but provides
17 : /// the documentation of the members.
18 : /// @{
19 : template <typename T, template <typename> typename Comparator>
20 1 : struct evolution_comparator {
21 0 : bool time_runs_forward = true;
22 0 : constexpr bool operator()(const T& x, const T& y) const {
23 : return time_runs_forward ? Comparator<T>{}(x, y) : Comparator<T>{}(y, x);
24 : }
25 :
26 : /// Provides an infinite (in the sense of
27 : /// std::numeric_limits::infinity()) value that compares greater
28 : /// than any other value in the evolution ordering.
29 : template <typename U = T>
30 1 : constexpr U infinity() const {
31 : static_assert(std::numeric_limits<U>::has_infinity);
32 : return time_runs_forward ? std::numeric_limits<U>::infinity()
33 : : -std::numeric_limits<U>::infinity();
34 : }
35 :
36 : // NOLINTNEXTLINE(google-runtime-references)
37 0 : void pup(PUP::er& p) { p | time_runs_forward; }
38 : };
39 :
40 : template <template <typename> typename Comparator>
41 0 : struct evolution_comparator<void, Comparator> {
42 0 : bool time_runs_forward = true;
43 :
44 : template <typename T, typename U>
45 0 : constexpr decltype(auto) operator()(T&& t, U&& u) const {
46 : static_assert(std::is_same_v<decltype(Comparator<void>{}(
47 : std::forward<T>(t), std::forward<U>(u))),
48 : decltype(Comparator<void>{}(
49 : std::forward<U>(u), std::forward<T>(t)))>,
50 : "The return types of operators used in evolution comparators "
51 : "must be symmetric in their arguments.");
52 : return time_runs_forward
53 : ? Comparator<void>{}(std::forward<T>(t), std::forward<U>(u))
54 : : Comparator<void>{}(std::forward<U>(u), std::forward<T>(t));
55 : }
56 :
57 : /// \copydoc evolution_comparator::infinity
58 : template <typename U>
59 1 : constexpr U infinity() const {
60 : static_assert(std::numeric_limits<U>::has_infinity);
61 : return time_runs_forward ? std::numeric_limits<U>::infinity()
62 : : -std::numeric_limits<U>::infinity();
63 : }
64 :
65 : // NOLINTNEXTLINE(google-runtime-references)
66 0 : void pup(PUP::er& p) { p | time_runs_forward; }
67 : };
68 : /// @}
69 :
70 : /// \ingroup TimeGroup
71 : /// Ordering functors that reverse their order when time runs
72 : /// backwards. See evolution_comparator and
73 : /// evolution_comparator<void,Comparator> for the provided interface.
74 : ///
75 : /// \see std::less
76 : template <typename T = void>
77 1 : using evolution_less = evolution_comparator<T, std::less>;
78 :
79 : /// \ingroup TimeGroup
80 : /// \copydoc evolution_less
81 : template <typename T = void>
82 1 : using evolution_greater = evolution_comparator<T, std::greater>;
83 :
84 : /// \ingroup TimeGroup
85 : /// \copydoc evolution_less
86 : template <typename T = void>
87 1 : using evolution_less_equal = evolution_comparator<T, std::less_equal>;
88 :
89 : /// \ingroup TimeGroup
90 : /// \copydoc evolution_less
91 : template <typename T = void>
92 1 : using evolution_greater_equal = evolution_comparator<T, std::greater_equal>;
|