Warning: This file is not a C or C++ file. It does not have highlighting.
1 | // -*- C++ -*- |
---|---|
2 | //===----------------------------------------------------------------------===// |
3 | // |
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 |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H |
11 | #define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H |
12 | |
13 | #include <__compare/synth_three_way.h> |
14 | #include <__concepts/boolean_testable.h> |
15 | #include <__config> |
16 | #include <__functional/weak_result_type.h> |
17 | #include <__memory/addressof.h> |
18 | #include <__type_traits/desugars_to.h> |
19 | #include <__type_traits/enable_if.h> |
20 | #include <__type_traits/invoke.h> |
21 | #include <__type_traits/is_const.h> |
22 | #include <__type_traits/remove_cvref.h> |
23 | #include <__type_traits/void_t.h> |
24 | #include <__utility/declval.h> |
25 | #include <__utility/forward.h> |
26 | |
27 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
28 | # pragma GCC system_header |
29 | #endif |
30 | |
31 | _LIBCPP_BEGIN_NAMESPACE_STD |
32 | |
33 | template <class _Tp> |
34 | class reference_wrapper : public __weak_result_type<_Tp> { |
35 | public: |
36 | // types |
37 | typedef _Tp type; |
38 | |
39 | private: |
40 | type* __f_; |
41 | |
42 | static void __fun(_Tp&) _NOEXCEPT; |
43 | static void __fun(_Tp&&) = delete; // NOLINT(modernize-use-equals-delete) ; This is llvm.org/PR54276 |
44 | |
45 | public: |
46 | template <class _Up, |
47 | class = __void_t<decltype(__fun(std::declval<_Up>()))>, |
48 | __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, int> = 0> |
49 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper(_Up&& __u) |
50 | _NOEXCEPT_(noexcept(__fun(std::declval<_Up>()))) { |
51 | type& __f = static_cast<_Up&&>(__u); |
52 | __f_ = std::addressof(__f); |
53 | } |
54 | |
55 | // access |
56 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT { return *__f_; } |
57 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; } |
58 | |
59 | // invoke |
60 | template <class... _ArgTypes> |
61 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<type&, _ArgTypes...> |
62 | operator()(_ArgTypes&&... __args) const |
63 | #if _LIBCPP_STD_VER >= 17 |
64 | // Since is_nothrow_invocable requires C++17 LWG3764 is not backported |
65 | // to earlier versions. |
66 | noexcept(is_nothrow_invocable_v<_Tp&, _ArgTypes...>) |
67 | #endif |
68 | { |
69 | return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); |
70 | } |
71 | |
72 | #if _LIBCPP_STD_VER >= 26 |
73 | |
74 | // [refwrap.comparisons], comparisons |
75 | |
76 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, reference_wrapper __y) |
77 | requires requires { |
78 | { __x.get() == __y.get() } -> __boolean_testable; |
79 | } |
80 | { |
81 | return __x.get() == __y.get(); |
82 | } |
83 | |
84 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, const _Tp& __y) |
85 | requires requires { |
86 | { __x.get() == __y } -> __boolean_testable; |
87 | } |
88 | { |
89 | return __x.get() == __y; |
90 | } |
91 | |
92 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, reference_wrapper<const _Tp> __y) |
93 | requires(!is_const_v<_Tp>) && requires { |
94 | { __x.get() == __y.get() } -> __boolean_testable; |
95 | } |
96 | { |
97 | return __x.get() == __y.get(); |
98 | } |
99 | |
100 | _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(reference_wrapper __x, reference_wrapper __y) |
101 | requires requires { std::__synth_three_way(__x.get(), __y.get()); } |
102 | { |
103 | return std::__synth_three_way(__x.get(), __y.get()); |
104 | } |
105 | |
106 | _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(reference_wrapper __x, const _Tp& __y) |
107 | requires requires { std::__synth_three_way(__x.get(), __y); } |
108 | { |
109 | return std::__synth_three_way(__x.get(), __y); |
110 | } |
111 | |
112 | _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(reference_wrapper __x, reference_wrapper<const _Tp> __y) |
113 | requires(!is_const_v<_Tp>) && requires { std::__synth_three_way(__x.get(), __y.get()); } |
114 | { |
115 | return std::__synth_three_way(__x.get(), __y.get()); |
116 | } |
117 | |
118 | #endif // _LIBCPP_STD_VER >= 26 |
119 | }; |
120 | |
121 | #if _LIBCPP_STD_VER >= 17 |
122 | template <class _Tp> |
123 | reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; |
124 | #endif |
125 | |
126 | template <class _Tp> |
127 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT { |
128 | return reference_wrapper<_Tp>(__t); |
129 | } |
130 | |
131 | template <class _Tp> |
132 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> |
133 | ref(reference_wrapper<_Tp> __t) _NOEXCEPT { |
134 | return __t; |
135 | } |
136 | |
137 | template <class _Tp> |
138 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> cref(const _Tp& __t) _NOEXCEPT { |
139 | return reference_wrapper<const _Tp>(__t); |
140 | } |
141 | |
142 | template <class _Tp> |
143 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<const _Tp> |
144 | cref(reference_wrapper<_Tp> __t) _NOEXCEPT { |
145 | return __t; |
146 | } |
147 | |
148 | template <class _Tp> |
149 | void ref(const _Tp&&) = delete; |
150 | template <class _Tp> |
151 | void cref(const _Tp&&) = delete; |
152 | |
153 | // Let desugars-to pass through std::reference_wrapper |
154 | template <class _CanonicalTag, class _Operation, class... _Args> |
155 | inline const bool __desugars_to_v<_CanonicalTag, reference_wrapper<_Operation>, _Args...> = |
156 | __desugars_to_v<_CanonicalTag, _Operation, _Args...>; |
157 | |
158 | _LIBCPP_END_NAMESPACE_STD |
159 | |
160 | #endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H |
161 |
Warning: This file is not a C or C++ file. It does not have highlighting.