ref.hpp 5.8 KB

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