23#if (defined(__cpp_constexpr) && __cpp_constexpr >= 201304L) ||\
24 (!defined(__cpp_constexpr) && __cplusplus >= 201402L)
25#define CPP_CXX14_CONSTEXPR constexpr
27#define CPP_CXX14_CONSTEXPR inline
30#ifndef CPP_CXX_INLINE_VARIABLES
31#ifdef __cpp_inline_variables
32#define CPP_CXX_INLINE_VARIABLES __cpp_inline_variables
34#elif defined(__clang__) && \
35 (__clang_major__ > 3 || __clang_major__ == 3 && __clang_minor__ == 9) && \
37#define CPP_CXX_INLINE_VARIABLES 201606L
39#define CPP_CXX_INLINE_VARIABLES __cplusplus
43#if defined(_MSC_VER) && !defined(__clang__)
45#define CPP_WORKAROUND_MSVC_895622
49#if CPP_CXX_INLINE_VARIABLES < 201606L
51#define CPP_INLINE_VARIABLE(type, name) \
54 constexpr auto &name = ::concepts::detail::static_const<type>::value; \
58#define CPP_INLINE_VAR inline
59#define CPP_INLINE_VARIABLE(type, name) \
60 inline constexpr type name{}; \
64#if CPP_CXX_INLINE_VARIABLES < 201606L
65#define CPP_DEFINE_CPO(type, name) \
68 constexpr auto &name = ::concepts::detail::static_const<type>::value; \
72#define CPP_DEFINE_CPO(type, name) \
75 inline constexpr type name{}; \
80#if defined(_MSC_VER) && !defined(__clang__)
81#define CPP_DIAGNOSTIC_PUSH __pragma(warning(push))
82#define CPP_DIAGNOSTIC_POP __pragma(warning(pop))
83#define CPP_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME
84#define CPP_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
85#define CPP_DIAGNOSTIC_IGNORE_CPP2A_COMPAT
87#if defined(__GNUC__) || defined(__clang__)
88#define CPP_PRAGMA(X) _Pragma(#X)
89#define CPP_DIAGNOSTIC_PUSH CPP_PRAGMA(GCC diagnostic push)
90#define CPP_DIAGNOSTIC_POP CPP_PRAGMA(GCC diagnostic pop)
91#define CPP_DIAGNOSTIC_IGNORE_PRAGMAS \
92 CPP_PRAGMA(GCC diagnostic ignored "-Wpragmas")
93#define CPP_DIAGNOSTIC_IGNORE(X) \
94 CPP_DIAGNOSTIC_IGNORE_PRAGMAS \
95 CPP_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas") \
96 CPP_PRAGMA(GCC diagnostic ignored X)
97#define CPP_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME \
98 CPP_DIAGNOSTIC_IGNORE("-Wunknown-warning-option") \
99 CPP_DIAGNOSTIC_IGNORE("-Winit-list-lifetime")
100#define CPP_DIAGNOSTIC_IGNORE_FLOAT_EQUAL CPP_DIAGNOSTIC_IGNORE("-Wfloat-equal")
101#define CPP_DIAGNOSTIC_IGNORE_CPP2A_COMPAT CPP_DIAGNOSTIC_IGNORE("-Wc++2a-compat")
103#define CPP_DIAGNOSTIC_PUSH
104#define CPP_DIAGNOSTIC_POP
105#define CPP_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME
106#define CPP_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
107#define CPP_DIAGNOSTIC_IGNORE_CPP2A_COMPAT
117 CPP_INLINE_VAR
constexpr bool is_movable_v =
118 std::is_object<T>::value &&
119 std::is_move_constructible<T>::value &&
120 std::is_move_assignable<T>::value;
125 static constexpr T
const value {};
128 constexpr T
const static_const<T>::value;
136 struct is_nothrow_swappable;
138 template<
typename T,
typename U>
139 struct is_swappable_with;
141 template<
typename T,
typename U>
142 struct is_nothrow_swappable_with;
144 template<
typename T,
typename U = T>
147 std::is_move_constructible<T>::value &&
148 std::is_assignable<T &, U>::value, T>
149 exchange(T &t, U &&u)
151 std::is_nothrow_move_constructible<T>::value &&
152 std::is_nothrow_assignable<T &, U>::value)
156 CPP_DIAGNOSTIC_IGNORE_INIT_LIST_LIFETIME
161 namespace adl_swap_detail
169 nope swap(T &, T &) =
delete;
171 template<
typename T, std::
size_t N>
172 nope swap(T (&)[N], T (&)[N]) =
delete;
174#ifdef CPP_WORKAROUND_MSVC_895622
178 template<
typename T,
typename U>
179 decltype(swap(std::declval<T>(), std::declval<U>())) try_adl_swap_(
int);
181 template<
typename T,
typename U>
182 nope try_adl_swap_(
long);
184 template<
typename T,
typename U = T>
185 CPP_INLINE_VAR
constexpr bool is_adl_swappable_v =
186 !META_IS_SAME(
decltype(adl_swap_detail::try_adl_swap_<T, U>(42)), nope);
191 template<
typename T,
typename U>
193 meta::if_c<is_adl_swappable_v<T, U>>
194 operator()(T &&t, U &&u)
const
195 noexcept(
noexcept(swap((T &&) t, (U &&) u)))
197 swap((T &&) t, (U &&) u);
205 !is_adl_swappable_v<T &> &&
206 detail::is_movable_v<T>>
207 operator()(T &a, T &b)
const
208 noexcept(
noexcept(b = concepts::exchange(a, (T &&) b)))
210 b = concepts::exchange(a, (T &&) b);
216 template<
typename T,
typename U, std::
size_t N>
219 !is_adl_swappable_v<T (&)[N], U (&)[N]> &&
220 is_swappable_with<T &, U &>::value>
221 operator()(T (&t)[N], U (&u)[N])
const
222 noexcept(is_nothrow_swappable_with<T &, U &>::value)
224 for(std::size_t i = 0; i < N; ++i)
231 template<
typename F0,
typename S0,
typename F1,
typename S1>
233 meta::if_c<is_swappable_with<F0, F1>::value && is_swappable_with<S0, S1>::value>
234 operator()(std::pair<F0, S0> &&left, std::pair<F1, S1> &&right)
const
236 is_nothrow_swappable_with<F0, F1>::value &&
237 is_nothrow_swappable_with<S0, S1>::value)
239 swap_fn()(
static_cast<std::pair<F0, S0> &&
>(left).first,
240 static_cast<std::pair<F1, S1> &&
>(right).first);
241 swap_fn()(
static_cast<std::pair<F0, S0> &&
>(left).second,
242 static_cast<std::pair<F1, S1> &&
>(right).second);
245 template<
typename ...Ts,
typename ...Us>
247 meta::if_c<meta::and_c<is_swappable_with<Ts, Us>::value...>::value>
248 operator()(std::tuple<Ts...> &&left, std::tuple<Us...> &&right)
const
252 static_cast<std::tuple<Ts...
> &&>(left),
253 static_cast<std::tuple<Us...
> &&>(right),
258 template<
typename... Ts>
259 static constexpr int ignore_unused(Ts &&...)
263 template<
typename T,
typename U, std::size_t ...Is>
267 (void) swap_fn::ignore_unused(
268 (swap_fn()(std::get<Is>(
static_cast<T &&
>(left)),
269 std::get<Is>(
static_cast<U &&
>(right))), 42)...);
273 template<
typename T,
typename U,
typename =
void>
274 struct is_swappable_with_
278 template<
typename T,
typename U>
279 struct is_swappable_with_<T, U,
meta::
void_<
280 decltype(swap_fn()(std::declval<T>(), std::declval<U>())),
281 decltype(swap_fn()(std::declval<U>(), std::declval<T>()))>>
285 template<
typename T,
typename U>
286 struct is_nothrow_swappable_with_
287 :
meta::bool_<noexcept(swap_fn()(std::declval<T>(), std::declval<U>())) &&
288 noexcept(swap_fn()(std::declval<U>(), std::declval<T>()))>
310 template<
typename T,
typename U>
312 : adl_swap_detail::is_swappable_with_<T, U>
316 template<
typename T,
typename U>
319 is_swappable_with<T, U>,
320 adl_swap_detail::is_nothrow_swappable_with_<T, U>>
337 CPP_DEFINE_CPO(adl_swap_detail::swap_fn, swap)
_t< detail::make_indices_< N, index_sequence< 0 >, detail::strategy_(1, N)> > make_index_sequence
Generate index_sequence containing integer constants [0,1,2,...,N-1].
Definition meta.hpp:473
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
_t< defer< detail::_and_< 0==sizeof...(Bs)>::template invoke, Bs... > > and_
Logically AND together all the integral constant-wrapped Boolean parameters, with short-circuiting.
Definition meta.hpp:1411
void void_
An alias for void.
Definition meta.hpp:597