refwrap.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. // Implementation of std::reference_wrapper -*- C++ -*-
  2. // Copyright (C) 2004-2018 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/c++0x_warning.h>
  29. #else
  30. #include <bits/move.h>
  31. #include <bits/invoke.h>
  32. #include <bits/stl_function.h> // for unary_function and binary_function
  33. namespace std _GLIBCXX_VISIBILITY(default)
  34. {
  35. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  36. /**
  37. * Derives from @c unary_function or @c binary_function, or perhaps
  38. * nothing, depending on the number of arguments provided. The
  39. * primary template is the basis case, which derives nothing.
  40. */
  41. template<typename _Res, typename... _ArgTypes>
  42. struct _Maybe_unary_or_binary_function { };
  43. /// Derives from @c unary_function, as appropriate.
  44. template<typename _Res, typename _T1>
  45. struct _Maybe_unary_or_binary_function<_Res, _T1>
  46. : std::unary_function<_T1, _Res> { };
  47. /// Derives from @c binary_function, as appropriate.
  48. template<typename _Res, typename _T1, typename _T2>
  49. struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
  50. : std::binary_function<_T1, _T2, _Res> { };
  51. template<typename _Signature>
  52. struct _Mem_fn_traits;
  53. template<typename _Res, typename _Class, typename... _ArgTypes>
  54. struct _Mem_fn_traits_base
  55. {
  56. using __result_type = _Res;
  57. using __maybe_type
  58. = _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>;
  59. using __arity = integral_constant<size_t, sizeof...(_ArgTypes)>;
  60. };
  61. #define _GLIBCXX_MEM_FN_TRAITS2(_CV, _REF, _LVAL, _RVAL) \
  62. template<typename _Res, typename _Class, typename... _ArgTypes> \
  63. struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) _CV _REF> \
  64. : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \
  65. { \
  66. using __vararg = false_type; \
  67. }; \
  68. template<typename _Res, typename _Class, typename... _ArgTypes> \
  69. struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF> \
  70. : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \
  71. { \
  72. using __vararg = true_type; \
  73. };
  74. #define _GLIBCXX_MEM_FN_TRAITS(_REF, _LVAL, _RVAL) \
  75. _GLIBCXX_MEM_FN_TRAITS2( , _REF, _LVAL, _RVAL) \
  76. _GLIBCXX_MEM_FN_TRAITS2(const , _REF, _LVAL, _RVAL) \
  77. _GLIBCXX_MEM_FN_TRAITS2(volatile , _REF, _LVAL, _RVAL) \
  78. _GLIBCXX_MEM_FN_TRAITS2(const volatile, _REF, _LVAL, _RVAL)
  79. _GLIBCXX_MEM_FN_TRAITS( , true_type, true_type)
  80. _GLIBCXX_MEM_FN_TRAITS(&, true_type, false_type)
  81. _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
  82. #if __cplusplus > 201402L
  83. _GLIBCXX_MEM_FN_TRAITS(noexcept, true_type, true_type)
  84. _GLIBCXX_MEM_FN_TRAITS(& noexcept, true_type, false_type)
  85. _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type)
  86. #endif
  87. #undef _GLIBCXX_MEM_FN_TRAITS
  88. #undef _GLIBCXX_MEM_FN_TRAITS2
  89. /// If we have found a result_type, extract it.
  90. template<typename _Functor, typename = __void_t<>>
  91. struct _Maybe_get_result_type
  92. { };
  93. template<typename _Functor>
  94. struct _Maybe_get_result_type<_Functor,
  95. __void_t<typename _Functor::result_type>>
  96. { typedef typename _Functor::result_type result_type; };
  97. /**
  98. * Base class for any function object that has a weak result type, as
  99. * defined in 20.8.2 [func.require] of C++11.
  100. */
  101. template<typename _Functor>
  102. struct _Weak_result_type_impl
  103. : _Maybe_get_result_type<_Functor>
  104. { };
  105. /// Retrieve the result type for a function type.
  106. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
  107. struct _Weak_result_type_impl<_Res(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL>
  108. { typedef _Res result_type; };
  109. /// Retrieve the result type for a varargs function type.
  110. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
  111. struct _Weak_result_type_impl<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
  112. { typedef _Res result_type; };
  113. /// Retrieve the result type for a function pointer.
  114. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
  115. struct _Weak_result_type_impl<_Res(*)(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL>
  116. { typedef _Res result_type; };
  117. /// Retrieve the result type for a varargs function pointer.
  118. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM>
  119. struct
  120. _Weak_result_type_impl<_Res(*)(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL>
  121. { typedef _Res result_type; };
  122. // Let _Weak_result_type_impl perform the real work.
  123. template<typename _Functor,
  124. bool = is_member_function_pointer<_Functor>::value>
  125. struct _Weak_result_type_memfun
  126. : _Weak_result_type_impl<_Functor>
  127. { };
  128. // A pointer to member function has a weak result type.
  129. template<typename _MemFunPtr>
  130. struct _Weak_result_type_memfun<_MemFunPtr, true>
  131. {
  132. using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type;
  133. };
  134. // A pointer to data member doesn't have a weak result type.
  135. template<typename _Func, typename _Class>
  136. struct _Weak_result_type_memfun<_Func _Class::*, false>
  137. { };
  138. /**
  139. * Strip top-level cv-qualifiers from the function object and let
  140. * _Weak_result_type_memfun perform the real work.
  141. */
  142. template<typename _Functor>
  143. struct _Weak_result_type
  144. : _Weak_result_type_memfun<typename remove_cv<_Functor>::type>
  145. { };
  146. // Detect nested argument_type.
  147. template<typename _Tp, typename = __void_t<>>
  148. struct _Refwrap_base_arg1
  149. { };
  150. // Nested argument_type.
  151. template<typename _Tp>
  152. struct _Refwrap_base_arg1<_Tp,
  153. __void_t<typename _Tp::argument_type>>
  154. {
  155. typedef typename _Tp::argument_type argument_type;
  156. };
  157. // Detect nested first_argument_type and second_argument_type.
  158. template<typename _Tp, typename = __void_t<>>
  159. struct _Refwrap_base_arg2
  160. { };
  161. // Nested first_argument_type and second_argument_type.
  162. template<typename _Tp>
  163. struct _Refwrap_base_arg2<_Tp,
  164. __void_t<typename _Tp::first_argument_type,
  165. typename _Tp::second_argument_type>>
  166. {
  167. typedef typename _Tp::first_argument_type first_argument_type;
  168. typedef typename _Tp::second_argument_type second_argument_type;
  169. };
  170. /**
  171. * Derives from unary_function or binary_function when it
  172. * can. Specializations handle all of the easy cases. The primary
  173. * template determines what to do with a class type, which may
  174. * derive from both unary_function and binary_function.
  175. */
  176. template<typename _Tp>
  177. struct _Reference_wrapper_base
  178. : _Weak_result_type<_Tp>, _Refwrap_base_arg1<_Tp>, _Refwrap_base_arg2<_Tp>
  179. { };
  180. // - a function type (unary)
  181. template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
  182. struct _Reference_wrapper_base<_Res(_T1) _GLIBCXX_NOEXCEPT_QUAL>
  183. : unary_function<_T1, _Res>
  184. { };
  185. template<typename _Res, typename _T1>
  186. struct _Reference_wrapper_base<_Res(_T1) const>
  187. : unary_function<_T1, _Res>
  188. { };
  189. template<typename _Res, typename _T1>
  190. struct _Reference_wrapper_base<_Res(_T1) volatile>
  191. : unary_function<_T1, _Res>
  192. { };
  193. template<typename _Res, typename _T1>
  194. struct _Reference_wrapper_base<_Res(_T1) const volatile>
  195. : unary_function<_T1, _Res>
  196. { };
  197. // - a function type (binary)
  198. template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
  199. struct _Reference_wrapper_base<_Res(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL>
  200. : binary_function<_T1, _T2, _Res>
  201. { };
  202. template<typename _Res, typename _T1, typename _T2>
  203. struct _Reference_wrapper_base<_Res(_T1, _T2) const>
  204. : binary_function<_T1, _T2, _Res>
  205. { };
  206. template<typename _Res, typename _T1, typename _T2>
  207. struct _Reference_wrapper_base<_Res(_T1, _T2) volatile>
  208. : binary_function<_T1, _T2, _Res>
  209. { };
  210. template<typename _Res, typename _T1, typename _T2>
  211. struct _Reference_wrapper_base<_Res(_T1, _T2) const volatile>
  212. : binary_function<_T1, _T2, _Res>
  213. { };
  214. // - a function pointer type (unary)
  215. template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
  216. struct _Reference_wrapper_base<_Res(*)(_T1) _GLIBCXX_NOEXCEPT_QUAL>
  217. : unary_function<_T1, _Res>
  218. { };
  219. // - a function pointer type (binary)
  220. template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
  221. struct _Reference_wrapper_base<_Res(*)(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL>
  222. : binary_function<_T1, _T2, _Res>
  223. { };
  224. template<typename _Tp, bool = is_member_function_pointer<_Tp>::value>
  225. struct _Reference_wrapper_base_memfun
  226. : _Reference_wrapper_base<_Tp>
  227. { };
  228. template<typename _MemFunPtr>
  229. struct _Reference_wrapper_base_memfun<_MemFunPtr, true>
  230. : _Mem_fn_traits<_MemFunPtr>::__maybe_type
  231. {
  232. using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type;
  233. };
  234. /**
  235. * @brief Primary class template for reference_wrapper.
  236. * @ingroup functors
  237. * @{
  238. */
  239. template<typename _Tp>
  240. class reference_wrapper
  241. : public _Reference_wrapper_base_memfun<typename remove_cv<_Tp>::type>
  242. {
  243. _Tp* _M_data;
  244. public:
  245. typedef _Tp type;
  246. reference_wrapper(_Tp& __indata) noexcept
  247. : _M_data(std::__addressof(__indata))
  248. { }
  249. reference_wrapper(_Tp&&) = delete;
  250. reference_wrapper(const reference_wrapper&) = default;
  251. reference_wrapper&
  252. operator=(const reference_wrapper&) = default;
  253. operator _Tp&() const noexcept
  254. { return this->get(); }
  255. _Tp&
  256. get() const noexcept
  257. { return *_M_data; }
  258. template<typename... _Args>
  259. typename result_of<_Tp&(_Args&&...)>::type
  260. operator()(_Args&&... __args) const
  261. {
  262. return std::__invoke(get(), std::forward<_Args>(__args)...);
  263. }
  264. };
  265. /// Denotes a reference should be taken to a variable.
  266. template<typename _Tp>
  267. inline reference_wrapper<_Tp>
  268. ref(_Tp& __t) noexcept
  269. { return reference_wrapper<_Tp>(__t); }
  270. /// Denotes a const reference should be taken to a variable.
  271. template<typename _Tp>
  272. inline reference_wrapper<const _Tp>
  273. cref(const _Tp& __t) noexcept
  274. { return reference_wrapper<const _Tp>(__t); }
  275. template<typename _Tp>
  276. void ref(const _Tp&&) = delete;
  277. template<typename _Tp>
  278. void cref(const _Tp&&) = delete;
  279. /// std::ref overload to prevent wrapping a reference_wrapper
  280. template<typename _Tp>
  281. inline reference_wrapper<_Tp>
  282. ref(reference_wrapper<_Tp> __t) noexcept
  283. { return __t; }
  284. /// std::cref overload to prevent wrapping a reference_wrapper
  285. template<typename _Tp>
  286. inline reference_wrapper<const _Tp>
  287. cref(reference_wrapper<_Tp> __t) noexcept
  288. { return { __t.get() }; }
  289. // @} group functors
  290. _GLIBCXX_END_NAMESPACE_VERSION
  291. } // namespace std
  292. #endif // C++11
  293. #endif // _GLIBCXX_REFWRAP_H