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. // (glenjofe@gmail.com)
  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. // reference_wrapper
  40. /**
  41. @brief Contains a reference to an object of type `T`.
  42. `reference_wrapper` is primarily used to "feed" references to
  43. function templates (algorithms) that take their parameter by
  44. value. It provides an implicit conversion to `T&`, which
  45. usually allows the function templates to work on references
  46. unmodified.
  47. */
  48. template<class T> class reference_wrapper
  49. {
  50. public:
  51. /**
  52. Type `T`.
  53. */
  54. typedef T type;
  55. /**
  56. Constructs a `reference_wrapper` object that stores a
  57. reference to `t`.
  58. @remark Does not throw.
  59. */
  60. BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
  61. #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
  62. BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {}
  63. #endif
  64. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  65. /**
  66. @remark Construction from a temporary object is disabled.
  67. */
  68. BOOST_DELETED_FUNCTION(reference_wrapper(T&& t))
  69. public:
  70. #endif
  71. /**
  72. @return The stored reference.
  73. @remark Does not throw.
  74. */
  75. BOOST_FORCEINLINE operator T& () const { return *t_; }
  76. /**
  77. @return The stored reference.
  78. @remark Does not throw.
  79. */
  80. BOOST_FORCEINLINE T& get() const { return *t_; }
  81. /**
  82. @return A pointer to the object referenced by the stored
  83. reference.
  84. @remark Does not throw.
  85. */
  86. BOOST_FORCEINLINE T* get_pointer() const { return t_; }
  87. private:
  88. T* t_;
  89. };
  90. // ref
  91. /**
  92. @cond
  93. */
  94. #if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
  95. # define BOOST_REF_CONST
  96. #else
  97. # define BOOST_REF_CONST const
  98. #endif
  99. /**
  100. @endcond
  101. */
  102. /**
  103. @return `reference_wrapper<T>(t)`
  104. @remark Does not throw.
  105. */
  106. template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t )
  107. {
  108. #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
  109. return reference_wrapper<T>( t, ref_workaround_tag() );
  110. #else
  111. return reference_wrapper<T>( t );
  112. #endif
  113. }
  114. // cref
  115. /**
  116. @return `reference_wrapper<T const>(t)`
  117. @remark Does not throw.
  118. */
  119. template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t )
  120. {
  121. return reference_wrapper<T const>(t);
  122. }
  123. #undef BOOST_REF_CONST
  124. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  125. /**
  126. @cond
  127. */
  128. #if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
  129. # define BOOST_REF_DELETE
  130. #else
  131. # define BOOST_REF_DELETE = delete
  132. #endif
  133. /**
  134. @endcond
  135. */
  136. /**
  137. @remark Construction from a temporary object is disabled.
  138. */
  139. template<class T> void ref(T const&&) BOOST_REF_DELETE;
  140. /**
  141. @remark Construction from a temporary object is disabled.
  142. */
  143. template<class T> void cref(T const&&) BOOST_REF_DELETE;
  144. #undef BOOST_REF_DELETE
  145. #endif
  146. // is_reference_wrapper
  147. /**
  148. @brief Determine if a type `T` is an instantiation of
  149. `reference_wrapper`.
  150. The value static constant will be true if the type `T` is a
  151. specialization of `reference_wrapper`.
  152. */
  153. template<typename T> struct is_reference_wrapper
  154. {
  155. BOOST_STATIC_CONSTANT( bool, value = false );
  156. };
  157. /**
  158. @cond
  159. */
  160. template<typename T> struct is_reference_wrapper< reference_wrapper<T> >
  161. {
  162. BOOST_STATIC_CONSTANT( bool, value = true );
  163. };
  164. #if !defined(BOOST_NO_CV_SPECIALIZATIONS)
  165. template<typename T> struct is_reference_wrapper< reference_wrapper<T> const >
  166. {
  167. BOOST_STATIC_CONSTANT( bool, value = true );
  168. };
  169. template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile >
  170. {
  171. BOOST_STATIC_CONSTANT( bool, value = true );
  172. };
  173. template<typename T> struct is_reference_wrapper< reference_wrapper<T> const volatile >
  174. {
  175. BOOST_STATIC_CONSTANT( bool, value = true );
  176. };
  177. #endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
  178. /**
  179. @endcond
  180. */
  181. // unwrap_reference
  182. /**
  183. @brief Find the type in a `reference_wrapper`.
  184. The `typedef` type is `T::type` if `T` is a
  185. `reference_wrapper`, `T` otherwise.
  186. */
  187. template<typename T> struct unwrap_reference
  188. {
  189. typedef T type;
  190. };
  191. /**
  192. @cond
  193. */
  194. template<typename T> struct unwrap_reference< reference_wrapper<T> >
  195. {
  196. typedef T type;
  197. };
  198. #if !defined(BOOST_NO_CV_SPECIALIZATIONS)
  199. template<typename T> struct unwrap_reference< reference_wrapper<T> const >
  200. {
  201. typedef T type;
  202. };
  203. template<typename T> struct unwrap_reference< reference_wrapper<T> volatile >
  204. {
  205. typedef T type;
  206. };
  207. template<typename T> struct unwrap_reference< reference_wrapper<T> const volatile >
  208. {
  209. typedef T type;
  210. };
  211. #endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
  212. /**
  213. @endcond
  214. */
  215. // unwrap_ref
  216. /**
  217. @return `unwrap_reference<T>::type&(t)`
  218. @remark Does not throw.
  219. */
  220. template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t )
  221. {
  222. return t;
  223. }
  224. // get_pointer
  225. /**
  226. @cond
  227. */
  228. template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r )
  229. {
  230. return r.get_pointer();
  231. }
  232. /**
  233. @endcond
  234. */
  235. } // namespace boost
  236. #endif // #ifndef BOOST_CORE_REF_HPP