ref.hpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #ifndef BOOST_CORE_REF_HPP
  2. #define BOOST_CORE_REF_HPP
  3. #include <boost/config.hpp>
  4. #include <boost/config/workaround.hpp>
  5. #include <boost/core/addressof.hpp>
  6. #include <boost/core/enable_if.hpp>
  7. #if defined(BOOST_HAS_PRAGMA_ONCE)
  8. # pragma once
  9. #endif
  10. //
  11. // ref.hpp - ref/cref, useful helper functions
  12. //
  13. // Copyright (C) 1999, 2000 Jaakko Jarvi ([email protected])
  14. // Copyright (C) 2001, 2002 Peter Dimov
  15. // Copyright (C) 2002 David Abrahams
  16. //
  17. // Copyright (C) 2014 Glen Joseph Fernandes
  18. // ([email protected])
  19. //
  20. // Copyright (C) 2014 Agustin Berge
  21. //
  22. // Distributed under the Boost Software License, Version 1.0. (See
  23. // accompanying file LICENSE_1_0.txt or copy at
  24. // http://www.boost.org/LICENSE_1_0.txt)
  25. //
  26. // See http://www.boost.org/libs/core/doc/html/core/ref.html for documentation.
  27. //
  28. /**
  29. @file
  30. */
  31. /**
  32. Boost namespace.
  33. */
  34. namespace boost
  35. {
  36. #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
  37. struct ref_workaround_tag {};
  38. #endif
  39. namespace detail
  40. {
  41. template< class Y, class T > struct ref_convertible
  42. {
  43. typedef char (&yes) [1];
  44. typedef char (&no) [2];
  45. static yes f( T* );
  46. static no f( ... );
  47. enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
  48. };
  49. #if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
  50. struct ref_empty
  51. {
  52. };
  53. #endif
  54. } // namespace detail
  55. // reference_wrapper
  56. /**
  57. @brief Contains a reference to an object of type `T`.
  58. `reference_wrapper` is primarily used to "feed" references to
  59. function templates (algorithms) that take their parameter by
  60. value. It provides an implicit conversion to `T&`, which
  61. usually allows the function templates to work on references
  62. unmodified.
  63. */
  64. template<class T> class reference_wrapper
  65. {
  66. public:
  67. /**
  68. Type `T`.
  69. */
  70. typedef T type;
  71. /**
  72. Constructs a `reference_wrapper` object that stores a
  73. reference to `t`.
  74. @remark Does not throw.
  75. */
  76. BOOST_FORCEINLINE explicit reference_wrapper(T& t) BOOST_NOEXCEPT : t_(boost::addressof(t)) {}
  77. #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
  78. BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ) BOOST_NOEXCEPT : t_( boost::addressof( t ) ) {}
  79. #endif
  80. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  81. /**
  82. @remark Construction from a temporary object is disabled.
  83. */
  84. BOOST_DELETED_FUNCTION(reference_wrapper(T&& t))
  85. public:
  86. #endif
  87. template<class Y> friend class reference_wrapper;
  88. /**
  89. Constructs a `reference_wrapper` object that stores the
  90. reference stored in the compatible `reference_wrapper` `r`.
  91. @remark Only enabled when `Y*` is convertible to `T*`.
  92. @remark Does not throw.
  93. */
  94. #if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
  95. template<class Y, class = typename enable_if_c<boost::detail::ref_convertible<Y, T>::value>::type>
  96. reference_wrapper( reference_wrapper<Y> r ) BOOST_NOEXCEPT : t_( r.t_ )
  97. {
  98. }
  99. #else
  100. template<class Y> reference_wrapper( reference_wrapper<Y> r,
  101. typename enable_if_c<boost::detail::ref_convertible<Y, T>::value,
  102. boost::detail::ref_empty>::type = boost::detail::ref_empty() ) BOOST_NOEXCEPT : t_( r.t_ )
  103. {
  104. }
  105. #endif
  106. /**
  107. @return The stored reference.
  108. @remark Does not throw.
  109. */
  110. BOOST_FORCEINLINE operator T& () const BOOST_NOEXCEPT { return *t_; }
  111. /**
  112. @return The stored reference.
  113. @remark Does not throw.
  114. */
  115. BOOST_FORCEINLINE T& get() const BOOST_NOEXCEPT { return *t_; }
  116. /**
  117. @return A pointer to the object referenced by the stored
  118. reference.
  119. @remark Does not throw.
  120. */
  121. BOOST_FORCEINLINE T* get_pointer() const BOOST_NOEXCEPT { return t_; }
  122. private:
  123. T* t_;
  124. };
  125. // ref
  126. /**
  127. @cond
  128. */
  129. #if defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) )
  130. # define BOOST_REF_CONST
  131. #else
  132. # define BOOST_REF_CONST const
  133. #endif
  134. /**
  135. @endcond
  136. */
  137. /**
  138. @return `reference_wrapper<T>(t)`
  139. @remark Does not throw.
  140. */
  141. template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t ) BOOST_NOEXCEPT
  142. {
  143. #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
  144. return reference_wrapper<T>( t, ref_workaround_tag() );
  145. #else
  146. return reference_wrapper<T>( t );
  147. #endif
  148. }
  149. // cref
  150. /**
  151. @return `reference_wrapper<T const>(t)`
  152. @remark Does not throw.
  153. */
  154. template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t ) BOOST_NOEXCEPT
  155. {
  156. return reference_wrapper<T const>(t);
  157. }
  158. #undef BOOST_REF_CONST
  159. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  160. /**
  161. @cond
  162. */
  163. #if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
  164. # define BOOST_REF_DELETE
  165. #else
  166. # define BOOST_REF_DELETE = delete
  167. #endif
  168. /**
  169. @endcond
  170. */
  171. /**
  172. @remark Construction from a temporary object is disabled.
  173. */
  174. template<class T> void ref(T const&&) BOOST_REF_DELETE;
  175. /**
  176. @remark Construction from a temporary object is disabled.
  177. */
  178. template<class T> void cref(T const&&) BOOST_REF_DELETE;
  179. #undef BOOST_REF_DELETE
  180. #endif
  181. // is_reference_wrapper
  182. /**
  183. @brief Determine if a type `T` is an instantiation of
  184. `reference_wrapper`.
  185. The value static constant will be true if the type `T` is a
  186. specialization of `reference_wrapper`.
  187. */
  188. template<typename T> struct is_reference_wrapper
  189. {
  190. BOOST_STATIC_CONSTANT( bool, value = false );
  191. };
  192. /**
  193. @cond
  194. */
  195. template<typename T> struct is_reference_wrapper< reference_wrapper<T> >
  196. {
  197. BOOST_STATIC_CONSTANT( bool, value = true );
  198. };
  199. #if !defined(BOOST_NO_CV_SPECIALIZATIONS)
  200. template<typename T> struct is_reference_wrapper< reference_wrapper<T> const >
  201. {
  202. BOOST_STATIC_CONSTANT( bool, value = true );
  203. };
  204. template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile >
  205. {
  206. BOOST_STATIC_CONSTANT( bool, value = true );
  207. };
  208. template<typename T> struct is_reference_wrapper< reference_wrapper<T> const volatile >
  209. {
  210. BOOST_STATIC_CONSTANT( bool, value = true );
  211. };
  212. #endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
  213. /**
  214. @endcond
  215. */
  216. // unwrap_reference
  217. /**
  218. @brief Find the type in a `reference_wrapper`.
  219. The `typedef` type is `T::type` if `T` is a
  220. `reference_wrapper`, `T` otherwise.
  221. */
  222. template<typename T> struct unwrap_reference
  223. {
  224. typedef T type;
  225. };
  226. /**
  227. @cond
  228. */
  229. template<typename T> struct unwrap_reference< reference_wrapper<T> >
  230. {
  231. typedef T type;
  232. };
  233. #if !defined(BOOST_NO_CV_SPECIALIZATIONS)
  234. template<typename T> struct unwrap_reference< reference_wrapper<T> const >
  235. {
  236. typedef T type;
  237. };
  238. template<typename T> struct unwrap_reference< reference_wrapper<T> volatile >
  239. {
  240. typedef T type;
  241. };
  242. template<typename T> struct unwrap_reference< reference_wrapper<T> const volatile >
  243. {
  244. typedef T type;
  245. };
  246. #endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
  247. /**
  248. @endcond
  249. */
  250. // unwrap_ref
  251. /**
  252. @return `unwrap_reference<T>::type&(t)`
  253. @remark Does not throw.
  254. */
  255. template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t ) BOOST_NOEXCEPT
  256. {
  257. return t;
  258. }
  259. // get_pointer
  260. /**
  261. @cond
  262. */
  263. template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r ) BOOST_NOEXCEPT
  264. {
  265. return r.get_pointer();
  266. }
  267. /**
  268. @endcond
  269. */
  270. } // namespace boost
  271. #endif // #ifndef BOOST_CORE_REF_HPP