is_lvalue_iterator.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright David Abrahams 2003. Use, modification and distribution is
  2. // subject to the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
  5. # define IS_LVALUE_ITERATOR_DWA2003112_HPP
  6. #include <boost/detail/workaround.hpp>
  7. #include <boost/type_traits/add_lvalue_reference.hpp>
  8. #include <boost/iterator/detail/any_conversion_eater.hpp>
  9. #include <boost/mpl/bool.hpp>
  10. #include <boost/mpl/aux_/lambda_support.hpp>
  11. #include <iterator>
  12. // should be the last #includes
  13. #include <boost/type_traits/integral_constant.hpp>
  14. #include <boost/iterator/detail/config_def.hpp>
  15. #ifndef BOOST_NO_IS_CONVERTIBLE
  16. namespace boost {
  17. namespace iterators {
  18. namespace detail
  19. {
  20. #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
  21. // Calling lvalue_preserver( <expression>, 0 ) returns a reference
  22. // to the expression's result if <expression> is an lvalue, or
  23. // not_an_lvalue() otherwise.
  24. struct not_an_lvalue {};
  25. template <class T>
  26. T& lvalue_preserver(T&, int);
  27. template <class U>
  28. not_an_lvalue lvalue_preserver(U const&, ...);
  29. # define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0)
  30. #else
  31. # define BOOST_LVALUE_PRESERVER(expr) expr
  32. #endif
  33. // Guts of is_lvalue_iterator. Value is the iterator's value_type
  34. // and the result is computed in the nested rebind template.
  35. template <class Value>
  36. struct is_lvalue_iterator_impl
  37. {
  38. // Eat implicit conversions so we don't report true for things
  39. // convertible to Value const&
  40. struct conversion_eater
  41. {
  42. conversion_eater(typename add_lvalue_reference<Value>::type);
  43. };
  44. static char tester(conversion_eater, int);
  45. static char (& tester(any_conversion_eater, ...) )[2];
  46. template <class It>
  47. struct rebind
  48. {
  49. static It& x;
  50. BOOST_STATIC_CONSTANT(
  51. bool
  52. , value = (
  53. sizeof(
  54. is_lvalue_iterator_impl<Value>::tester(
  55. BOOST_LVALUE_PRESERVER(*x), 0
  56. )
  57. ) == 1
  58. )
  59. );
  60. };
  61. };
  62. #undef BOOST_LVALUE_PRESERVER
  63. //
  64. // void specializations to handle std input and output iterators
  65. //
  66. template <>
  67. struct is_lvalue_iterator_impl<void>
  68. {
  69. template <class It>
  70. struct rebind : boost::mpl::false_
  71. {};
  72. };
  73. #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
  74. template <>
  75. struct is_lvalue_iterator_impl<const void>
  76. {
  77. template <class It>
  78. struct rebind : boost::mpl::false_
  79. {};
  80. };
  81. template <>
  82. struct is_lvalue_iterator_impl<volatile void>
  83. {
  84. template <class It>
  85. struct rebind : boost::mpl::false_
  86. {};
  87. };
  88. template <>
  89. struct is_lvalue_iterator_impl<const volatile void>
  90. {
  91. template <class It>
  92. struct rebind : boost::mpl::false_
  93. {};
  94. };
  95. #endif
  96. //
  97. // This level of dispatching is required for Borland. We might save
  98. // an instantiation by removing it for others.
  99. //
  100. template <class It>
  101. struct is_readable_lvalue_iterator_impl
  102. : is_lvalue_iterator_impl<
  103. BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type const
  104. >::template rebind<It>
  105. {};
  106. template <class It>
  107. struct is_non_const_lvalue_iterator_impl
  108. : is_lvalue_iterator_impl<
  109. BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type
  110. >::template rebind<It>
  111. {};
  112. } // namespace detail
  113. template< typename T > struct is_lvalue_iterator
  114. : public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_lvalue_iterator_impl<T>::value>
  115. {
  116. public:
  117. BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_lvalue_iterator,(T))
  118. };
  119. template< typename T > struct is_non_const_lvalue_iterator
  120. : public ::boost::integral_constant<bool,::boost::iterators::detail::is_non_const_lvalue_iterator_impl<T>::value>
  121. {
  122. public:
  123. BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_non_const_lvalue_iterator,(T))
  124. };
  125. } // namespace iterators
  126. using iterators::is_lvalue_iterator;
  127. using iterators::is_non_const_lvalue_iterator;
  128. } // namespace boost
  129. #endif
  130. #include <boost/iterator/detail/config_undef.hpp>
  131. #endif // IS_LVALUE_ITERATOR_DWA2003112_HPP