17 #ifndef OPENKALMAN_MOVABLE_WRAPPER_HPP 18 #define OPENKALMAN_MOVABLE_WRAPPER_HPP 38 template<
typename T,
typename =
void>
65 constexpr T&
get() & noexcept {
return t_; }
67 constexpr
const T&
get()
const & noexcept {
return t_; }
69 constexpr T&&
get() && noexcept {
return std::move(t_); }
71 constexpr
const T&&
get()
const && noexcept {
return std::move(t_); }
77 constexpr
operator T& () & noexcept {
return t_; }
79 constexpr
operator const T& ()
const & noexcept {
return t_; }
81 constexpr
operator T () && noexcept {
return std::move(t_); }
83 constexpr
operator const T () const && noexcept {
return std::move(t_); }
89 template<
typename...ArgTypes>
90 constexpr std::invoke_result_t<T&, ArgTypes...>
91 operator () (ArgTypes&&...args) & noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
93 #if __cplusplus >= 202002L 94 return std::invoke(t_, std::forward<ArgTypes>(args)...);
96 return OpenKalman::invoke(t_, std::forward<ArgTypes>(args)...);
101 template<
typename...ArgTypes>
102 std::invoke_result_t<T&, ArgTypes...>
103 constexpr
operator () (ArgTypes&&...args)
const & noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
105 #if __cplusplus >= 202002L 106 return std::invoke(t_, std::forward<ArgTypes>(args)...);
108 return OpenKalman::invoke(t_, std::forward<ArgTypes>(args)...);
113 template<
typename...ArgTypes>
114 std::invoke_result_t<T&, ArgTypes...>
115 constexpr
operator () (ArgTypes&&...args) && noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
117 #if __cplusplus >= 202002L 118 return std::invoke(std::move(t_), std::forward<ArgTypes>(args)...);
120 return OpenKalman::invoke(std::move(t_), std::forward<ArgTypes>(args)...);
125 template<
typename...ArgTypes>
126 std::invoke_result_t<T&, ArgTypes...>
127 constexpr
operator () (ArgTypes&&...args)
const && noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
129 #if __cplusplus >= 202002L 130 return std::invoke(std::move(t_), std::forward<ArgTypes>(args)...);
132 return OpenKalman::invoke(std::move(t_), std::forward<ArgTypes>(args)...);
155 #if __cplusplus >= 202002L 156 using T_ = std::reference_wrapper<std::remove_reference_t<T>>;
172 #ifdef __cpp_concepts 173 template<
typename Arg>
175 movable_wrapper(Arg&& arg) noexcept requires std::constructible_from<T_, Arg&&>
177 template<
typename Arg, std::enable_if_t<std::is_constructible_v<T_, Arg&&>,
int> = 0>
180 : t_ {std::forward<Arg>(arg)} {}
186 constexpr T&
get()
const noexcept {
return t_; }
192 constexpr
operator T& ()
const noexcept {
return t_; }
198 template<
typename...ArgTypes>
199 constexpr std::invoke_result_t<T&, ArgTypes...>
200 operator () (ArgTypes&&...args)
const noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
202 return t_(std::forward<ArgTypes>(args)...);
219 #ifdef __cpp_concepts 220 template<tuple_like T> requires (not std::movable<T>)
224 struct
movable_wrapper<T,
std::enable_if_t<not std::is_lvalue_reference_v<T> and tuple_like<T> and not movable<T>>>
230 static constexpr decltype(
auto)
234 else return std::forward<U>(u);
238 template<
typename U, std::size_t...i>
239 static constexpr
auto 240 fill_tuple(U&& u, std::index_sequence<i...>)
242 return std::tuple { make_element(OpenKalman::internal::generalized_std_get<i>(std::forward<U>(u)))...};
246 using T_ = decltype(fill_tuple(std::declval<T>(), std::make_index_sequence<std::tuple_size_v<T>>{}));
268 : t_ {fill_tuple(std::forward<T>(t), std::make_index_sequence<std::tuple_size_v<T>>{})} {}
274 constexpr T_&
get() & noexcept {
return t_; }
276 constexpr
const T_&
get()
const & noexcept {
return t_; }
278 constexpr T_&&
get() && noexcept {
return std::move(t_); }
280 constexpr
const T_&&
get()
const && noexcept {
return std::move(t_); }
300 #ifdef __cpp_concepts 301 template<std::
size_t i,
typename T> requires tuple_like<T>
303 template<std::
size_t i,
typename T, std::enable_if_t<tuple_like<T>,
int> = 0>
305 constexpr decltype(
auto)
308 static_assert(i < std::tuple_size_v<std::decay_t<T>>,
"Index out of range");
309 return OpenKalman::internal::generalized_std_get<i>(arg.get());
313 #ifdef __cpp_concepts 314 template<std::
size_t i,
typename T> requires tuple_like<T>
316 template<std::
size_t i,
typename T, std::enable_if_t<tuple_like<T>,
int> = 0>
318 constexpr decltype(
auto)
321 static_assert(i < std::tuple_size_v<std::decay_t<T>>,
"Index out of range");
322 return OpenKalman::internal::generalized_std_get<i>(arg.get());
326 #ifdef __cpp_concepts 327 template<std::
size_t i,
typename T> requires tuple_like<T>
329 template<std::
size_t i,
typename T, std::enable_if_t<tuple_like<T>,
int> = 0>
331 constexpr decltype(
auto)
334 static_assert(i < std::tuple_size_v<std::decay_t<T>>,
"Index out of range");
335 return OpenKalman::internal::generalized_std_get<i>(std::move(arg).get());
339 #ifdef __cpp_concepts 340 template<std::
size_t i,
typename T> requires tuple_like<T>
342 template<std::
size_t i,
typename T, std::enable_if_t<tuple_like<T>,
int> = 0>
344 constexpr decltype(
auto)
347 static_assert(i < std::tuple_size_v<std::decay_t<T>>,
"Index out of range");
348 return OpenKalman::internal::generalized_std_get<i>(std::move(arg).get());
352 #ifdef __cpp_impl_three_way_comparison 355 requires requires { {lhs.
get() == rhs.
get()} -> std::convertible_to<bool>; }
357 return lhs.
get() == rhs.
get();
362 requires (not std::is_const_v<T>) and requires { {lhs.
get() == rhs.
get()} -> std::convertible_to<bool>; }
364 return lhs.
get() == rhs.
get();
369 requires requires { {lhs.
get() == ref} -> std::convertible_to<bool>; }
371 return lhs.
get() == ref;
376 requires requires { {lhs.
get() < rhs.
get()} -> std::convertible_to<bool>; {lhs.
get() > rhs.
get()} -> std::convertible_to<bool>; }
378 return lhs.
get() <=> rhs.
get();
383 (not std::is_const_v<T>) and
384 requires { {lhs.
get() < rhs.
get()} -> std::convertible_to<bool>; {lhs.
get() > rhs.
get()} -> std::convertible_to<bool>; }
386 return lhs.
get() <=> rhs.
get();
391 requires requires { {lhs.
get() < ref} -> std::convertible_to<bool>; {lhs.
get() > ref} -> std::convertible_to<bool>; }
393 return lhs.
get() <=> ref;
396 template<
typename T, std::enable_if_t<
397 std::is_convertible<decltype(std::declval<const movable_wrapper<T>&>().
get() == std::declval<const movable_wrapper<T>&>().
get()),
bool>::
value,
int> = 0>
399 {
return lhs.
get() == rhs.
get(); }
401 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
402 std::is_convertible<decltype(std::declval<const movable_wrapper<T>&>().get() == std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
404 {
return lhs.
get() == rhs.
get(); }
406 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
407 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() == std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
409 {
return lhs.
get() == rhs.
get(); }
411 template<
typename T, std::enable_if_t<
412 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().
get() == std::declval<const T&>()),
bool>
::value,
int> = 0>
414 {
return lhs.
get() == ref; }
416 template<
typename T, std::enable_if_t<
419 {
return ref == lhs.
get(); }
422 template<
typename T, std::enable_if_t<
423 std::is_convertible<decltype(std::declval<const movable_wrapper<T>&>().
get() == std::declval<const movable_wrapper<T>&>().
get()),
bool>::
value,
int> = 0>
425 {
return lhs.
get() != rhs.
get(); }
427 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
428 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() != std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
430 {
return lhs.
get() != rhs.
get(); }
432 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
433 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() != std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
435 {
return lhs.
get() != rhs.
get(); }
437 template<
typename T, std::enable_if_t<
438 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().
get() != std::declval<const T&>()),
bool>
::value,
int> = 0>
440 {
return lhs.
get() != ref; }
442 template<
typename T, std::enable_if_t<
445 {
return ref != lhs.
get(); }
448 template<
typename T, std::enable_if_t<
449 std::is_convertible<decltype(std::declval<const movable_wrapper<T>&>().
get() == std::declval<const movable_wrapper<T>&>().
get()),
bool>::
value,
int> = 0>
451 {
return lhs.
get() < rhs.
get(); }
453 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
454 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() < std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
455 constexpr
bool operator<(const movable_wrapper<T>& lhs, const movable_wrapper<const T>& rhs) noexcept
456 { return lhs.get() < rhs.get(); }
458 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
459 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() < std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
460 constexpr
bool operator<(const movable_wrapper<const T>& lhs, const movable_wrapper<T>& rhs) noexcept
461 { return lhs.get() < rhs.get(); }
463 template<
typename T, std::enable_if_t<
464 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() < std::declval<const T&>()),
bool>::value,
int> = 0>
465 constexpr
bool operator<(const movable_wrapper<T>& lhs, const T& ref) noexcept
466 { return lhs.get() < ref; }
468 template<
typename T, std::enable_if_t<
469 std::is_convertible<decltype(std::declval<const T&>() < std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
470 constexpr
bool operator<(const T& ref, const movable_wrapper<T>& lhs) noexcept
471 { return ref < lhs.get(); }
474 template<
typename T, std::enable_if_t<
475 std::is_convertible<decltype(std::declval<const movable_wrapper<T>&>().get() == std::declval<const movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
477 {
return lhs.
get() > rhs.
get(); }
479 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
480 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() > std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
482 {
return lhs.
get() > rhs.
get(); }
484 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
485 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() > std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
487 {
return lhs.
get() > rhs.
get(); }
489 template<
typename T, std::enable_if_t<
490 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().
get() > std::declval<const T&>()),
bool>
::value,
int> = 0>
492 {
return lhs.
get() > ref; }
494 template<
typename T, std::enable_if_t<
497 {
return ref > lhs.
get(); }
500 template<
typename T, std::enable_if_t<
501 std::is_convertible<decltype(std::declval<const movable_wrapper<T>&>().
get() == std::declval<const movable_wrapper<T>&>().
get()),
bool>::
value,
int> = 0>
503 {
return lhs.
get() <= rhs.
get(); }
505 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
506 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() <= std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
507 constexpr
bool operator<=(const movable_wrapper<T>& lhs, const movable_wrapper<const T>& rhs) noexcept
508 { return lhs.get() <= rhs.get(); }
510 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
511 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() <= std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
512 constexpr
bool operator<=(const movable_wrapper<const T>& lhs, const movable_wrapper<T>& rhs) noexcept
513 { return lhs.get() <= rhs.get(); }
515 template<
typename T, std::enable_if_t<
516 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() <= std::declval<const T&>()),
bool>::value,
int> = 0>
517 constexpr
bool operator<=(const movable_wrapper<T>& lhs, const T& ref) noexcept
518 { return lhs.get() <= ref; }
520 template<
typename T, std::enable_if_t<
521 std::is_convertible<decltype(std::declval<const T&>() <= std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
522 constexpr
bool operator<=(const T& ref, const movable_wrapper<T>& lhs) noexcept
523 { return ref <= lhs.get(); }
526 template<
typename T, std::enable_if_t<
527 std::is_convertible<decltype(std::declval<const movable_wrapper<T>&>().get() == std::declval<const movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
529 {
return lhs.
get() >= rhs.
get(); }
531 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
532 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() >= std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
534 {
return lhs.
get() >= rhs.
get(); }
536 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
537 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().get() >= std::declval<movable_wrapper<T>&>().get()),
bool>::value,
int> = 0>
539 {
return lhs.
get() >= rhs.
get(); }
541 template<
typename T, std::enable_if_t<
542 std::is_convertible<decltype(std::declval<movable_wrapper<T>&>().
get() >= std::declval<const T&>()),
bool>
::value,
int> = 0>
544 {
return lhs.
get() >= ref; }
546 template<
typename T, std::enable_if_t<
549 {
return ref >= lhs.
get(); }
553 #if __cplusplus >= 202002L 557 inline constexpr
bool is_movable_wrapper_ref =
false;
560 inline constexpr
bool is_movable_wrapper_ref<movable_wrapper<T&>> =
true;
564 template<
typename R,
typename T,
typename RQ,
typename TQ>
565 concept movable_wrapper_common_reference_exists_with =
566 detail::is_movable_wrapper_ref<R> and
567 requires {
typename std::common_reference_t<typename R::type, TQ>; } and
568 std::convertible_to<RQ, std::common_reference_t<typename R::type, TQ>>
573 #ifndef __cpp_concepts 574 template<
typename T,
typename =
void>
579 : std::tuple_size<T> {};
582 template<std::
size_t i,
typename T,
typename =
void>
585 template<std::
size_t i,
typename T>
587 : std::tuple_element<i, T> {};
595 #ifdef __cpp_concepts 596 template<
typename Tup> requires requires { tuple_size<std::decay_t<Tup>>
::value; }
599 template<
typename Tup>
600 struct tuple_size<OpenKalman::collections::internal::movable_wrapper<Tup>>
605 #ifdef __cpp_concepts 606 template<std::
size_t i,
typename Tup> requires requires {
typename tuple_element<i, std::decay_t<Tup>>
::type; }
607 struct tuple_element<i, OpenKalman::collections::internal::movable_wrapper<Tup>> : tuple_element<i, std::decay_t<Tup>> {};
609 template<std::
size_t i,
typename Tup>
610 struct tuple_element<i, OpenKalman::collections::internal::movable_wrapper<Tup>>
615 #if __cplusplus >= 202002L 616 template <
typename R,
typename T,
template<
typename>
typename RQual,
template<
typename>
typename TQual> requires
617 OpenKalman::collections::internal::movable_wrapper_common_reference_exists_with<R, T, RQual<R>, TQual<T>> and
618 (not OpenKalman::collections::internal::movable_wrapper_common_reference_exists_with<T, R, TQual<T>, RQual<R>>)
619 struct basic_common_reference<R, T, RQual, TQual>
621 using type = common_reference_t<typename R::type, TQual<T>>;
625 template <
typename T,
typename R,
template <
typename>
typename TQual,
template <
typename>
typename RQual> requires
626 OpenKalman::collections::internal::movable_wrapper_common_reference_exists_with<R, T, RQual<R>, TQual<T>> and
627 (not OpenKalman::collections::internal::movable_wrapper_common_reference_exists_with<T, R, TQual<T>, RQual<R>>)
628 struct basic_common_reference<T, R, TQual, RQual>
630 using type = common_reference_t<typename R::type, TQual<T>>;
637 #endif //OPENKALMAN_MOVABLE_WRAPPER_HPP Definition for collections::tuple_like.
Definition: movable_wrapper.hpp:575
constexpr std::invoke_result_t< T &, ArgTypes... > operator()(ArgTypes &&...args) &noexcept(std::is_nothrow_invocable_v< T &, ArgTypes... >)
Call the callable object.
Definition: movable_wrapper.hpp:91
Definition: tuple_reverse.hpp:103
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
Definition: movable_wrapper.hpp:583
Definitions relating to the availability of c++ language features.
F type
The wrapped type.
Definition: movable_wrapper.hpp:45
constexpr T & get() &noexcept
Retrieve the stored value.
Definition: movable_wrapper.hpp:65
constexpr movable_wrapper() noexcept=default
Default constructor.
Definition: tuple_like_to_tuple.hpp:24
T & type
The wrapped type.
Definition: movable_wrapper.hpp:166
Definition: movable_wrapper.hpp:40
constexpr movable_wrapper(Arg &&arg) noexcept
Construct from a value.
Definition: movable_wrapper.hpp:178
T type
The wrapped type.
Definition: movable_wrapper.hpp:253