17 #ifndef OPENKALMAN_MOVABLE_WRAPPER_HPP 18 #define OPENKALMAN_MOVABLE_WRAPPER_HPP 33 requires (std::move_constructible<T> and std::is_object_v<T>) or std::is_lvalue_reference_v<T>
39 static_assert(stdex::move_constructible<T> and std::is_object_v<T>);
55 #ifdef __cpp_lib_concepts 56 movable_wrapper() noexcept(
std::is_nothrow_default_constructible_v<
T_>) requires
std::default_initializable<
T_> = default;
72 constexpr T&
get() & noexcept {
return t_.operator*(); }
74 constexpr
const T&
get()
const & noexcept {
return t_.operator*(); }
76 constexpr T&&
get() && noexcept {
return std::move(t_.operator*()); }
78 constexpr
const T&&
get()
const && noexcept {
return std::move(t_.operator*()); }
84 constexpr
operator T& () & noexcept {
return t_.operator*(); }
86 constexpr
operator const T& ()
const & noexcept {
return t_.operator*(); }
88 constexpr
operator T () && noexcept {
return std::move(t_.operator*()); }
90 constexpr
operator const T () const && noexcept {
return std::move(t_.operator*()); }
96 template<
typename...ArgTypes>
97 constexpr std::invoke_result_t<T&, ArgTypes...>
98 operator () (ArgTypes&&...args) & noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
100 return stdex::invoke(t_.operator*(), std::forward<ArgTypes>(args)...);
104 template<
typename...ArgTypes>
105 std::invoke_result_t<
const T&, ArgTypes...>
106 constexpr
operator () (ArgTypes&&...args)
const & noexcept(std::is_nothrow_invocable_v<const T&, ArgTypes...>)
108 return stdex::invoke(t_.operator*(), std::forward<ArgTypes>(args)...);
112 template<
typename...ArgTypes>
113 std::invoke_result_t<T&&, ArgTypes...>
114 constexpr
operator () (ArgTypes&&...args) && noexcept(std::is_nothrow_invocable_v<T&&, ArgTypes...>)
116 return stdex::invoke(std::move(t_.operator*()), std::forward<ArgTypes>(args)...);
120 template<
typename...ArgTypes>
121 std::invoke_result_t<
const T&&, ArgTypes...>
122 constexpr
operator () (ArgTypes&&...args)
const && noexcept(std::is_nothrow_invocable_v<const T&&, ArgTypes...>)
124 return stdex::invoke(std::move(t_.operator*()), std::forward<ArgTypes>(args)...);
164 constexpr T&
get()
const noexcept {
return t_; }
170 constexpr
operator T& ()
const noexcept {
return t_; }
176 template<
typename...ArgTypes>
177 constexpr std::invoke_result_t<T&, ArgTypes...>
178 operator () (ArgTypes&&...args)
const noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
180 return stdex::invoke(t_, std::forward<ArgTypes>(args)...);
198 #ifdef __cpp_impl_three_way_comparison 201 requires requires { {lhs.
get() == rhs.
get()} -> OpenKalman::internal::boolean_testable; }
203 return lhs.
get() == rhs.
get();
208 requires (not std::is_const_v<T>) and requires { {lhs.
get() == rhs.
get()} -> OpenKalman::internal::boolean_testable; }
210 return lhs.
get() == rhs.
get();
215 requires requires { {lhs.
get() == ref} -> OpenKalman::internal::boolean_testable; }
217 return lhs.
get() == ref;
223 {lhs.
get() < rhs.
get()} -> OpenKalman::internal::boolean_testable;
224 {lhs.
get() > rhs.
get()} -> OpenKalman::internal::boolean_testable; }
226 return lhs.
get() <=> rhs.
get();
231 (not std::is_const_v<T>) and
233 {lhs.
get() < rhs.
get()} -> OpenKalman::internal::boolean_testable;
234 {lhs.
get() > rhs.
get()} -> OpenKalman::internal::boolean_testable; }
236 return lhs.
get() <=> rhs.
get();
242 {lhs.
get() < ref} -> OpenKalman::internal::boolean_testable;
243 {lhs.
get() > ref} -> OpenKalman::internal::boolean_testable; }
245 return lhs.
get() <=> ref;
248 template<
typename T, std::enable_if_t<
249 OpenKalman::internal::boolean_testable<decltype(std::declval<const movable_wrapper<T>&>().
get() == std::declval<const movable_wrapper<T>&>().
get())>,
int> = 0>
251 {
return lhs.
get() == rhs.
get(); }
253 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
254 OpenKalman::
internal::
boolean_testable<decltype(std::declval<const movable_wrapper<T>&>().get() == std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
256 {
return lhs.
get() == rhs.
get(); }
258 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
259 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() == std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
261 {
return lhs.
get() == rhs.
get(); }
263 template<
typename T, std::enable_if_t<
264 OpenKalman::internal::boolean_testable<decltype(std::declval<movable_wrapper<T>&>().
get() == std::declval<const T&>())>,
int> = 0>
266 {
return lhs.
get() == ref; }
268 template<
typename T, std::enable_if_t<
269 OpenKalman::internal::boolean_testable<decltype(std::declval<const T&>() == std::declval<
movable_wrapper<T>&>().
get())>,
int> = 0>
271 {
return ref == lhs.
get(); }
274 template<
typename T, std::enable_if_t<
275 OpenKalman::internal::boolean_testable<decltype(std::declval<const movable_wrapper<T>&>().
get() == std::declval<const movable_wrapper<T>&>().
get())>,
int> = 0>
277 {
return lhs.
get() != rhs.
get(); }
279 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
280 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() != std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
282 {
return lhs.
get() != rhs.
get(); }
284 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
285 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() != std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
287 {
return lhs.
get() != rhs.
get(); }
289 template<
typename T, std::enable_if_t<
290 OpenKalman::internal::boolean_testable<decltype(std::declval<movable_wrapper<T>&>().
get() != std::declval<const T&>())>,
int> = 0>
292 {
return lhs.
get() != ref; }
294 template<
typename T, std::enable_if_t<
295 OpenKalman::internal::boolean_testable<decltype(std::declval<const T&>() != std::declval<
movable_wrapper<T>&>().
get())>,
int> = 0>
297 {
return ref != lhs.
get(); }
300 template<
typename T, std::enable_if_t<
301 OpenKalman::internal::boolean_testable<decltype(std::declval<const movable_wrapper<T>&>().
get() == std::declval<const movable_wrapper<T>&>().
get())>,
int> = 0>
303 {
return lhs.
get() < rhs.
get(); }
305 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
306 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() < std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
307 constexpr
bool operator<(const movable_wrapper<T>& lhs, const movable_wrapper<const T>& rhs) noexcept
308 { return lhs.get() < rhs.get(); }
310 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
311 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() < std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
312 constexpr
bool operator<(const movable_wrapper<const T>& lhs, const movable_wrapper<T>& rhs) noexcept
313 { return lhs.get() < rhs.get(); }
315 template<
typename T, std::enable_if_t<
316 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() < std::declval<const T&>())>,
int> = 0>
317 constexpr
bool operator<(const movable_wrapper<T>& lhs, const T& ref) noexcept
318 { return lhs.get() < ref; }
320 template<
typename T, std::enable_if_t<
321 OpenKalman::
internal::
boolean_testable<decltype(std::declval<const T&>() < std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
322 constexpr
bool operator<(const T& ref, const movable_wrapper<T>& lhs) noexcept
323 { return ref < lhs.get(); }
326 template<
typename T, std::enable_if_t<
327 OpenKalman::
internal::
boolean_testable<decltype(std::declval<const movable_wrapper<T>&>().get() == std::declval<const movable_wrapper<T>&>().get())>,
int> = 0>
329 {
return lhs.
get() > rhs.
get(); }
331 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
332 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() > std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
334 {
return lhs.
get() > rhs.
get(); }
336 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
337 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() > std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
339 {
return lhs.
get() > rhs.
get(); }
341 template<
typename T, std::enable_if_t<
342 OpenKalman::internal::boolean_testable<decltype(std::declval<movable_wrapper<T>&>().
get() > std::declval<const T&>())>,
int> = 0>
344 {
return lhs.
get() > ref; }
346 template<
typename T, std::enable_if_t<
347 OpenKalman::internal::boolean_testable<decltype(std::declval<const T&>() > std::declval<
movable_wrapper<T>&>().
get())>,
int> = 0>
349 {
return ref > lhs.
get(); }
352 template<
typename T, std::enable_if_t<
353 OpenKalman::internal::boolean_testable<decltype(std::declval<const movable_wrapper<T>&>().
get() == std::declval<const movable_wrapper<T>&>().
get())>,
int> = 0>
355 {
return lhs.
get() <= rhs.
get(); }
357 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
358 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() <= std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
359 constexpr
bool operator<=(const movable_wrapper<T>& lhs, const movable_wrapper<const T>& rhs) noexcept
360 { return lhs.get() <= rhs.get(); }
362 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
363 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() <= std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
364 constexpr
bool operator<=(const movable_wrapper<const T>& lhs, const movable_wrapper<T>& rhs) noexcept
365 { return lhs.get() <= rhs.get(); }
367 template<
typename T, std::enable_if_t<
368 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() <= std::declval<const T&>())>,
int> = 0>
369 constexpr
bool operator<=(const movable_wrapper<T>& lhs, const T& ref) noexcept
370 { return lhs.get() <= ref; }
372 template<
typename T, std::enable_if_t<
373 OpenKalman::
internal::
boolean_testable<decltype(std::declval<const T&>() <= std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
374 constexpr
bool operator<=(const T& ref, const movable_wrapper<T>& lhs) noexcept
375 { return ref <= lhs.get(); }
378 template<
typename T, std::enable_if_t<
379 OpenKalman::
internal::
boolean_testable<decltype(std::declval<const movable_wrapper<T>&>().get() == std::declval<const movable_wrapper<T>&>().get())>,
int> = 0>
381 {
return lhs.
get() >= rhs.
get(); }
383 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
384 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() >= std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
386 {
return lhs.
get() >= rhs.
get(); }
388 template<
typename T, std::enable_if_t<(not std::is_const_v<T>) and
389 OpenKalman::
internal::
boolean_testable<decltype(std::declval<movable_wrapper<T>&>().get() >= std::declval<movable_wrapper<T>&>().get())>,
int> = 0>
391 {
return lhs.
get() >= rhs.
get(); }
393 template<
typename T, std::enable_if_t<
394 OpenKalman::internal::boolean_testable<decltype(std::declval<movable_wrapper<T>&>().
get() >= std::declval<const T&>())>,
int> = 0>
396 {
return lhs.
get() >= ref; }
398 template<
typename T, std::enable_if_t<
399 OpenKalman::internal::boolean_testable<decltype(std::declval<const T&>() >= std::declval<
movable_wrapper<T>&>().
get())>,
int> = 0>
401 {
return ref >= lhs.
get(); }
405 #if __cplusplus >= 202002L 409 inline constexpr
bool is_movable_wrapper_ref =
false;
412 inline constexpr
bool is_movable_wrapper_ref<movable_wrapper<T&>> =
true;
416 template<
typename R,
typename T,
typename RQ,
typename TQ>
417 concept movable_wrapper_common_reference_exists_with =
418 detail::is_movable_wrapper_ref<R> and
419 requires {
typename stdex::common_reference_t<typename R::type, TQ>; } and
420 std::convertible_to<RQ, stdex::common_reference_t<typename R::type, TQ>>
429 #if __cplusplus >= 202002L 430 template <
typename R,
typename T,
template<
typename>
typename RQual,
template<
typename>
typename TQual> requires
431 OpenKalman::collections::internal::movable_wrapper_common_reference_exists_with<R, T, RQual<R>, TQual<T>> and
432 (not OpenKalman::collections::internal::movable_wrapper_common_reference_exists_with<T, R, TQual<T>, RQual<R>>)
433 struct basic_common_reference<R, T, RQual, TQual>
435 using type = common_reference_t<typename R::type, TQual<T>>;
439 template <
typename T,
typename R,
template <
typename>
typename TQual,
template <
typename>
typename RQual> requires
440 OpenKalman::collections::internal::movable_wrapper_common_reference_exists_with<R, T, RQual<R>, TQual<T>> and
441 (not OpenKalman::collections::internal::movable_wrapper_common_reference_exists_with<T, R, TQual<T>, RQual<R>>)
442 struct basic_common_reference<T, R, TQual, RQual>
444 using type = common_reference_t<typename R::type, TQual<T>>;
constexpr movable_wrapper(T &&t)
Construct from an rvalue reference.
Definition: movable_wrapper.hpp:66
constexpr movable_wrapper() noexcept(std::is_nothrow_default_constructible_v< T_ >)=default
Default constructor.
F type
The wrapped type.
Definition: movable_wrapper.hpp:48
constexpr std::invoke_result_t< T &, ArgTypes... > operator()(ArgTypes &&...args) &noexcept(std::is_nothrow_invocable_v< T &, ArgTypes... >)
Call the wrapped object if it is callable.
Definition: movable_wrapper.hpp:98
constexpr T & get() &noexcept
Retrieve the stored value.
Definition: movable_wrapper.hpp:72
constexpr movable_wrapper(T &t)
Construct from an lvalue reference.
Definition: movable_wrapper.hpp:158
Definition: tuple_like_to_tuple.hpp:24
Basic definitions for OpenKalman as a whole.
T & type
The wrapped type.
Definition: movable_wrapper.hpp:151
Definition: movable_wrapper.hpp:35