ref.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #ifndef BOOST_REF_HPP_INCLUDED
  2. #define BOOST_REF_HPP_INCLUDED
  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/utility/addressof.hpp>
  9. #include <boost/mpl/bool.hpp>
  10. #include <boost/detail/workaround.hpp>
  11. //
  12. // ref.hpp - ref/cref, useful helper functions
  13. //
  14. // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
  15. // Copyright (C) 2001, 2002 Peter Dimov
  16. // Copyright (C) 2002 David Abrahams
  17. //
  18. // Distributed under the Boost Software License, Version 1.0. (See
  19. // accompanying file LICENSE_1_0.txt or copy at
  20. // http://www.boost.org/LICENSE_1_0.txt)
  21. //
  22. // See http://www.boost.org/libs/bind/ref.html for documentation.
  23. //
  24. namespace boost
  25. {
  26. template<class T> class reference_wrapper
  27. {
  28. public:
  29. typedef T type;
  30. #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 )
  31. explicit reference_wrapper(T& t): t_(&t) {}
  32. #else
  33. explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
  34. #endif
  35. operator T& () const { return *t_; }
  36. T& get() const { return *t_; }
  37. T* get_pointer() const { return t_; }
  38. private:
  39. T* t_;
  40. };
  41. # if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
  42. # define BOOST_REF_CONST
  43. # else
  44. # define BOOST_REF_CONST const
  45. # endif
  46. template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t)
  47. {
  48. return reference_wrapper<T>(t);
  49. }
  50. template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const & t)
  51. {
  52. return reference_wrapper<T const>(t);
  53. }
  54. # undef BOOST_REF_CONST
  55. # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  56. template<typename T>
  57. class is_reference_wrapper
  58. : public mpl::false_
  59. {
  60. };
  61. template<typename T>
  62. class unwrap_reference
  63. {
  64. public:
  65. typedef T type;
  66. };
  67. # define AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(X) \
  68. template<typename T> \
  69. class is_reference_wrapper< X > \
  70. : public mpl::true_ \
  71. { \
  72. }; \
  73. \
  74. template<typename T> \
  75. class unwrap_reference< X > \
  76. { \
  77. public: \
  78. typedef T type; \
  79. }; \
  80. /**/
  81. AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T>)
  82. #if !defined(BOOST_NO_CV_SPECIALIZATIONS)
  83. AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const)
  84. AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> volatile)
  85. AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const volatile)
  86. #endif
  87. # undef AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF
  88. # else // no partial specialization
  89. } // namespace boost
  90. #include <boost/type.hpp>
  91. namespace boost
  92. {
  93. namespace detail
  94. {
  95. typedef char (&yes_reference_wrapper_t)[1];
  96. typedef char (&no_reference_wrapper_t)[2];
  97. no_reference_wrapper_t is_reference_wrapper_test(...);
  98. template<typename T>
  99. yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper<T> >);
  100. template<bool wrapped>
  101. struct reference_unwrapper
  102. {
  103. template <class T>
  104. struct apply
  105. {
  106. typedef T type;
  107. };
  108. };
  109. template<>
  110. struct reference_unwrapper<true>
  111. {
  112. template <class T>
  113. struct apply
  114. {
  115. typedef typename T::type type;
  116. };
  117. };
  118. }
  119. template<typename T>
  120. class is_reference_wrapper
  121. {
  122. public:
  123. BOOST_STATIC_CONSTANT(
  124. bool, value = (
  125. sizeof(detail::is_reference_wrapper_test(type<T>()))
  126. == sizeof(detail::yes_reference_wrapper_t)));
  127. typedef ::boost::mpl::bool_<value> type;
  128. };
  129. template <typename T>
  130. class unwrap_reference
  131. : public detail::reference_unwrapper<
  132. is_reference_wrapper<T>::value
  133. >::template apply<T>
  134. {};
  135. # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  136. template <class T> inline typename unwrap_reference<T>::type&
  137. unwrap_ref(T& t)
  138. {
  139. return t;
  140. }
  141. template<class T> inline T* get_pointer( reference_wrapper<T> const & r )
  142. {
  143. return r.get_pointer();
  144. }
  145. } // namespace boost
  146. #endif // #ifndef BOOST_REF_HPP_INCLUDED