2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
11 #define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H
13 #include <__compare/synth_three_way.h>
14 #include <__concepts/boolean_testable.h>
16 #include <__functional/weak_result_type.h>
17 #include <__memory/addressof.h>
18 #include <__type_traits/enable_if.h>
19 #include <__type_traits/invoke.h>
20 #include <__type_traits/is_const.h>
21 #include <__type_traits/remove_cvref.h>
22 #include <__type_traits/void_t.h>
23 #include <__utility/declval.h>
24 #include <__utility/forward.h>
26 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27 # pragma GCC system_header
30 _LIBCPP_BEGIN_NAMESPACE_STD
33 class _LIBCPP_TEMPLATE_VIS reference_wrapper
: public __weak_result_type
<_Tp
> {
41 static void __fun(_Tp
&) _NOEXCEPT
;
42 static void __fun(_Tp
&&) = delete; // NOLINT(modernize-use-equals-delete) ; This is llvm.org/PR54276
46 class = __void_t
<decltype(__fun(std::declval
<_Up
>()))>,
47 __enable_if_t
<!__is_same_uncvref
<_Up
, reference_wrapper
>::value
, int> = 0>
48 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
reference_wrapper(_Up
&& __u
)
49 _NOEXCEPT_(noexcept(__fun(std::declval
<_Up
>()))) {
50 type
& __f
= static_cast<_Up
&&>(__u
);
51 __f_
= std::addressof(__f
);
55 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
operator type
&() const _NOEXCEPT
{ return *__f_
; }
56 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type
& get() const _NOEXCEPT
{ return *__f_
; }
59 template <class... _ArgTypes
>
60 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of
<type
&, _ArgTypes
...>::type
61 operator()(_ArgTypes
&&... __args
) const
62 #if _LIBCPP_STD_VER >= 17
63 // Since is_nothrow_invocable requires C++17 LWG3764 is not backported
64 // to earlier versions.
65 noexcept(is_nothrow_invocable_v
<_Tp
&, _ArgTypes
...>)
68 return std::__invoke(get(), std::forward
<_ArgTypes
>(__args
)...);
71 #if _LIBCPP_STD_VER >= 26
73 // [refwrap.comparisons], comparisons
75 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(reference_wrapper __x
, reference_wrapper __y
)
77 { __x
.get() == __y
.get() } -> __boolean_testable
;
80 return __x
.get() == __y
.get();
83 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(reference_wrapper __x
, const _Tp
& __y
)
85 { __x
.get() == __y
} -> __boolean_testable
;
88 return __x
.get() == __y
;
91 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(reference_wrapper __x
, reference_wrapper
<const _Tp
> __y
)
92 requires(!is_const_v
<_Tp
>) && requires
{
93 { __x
.get() == __y
.get() } -> __boolean_testable
;
96 return __x
.get() == __y
.get();
99 _LIBCPP_HIDE_FROM_ABI
friend constexpr auto operator<=>(reference_wrapper __x
, reference_wrapper __y
)
100 requires requires
{ std::__synth_three_way(__x
.get(), __y
.get()); }
102 return std::__synth_three_way(__x
.get(), __y
.get());
105 _LIBCPP_HIDE_FROM_ABI
friend constexpr auto operator<=>(reference_wrapper __x
, const _Tp
& __y
)
106 requires requires
{ std::__synth_three_way(__x
.get(), __y
); }
108 return std::__synth_three_way(__x
.get(), __y
);
111 _LIBCPP_HIDE_FROM_ABI
friend constexpr auto operator<=>(reference_wrapper __x
, reference_wrapper
<const _Tp
> __y
)
112 requires(!is_const_v
<_Tp
>) && requires
{ std::__synth_three_way(__x
.get(), __y
.get()); }
114 return std::__synth_three_way(__x
.get(), __y
.get());
117 #endif // _LIBCPP_STD_VER >= 26
120 #if _LIBCPP_STD_VER >= 17
122 reference_wrapper(_Tp
&) -> reference_wrapper
<_Tp
>;
126 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper
<_Tp
> ref(_Tp
& __t
) _NOEXCEPT
{
127 return reference_wrapper
<_Tp
>(__t
);
131 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper
<_Tp
>
132 ref(reference_wrapper
<_Tp
> __t
) _NOEXCEPT
{
137 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper
<const _Tp
> cref(const _Tp
& __t
) _NOEXCEPT
{
138 return reference_wrapper
<const _Tp
>(__t
);
142 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper
<const _Tp
>
143 cref(reference_wrapper
<_Tp
> __t
) _NOEXCEPT
{
148 void ref(const _Tp
&&) = delete;
150 void cref(const _Tp
&&) = delete;
152 _LIBCPP_END_NAMESPACE_STD
154 #endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H