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>;