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