File indexing completed on 2025-04-19 09:13:36
0001 #ifndef META_UTILS_H
0002 #define META_UTILS_H
0003
0004 #include <tuple>
0005
0006 #define CHECK_TEST_RES(pred) MetaUtils::check(pred, __PRETTY_FUNCTION__)
0007
0008
0009 namespace MetaUtils {
0010
0011
0012 template <class Func, std::size_t... Is>
0013 constexpr void staticForImpl(Func &&f,
0014 std::index_sequence<Is...>) {
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 ((void)f(std::integral_constant<std::size_t, Is>()), ...);
0025 }
0026
0027
0028
0029
0030
0031
0032
0033 template <size_t N, class Func>
0034 constexpr void staticFor(Func&& f) {
0035 staticForImpl(std::forward<Func>(f),
0036 std::make_index_sequence<N>{});
0037 }
0038
0039
0040
0041
0042 template<class...> struct conjunction : std::true_type { };
0043 template<class B1> struct conjunction<B1> : B1 { };
0044 template<class B1, class... Bn>
0045 struct conjunction<B1, Bn...>
0046 : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
0047
0048 struct nonesuch {
0049 ~nonesuch() = delete;
0050 nonesuch(nonesuch const&) = delete;
0051 void operator=(nonesuch const&) = delete;
0052 };
0053
0054 namespace operatorTraits {
0055 template<class T>
0056 using addition_assignment_t = decltype(std::declval<T&>() += std::declval<const T&>());
0057 }
0058
0059
0060
0061 namespace detail {
0062 template <class Default, class AlwaysVoid,
0063 template<class...> class Op, class... Args>
0064 struct detector {
0065 using value_t = std::false_type;
0066 using type = Default;
0067 };
0068
0069 template <class Default, template<class...> class Op, class... Args>
0070 struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
0071 using value_t = std::true_type;
0072 using type = Op<Args...>;
0073 };
0074
0075 }
0076
0077
0078 namespace {
0079 template <typename, template <typename...> class>
0080 struct is_instance_impl : public std::false_type {};
0081
0082 template <template <typename...> class U, typename...Ts>
0083 struct is_instance_impl<U<Ts...>, U> : public std::true_type {};
0084 }
0085
0086
0087 template <typename T, template <typename ...> class U>
0088 using is_instance = is_instance_impl<std::decay_t<T>, U>;
0089
0090 template <template<class...> class Op, class... Args>
0091 using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
0092
0093 template <template<class...> class Op, class... Args>
0094 using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type;
0095
0096 template <class Default, template<class...> class Op, class... Args>
0097 using detected_or = detail::detector<Default, void, Op, Args...>;
0098
0099 template <class Expected, template<class...> class Op, class... Args>
0100 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
0101
0102 template< template<class...> class Op, class... Args >
0103 constexpr bool is_detected_v = is_detected<Op, Args...>::value;
0104
0105
0106
0107
0108
0109 template <typename T, template <class U> class Concept>
0110 constexpr bool checkConcept() {
0111 return Concept<T>::checkResult::value;
0112 }
0113
0114 inline int check(bool pred, const char* funcName) {
0115 if (pred == false)
0116 std::clog << funcName << " FAILED\n";
0117 return (int)(pred ? EXIT_SUCCESS : EXIT_FAILURE);
0118 }
0119
0120
0121 namespace {
0122
0123 template <size_t, size_t>
0124 struct _tuple {
0125 template <typename T>
0126 static auto remove (const T& t) {
0127 return std::make_tuple(t);
0128 }
0129 };
0130
0131 template <size_t N>
0132 struct _tuple<N, N> {
0133 template <typename T>
0134 static std::tuple<> remove (const T&) {
0135 return {};
0136 }
0137 };
0138
0139 template<size_t N, typename T, size_t... Is>
0140 auto _removeTupleElement(const T& tup, std::index_sequence<Is...>) {
0141 return std::tuple_cat( _tuple<Is, N>::remove(std::get<Is>(tup))...);
0142 }
0143
0144 }
0145
0146 template<size_t I, typename... Ts>
0147 auto removeTupleElement(const std::tuple<Ts...>& tup) {
0148 return _removeTupleElement<I>(tup, std::make_index_sequence<sizeof...(Ts)>{});
0149 }
0150
0151
0152 }
0153
0154 #endif