refwrap.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // Implementation of std::reference_wrapper -*- C++ -*-
  2. // Copyright (C) 2004-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file include/bits/refwrap.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{functional}
  23. */
  24. #ifndef _GLIBCXX_REFWRAP_H
  25. #define _GLIBCXX_REFWRAP_H 1
  26. #pragma GCC system_header
  27. #if __cplusplus >= 201103L
  28. #include <bits/move.h>
  29. #include <bits/invoke.h>
  30. #include <bits/stl_function.h> // for unary_function and binary_function
  31. namespace std _GLIBCXX_VISIBILITY(default)
  32. {
  33. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  34. /// @cond undocumented
  35. /**
  36. * Derives from @c unary_function or @c binary_function, or perhaps
  37. * nothing, depending on the number of arguments provided. The
  38. * primary template is the basis case, which derives nothing.
  39. */
  40. template<typename _Res, typename... _ArgTypes>
  41. struct _Maybe_unary_or_binary_function { };
  42. // Ignore warnings about unary_function and binary_function.
  43. #pragma GCC diagnostic push
  44. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  45. /// Derives from @c unary_function, as appropriate.
  46. template<typename _Res, typename _T1>
  47. struct _Maybe_unary_or_binary_function<_Res, _T1>
  48. : std::unary_function<_T1, _Res> { };
  49. /// Derives from @c binary_function, as appropriate.
  50. template<typename _Res, typename _T1, typename _T2>
  51. struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
  52. : std::binary_function<_T1, _T2, _Res> { };
  53. #pragma GCC diagnostic pop
  54. template<typename _Signature>
  55. struct _Mem_fn_traits;
  56. template<typename _Res, typename _Class, typename... _ArgTypes>
  57. struct _Mem_fn_traits_base
  58. {
  59. using __result_type = _Res;
  60. using __maybe_type
  61. = _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>;
  62. using __arity = integral_constant<size_t, sizeof...(_ArgTypes)>;
  63. };
  64. #define _GLIBCXX_MEM_FN_TRAITS2(_CV, _REF, _LVAL, _RVAL) \
  65. template<typename _Res, typename _Class, typename... _ArgTypes> \
  66. struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) _CV _REF> \
  67. : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \
  68. { \
  69. using __vararg = false_type; \
  70. }; \
  71. template<typename _Res, typename _Class, typename... _ArgTypes> \
  72. struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF> \
  73. : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \
  74. { \
  75. using __vararg = true_type; \
  76. };
  77. #define _GLIBCXX_MEM_FN_TRAITS(_REF, _LVAL, _RVAL) \
  78. _GLIBCXX_MEM_FN_TRAITS2( , _REF, _LVAL, _RVAL) \
  79. _GLIBCXX_MEM_FN_TRAITS2(const , _REF, _LVAL, _RVAL) \
  80. _GLIBCXX_MEM_FN_TRAITS2(volatile , _REF, _LVAL, _RVAL) \
  81. _GLIBCXX_MEM_FN_TRAITS2(const volatile, _REF, _LVAL, _RVAL)
  82. _GLIBCXX_MEM_FN_TRAITS( , true_type, true_type)
  83. _GLIBCXX_MEM_FN_TRAITS(&, true_type, false_type)
  84. _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
  85. #if __cplusplus > 201402L
  86. _GLIBCXX_MEM_FN_TRAITS(noexcept, true_type, true_type)
  87. _GLIBCXX_MEM_FN_TRAITS(& noexcept, true_type, false_type)
  88. _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
  89. #endif
  90. #undef _GLIBCXX_MEM_FN_TRAITS
  91. #undef _GLIBCXX_MEM_FN_TRAITS2
  92. /// If we have found a result_type, extract it.
  93. template<typename _Functor, typename = __void_t<>>
  94. struct _Maybe_get_result_type
  95. { };
  96. template<typename _Functor>
  97. struct _Maybe_get_result_type<_Functor,
  98. __void_t<typename _Functor::result_type>>
  99. { typedef typename _Functor::result_type result_type; };
  100. /**
  101. * Base class for any function object that has a weak result type, as
  102. * defined in 20.8.2 [func.require] of C++11.
  103. */
  104. template<typename _Functor>
  105. struct _Weak_result_type_impl
  106. : _Maybe_get_result_type<_Functor>
  107. { };
  108. /// Retrieve the result type for a function type.
  109. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
  110. struct _Weak_result_type_impl<_Res(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL>
  111. { typedef _Res result_type; };
  112. /// Retrieve the result type for a varargs function type.
  113. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
  114. struct _Weak_result_type_impl<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
  115. { typedef _Res result_type; };
  116. /// Retrieve the result type for a function pointer.
  117. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
  118. struct _Weak_result_type_impl<_Res(*)(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL>
  119. { typedef _Res result_type; };
  120. /// Retrieve the result type for a varargs function pointer.
  121. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
  122. struct
  123. _Weak_result_type_impl<_Res(*)(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
  124. { typedef _Res result_type; };
  125. // Let _Weak_result_type_impl perform the real work.
  126. template<typename _Functor,
  127. bool = is_member_function_pointer<_Functor>::value>
  128. struct _Weak_result_type_memfun
  129. : _Weak_result_type_impl<_Functor>
  130. { };
  131. // A pointer to member function has a weak result type.
  132. template<typename _MemFunPtr>
  133. struct _Weak_result_type_memfun<_MemFunPtr, true>
  134. {
  135. using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type;
  136. };
  137. // A pointer to data member doesn't have a weak result type.
  138. template<typename _Func, typename _Class>
  139. struct _Weak_result_type_memfun<_Func _Class::*, false>
  140. { };
  141. /**
  142. * Strip top-level cv-qualifiers from the function object and let
  143. * _Weak_result_type_memfun perform the real work.
  144. */
  145. template<typename _Functor>
  146. struct _Weak_result_type
  147. : _Weak_result_type_memfun<typename remove_cv<_Functor>::type>
  148. { };
  149. #if __cplusplus <= 201703L
  150. // Detect nested argument_type.
  151. template<typename _Tp, typename = __void_t<>>
  152. struct _Refwrap_base_arg1
  153. { };
  154. // Nested argument_type.
  155. template<typename _Tp>
  156. struct _Refwrap_base_arg1<_Tp,
  157. __void_t<typename _Tp::argument_type>>
  158. {
  159. typedef typename _Tp::argument_type argument_type;
  160. };
  161. // Detect nested first_argument_type and second_argument_type.
  162. template<typename _Tp, typename = __void_t<>>
  163. struct _Refwrap_base_arg2
  164. { };
  165. // Nested first_argument_type and second_argument_type.
  166. template<typename _Tp>
  167. struct _Refwrap_base_arg2<_Tp,
  168. __void_t<typename _Tp::first_argument_type,
  169. typename _Tp::second_argument_type>>
  170. {
  171. typedef typename _Tp::first_argument_type first_argument_type;
  172. typedef typename _Tp::second_argument_type second_argument_type;
  173. };
  174. /**
  175. * Derives from unary_function or binary_function when it
  176. * can. Specializations handle all of the easy cases. The primary
  177. * template determines what to do with a class type, which may
  178. * derive from both unary_function and binary_function.
  179. */
  180. template<typename _Tp>
  181. struct _Reference_wrapper_base
  182. : _Weak_result_type<_Tp>, _Refwrap_base_arg1<_Tp>, _Refwrap_base_arg2<_Tp>
  183. { };
  184. // Ignore warnings about unary_function and binary_function.
  185. #pragma GCC diagnostic push
  186. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  187. // - a function type (unary)
  188. template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
  189. struct _Reference_wrapper_base<_Res(_T1) _GLIBCXX_NOEXCEPT_QUAL>
  190. : unary_function<_T1, _Res>
  191. { };
  192. template<typename _Res, typename _T1>
  193. struct _Reference_wrapper_base<_Res(_T1) const>
  194. : unary_function<_T1, _Res>
  195. { };
  196. template<typename _Res, typename _T1>
  197. struct _Reference_wrapper_base<_Res(_T1) volatile>
  198. : unary_function<_T1, _Res>
  199. { };
  200. template<typename _Res, typename _T1>
  201. struct _Reference_wrapper_base<_Res(_T1) const volatile>
  202. : unary_function<_T1, _Res>
  203. { };
  204. // - a function type (binary)
  205. template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
  206. struct _Reference_wrapper_base<_Res(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL>
  207. : binary_function<_T1, _T2, _Res>
  208. { };
  209. template<typename _Res, typename _T1, typename _T2>
  210. struct _Reference_wrapper_base<_Res(_T1, _T2) const>
  211. : binary_function<_T1, _T2, _Res>
  212. { };
  213. template<typename _Res, typename _T1, typename _T2>
  214. struct _Reference_wrapper_base<_Res(_T1, _T2) volatile>
  215. : binary_function<_T1, _T2, _Res>
  216. { };
  217. template<typename _Res, typename _T1, typename _T2>
  218. struct _Reference_wrapper_base<_Res(_T1, _T2) const volatile>
  219. : binary_function<_T1, _T2, _Res>
  220. { };
  221. // - a function pointer type (unary)
  222. template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
  223. struct _Reference_wrapper_base<_Res(*)(_T1) _GLIBCXX_NOEXCEPT_QUAL>
  224. : unary_function<_T1, _Res>
  225. { };
  226. // - a function pointer type (binary)
  227. template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
  228. struct _Reference_wrapper_base<_Res(*)(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL>
  229. : binary_function<_T1, _T2, _Res>
  230. { };
  231. template<typename _Tp, bool = is_member_function_pointer<_Tp>::value>
  232. struct _Reference_wrapper_base_memfun
  233. : _Reference_wrapper_base<_Tp>
  234. { };
  235. template<typename _MemFunPtr>
  236. struct _Reference_wrapper_base_memfun<_MemFunPtr, true>
  237. : _Mem_fn_traits<_MemFunPtr>::__maybe_type
  238. {
  239. using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type;
  240. };
  241. #pragma GCC diagnostic pop
  242. #endif // ! C++20
  243. /// @endcond
  244. /**
  245. * @brief Primary class template for reference_wrapper.
  246. * @ingroup functors
  247. */
  248. template<typename _Tp>
  249. class reference_wrapper
  250. #if __cplusplus <= 201703L
  251. // In C++20 std::reference_wrapper<T> allows T to be incomplete,
  252. // so checking for nested types could result in ODR violations.
  253. : public _Reference_wrapper_base_memfun<typename remove_cv<_Tp>::type>
  254. #endif
  255. {
  256. _Tp* _M_data;
  257. _GLIBCXX20_CONSTEXPR
  258. static _Tp* _S_fun(_Tp& __r) noexcept { return std::__addressof(__r); }
  259. static void _S_fun(_Tp&&) = delete;
  260. template<typename _Up, typename _Up2 = __remove_cvref_t<_Up>>
  261. using __not_same
  262. = typename enable_if<!is_same<reference_wrapper, _Up2>::value>::type;
  263. public:
  264. typedef _Tp type;
  265. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  266. // 2993. reference_wrapper<T> conversion from T&&
  267. // 3041. Unnecessary decay in reference_wrapper
  268. template<typename _Up, typename = __not_same<_Up>, typename
  269. = decltype(reference_wrapper::_S_fun(std::declval<_Up>()))>
  270. _GLIBCXX20_CONSTEXPR
  271. reference_wrapper(_Up&& __uref)
  272. noexcept(noexcept(reference_wrapper::_S_fun(std::declval<_Up>())))
  273. : _M_data(reference_wrapper::_S_fun(std::forward<_Up>(__uref)))
  274. { }
  275. reference_wrapper(const reference_wrapper&) = default;
  276. reference_wrapper&
  277. operator=(const reference_wrapper&) = default;
  278. _GLIBCXX20_CONSTEXPR
  279. operator _Tp&() const noexcept
  280. { return this->get(); }
  281. _GLIBCXX20_CONSTEXPR
  282. _Tp&
  283. get() const noexcept
  284. { return *_M_data; }
  285. template<typename... _Args>
  286. _GLIBCXX20_CONSTEXPR
  287. typename result_of<_Tp&(_Args&&...)>::type
  288. operator()(_Args&&... __args) const
  289. {
  290. #if __cplusplus > 201703L
  291. if constexpr (is_object_v<type>)
  292. static_assert(sizeof(type), "type must be complete");
  293. #endif
  294. return std::__invoke(get(), std::forward<_Args>(__args)...);
  295. }
  296. };
  297. #if __cpp_deduction_guides
  298. template<typename _Tp>
  299. reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
  300. #endif
  301. /// @relates reference_wrapper @{
  302. /// Denotes a reference should be taken to a variable.
  303. template<typename _Tp>
  304. _GLIBCXX20_CONSTEXPR
  305. inline reference_wrapper<_Tp>
  306. ref(_Tp& __t) noexcept
  307. { return reference_wrapper<_Tp>(__t); }
  308. /// Denotes a const reference should be taken to a variable.
  309. template<typename _Tp>
  310. _GLIBCXX20_CONSTEXPR
  311. inline reference_wrapper<const _Tp>
  312. cref(const _Tp& __t) noexcept
  313. { return reference_wrapper<const _Tp>(__t); }
  314. template<typename _Tp>
  315. void ref(const _Tp&&) = delete;
  316. template<typename _Tp>
  317. void cref(const _Tp&&) = delete;
  318. /// std::ref overload to prevent wrapping a reference_wrapper
  319. template<typename _Tp>
  320. _GLIBCXX20_CONSTEXPR
  321. inline reference_wrapper<_Tp>
  322. ref(reference_wrapper<_Tp> __t) noexcept
  323. { return __t; }
  324. /// std::cref overload to prevent wrapping a reference_wrapper
  325. template<typename _Tp>
  326. _GLIBCXX20_CONSTEXPR
  327. inline reference_wrapper<const _Tp>
  328. cref(reference_wrapper<_Tp> __t) noexcept
  329. { return { __t.get() }; }
  330. /// @}
  331. _GLIBCXX_END_NAMESPACE_VERSION
  332. } // namespace std
  333. #endif // C++11
  334. #endif // _GLIBCXX_REFWRAP_H