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 <__config> 14 #include <__functional/weak_result_type.h> 15 #include <__memory/addressof.h> 16 #include <__utility/forward.h> 17 #include <type_traits> 18 19 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20 # pragma GCC system_header 21 # pragma clang include_instead(<functional>) 22 #endif 23 24 _LIBCPP_BEGIN_NAMESPACE_STD 25 26 template <class _Tp> 27 class _LIBCPP_TEMPLATE_VIS reference_wrapper 28 #if _LIBCPP_STD_VER <= 17 || !defined(_LIBCPP_ABI_NO_BINDER_BASES) 29 : public __weak_result_type<_Tp> 30 #endif 31 { 32 public: 33 // types 34 typedef _Tp type; 35 private: 36 type* __f_; 37 38 static void __fun(_Tp&) _NOEXCEPT; 39 static void __fun(_Tp&&) = delete; 40 41 public: 42 template <class _Up, class = __enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value, decltype(__fun(declval<_Up>())) > > 43 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 44 reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(declval<_Up>()))) { 45 type& __f = static_cast<_Up&&>(__u); 46 __f_ = _VSTD::addressof(__f); 47 } 48 49 // access 50 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 51 operator type&() const _NOEXCEPT {return *__f_;} 52 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 53 type& get() const _NOEXCEPT {return *__f_;} 54 55 #ifndef _LIBCPP_CXX03_LANG 56 // invoke 57 template <class... _ArgTypes> 58 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 59 typename __invoke_of<type&, _ArgTypes...>::type 60 operator() (_ArgTypes&&... __args) const { 61 return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); 62 } 63 #else 64 65 _LIBCPP_INLINE_VISIBILITY 66 typename __invoke_return<type>::type 67 operator() () const { 68 return _VSTD::__invoke(get()); 69 } 70 71 template <class _A0> 72 _LIBCPP_INLINE_VISIBILITY 73 typename __invoke_return0<type, _A0>::type 74 operator() (_A0& __a0) const { 75 return _VSTD::__invoke(get(), __a0); 76 } 77 78 template <class _A0> 79 _LIBCPP_INLINE_VISIBILITY 80 typename __invoke_return0<type, _A0 const>::type 81 operator() (_A0 const& __a0) const { 82 return _VSTD::__invoke(get(), __a0); 83 } 84 85 template <class _A0, class _A1> 86 _LIBCPP_INLINE_VISIBILITY 87 typename __invoke_return1<type, _A0, _A1>::type 88 operator() (_A0& __a0, _A1& __a1) const { 89 return _VSTD::__invoke(get(), __a0, __a1); 90 } 91 92 template <class _A0, class _A1> 93 _LIBCPP_INLINE_VISIBILITY 94 typename __invoke_return1<type, _A0 const, _A1>::type 95 operator() (_A0 const& __a0, _A1& __a1) const { 96 return _VSTD::__invoke(get(), __a0, __a1); 97 } 98 99 template <class _A0, class _A1> 100 _LIBCPP_INLINE_VISIBILITY 101 typename __invoke_return1<type, _A0, _A1 const>::type 102 operator() (_A0& __a0, _A1 const& __a1) const { 103 return _VSTD::__invoke(get(), __a0, __a1); 104 } 105 106 template <class _A0, class _A1> 107 _LIBCPP_INLINE_VISIBILITY 108 typename __invoke_return1<type, _A0 const, _A1 const>::type 109 operator() (_A0 const& __a0, _A1 const& __a1) const { 110 return _VSTD::__invoke(get(), __a0, __a1); 111 } 112 113 template <class _A0, class _A1, class _A2> 114 _LIBCPP_INLINE_VISIBILITY 115 typename __invoke_return2<type, _A0, _A1, _A2>::type 116 operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { 117 return _VSTD::__invoke(get(), __a0, __a1, __a2); 118 } 119 120 template <class _A0, class _A1, class _A2> 121 _LIBCPP_INLINE_VISIBILITY 122 typename __invoke_return2<type, _A0 const, _A1, _A2>::type 123 operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { 124 return _VSTD::__invoke(get(), __a0, __a1, __a2); 125 } 126 127 template <class _A0, class _A1, class _A2> 128 _LIBCPP_INLINE_VISIBILITY 129 typename __invoke_return2<type, _A0, _A1 const, _A2>::type 130 operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { 131 return _VSTD::__invoke(get(), __a0, __a1, __a2); 132 } 133 134 template <class _A0, class _A1, class _A2> 135 _LIBCPP_INLINE_VISIBILITY 136 typename __invoke_return2<type, _A0, _A1, _A2 const>::type 137 operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { 138 return _VSTD::__invoke(get(), __a0, __a1, __a2); 139 } 140 141 template <class _A0, class _A1, class _A2> 142 _LIBCPP_INLINE_VISIBILITY 143 typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type 144 operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { 145 return _VSTD::__invoke(get(), __a0, __a1, __a2); 146 } 147 148 template <class _A0, class _A1, class _A2> 149 _LIBCPP_INLINE_VISIBILITY 150 typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type 151 operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { 152 return _VSTD::__invoke(get(), __a0, __a1, __a2); 153 } 154 155 template <class _A0, class _A1, class _A2> 156 _LIBCPP_INLINE_VISIBILITY 157 typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type 158 operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { 159 return _VSTD::__invoke(get(), __a0, __a1, __a2); 160 } 161 162 template <class _A0, class _A1, class _A2> 163 _LIBCPP_INLINE_VISIBILITY 164 typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type 165 operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { 166 return _VSTD::__invoke(get(), __a0, __a1, __a2); 167 } 168 #endif // _LIBCPP_CXX03_LANG 169 }; 170 171 #if _LIBCPP_STD_VER > 14 172 template <class _Tp> 173 reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; 174 #endif 175 176 template <class _Tp> 177 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 178 reference_wrapper<_Tp> 179 ref(_Tp& __t) _NOEXCEPT 180 { 181 return reference_wrapper<_Tp>(__t); 182 } 183 184 template <class _Tp> 185 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 186 reference_wrapper<_Tp> 187 ref(reference_wrapper<_Tp> __t) _NOEXCEPT 188 { 189 return __t; 190 } 191 192 template <class _Tp> 193 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 194 reference_wrapper<const _Tp> 195 cref(const _Tp& __t) _NOEXCEPT 196 { 197 return reference_wrapper<const _Tp>(__t); 198 } 199 200 template <class _Tp> 201 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 202 reference_wrapper<const _Tp> 203 cref(reference_wrapper<_Tp> __t) _NOEXCEPT 204 { 205 return __t; 206 } 207 208 template <class _Tp> void ref(const _Tp&&) = delete; 209 template <class _Tp> void cref(const _Tp&&) = delete; 210 211 _LIBCPP_END_NAMESPACE_STD 212 213 #endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H 214