is_lvalue_iterator.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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/iterator.hpp>
  7. #include <boost/detail/workaround.hpp>
  8. #include <boost/detail/iterator.hpp>
  9. #include <boost/iterator/detail/any_conversion_eater.hpp>
  10. // should be the last #includes
  11. #include <boost/type_traits/detail/bool_trait_def.hpp>
  12. #include <boost/iterator/detail/config_def.hpp>
  13. #ifndef BOOST_NO_IS_CONVERTIBLE
  14. namespace boost {
  15. namespace detail
  16. {
  17. #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
  18. // Calling lvalue_preserver( <expression>, 0 ) returns a reference
  19. // to the expression's result if <expression> is an lvalue, or
  20. // not_an_lvalue() otherwise.
  21. struct not_an_lvalue {};
  22. template <class T>
  23. T& lvalue_preserver(T&, int);
  24. template <class U>
  25. not_an_lvalue lvalue_preserver(U const&, ...);
  26. # define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0)
  27. #else
  28. # define BOOST_LVALUE_PRESERVER(expr) expr
  29. #endif
  30. // Guts of is_lvalue_iterator. Value is the iterator's value_type
  31. // and the result is computed in the nested rebind template.
  32. template <class Value>
  33. struct is_lvalue_iterator_impl
  34. {
  35. // Eat implicit conversions so we don't report true for things
  36. // convertible to Value const&
  37. struct conversion_eater
  38. {
  39. conversion_eater(Value&);
  40. };
  41. static char tester(conversion_eater, int);
  42. static char (& tester(any_conversion_eater, ...) )[2];
  43. template <class It>
  44. struct rebind
  45. {
  46. static It& x;
  47. BOOST_STATIC_CONSTANT(
  48. bool
  49. , value = (
  50. sizeof(
  51. is_lvalue_iterator_impl<Value>::tester(
  52. BOOST_LVALUE_PRESERVER(*x), 0
  53. )
  54. ) == 1
  55. )
  56. );
  57. };
  58. };
  59. #undef BOOST_LVALUE_PRESERVER
  60. //
  61. // void specializations to handle std input and output iterators
  62. //
  63. template <>
  64. struct is_lvalue_iterator_impl<void>
  65. {
  66. template <class It>
  67. struct rebind : boost::mpl::false_
  68. {};
  69. };
  70. #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
  71. template <>
  72. struct is_lvalue_iterator_impl<const void>
  73. {
  74. template <class It>
  75. struct rebind : boost::mpl::false_
  76. {};
  77. };
  78. template <>
  79. struct is_lvalue_iterator_impl<volatile void>
  80. {
  81. template <class It>
  82. struct rebind : boost::mpl::false_
  83. {};
  84. };
  85. template <>
  86. struct is_lvalue_iterator_impl<const volatile void>
  87. {
  88. template <class It>
  89. struct rebind : boost::mpl::false_
  90. {};
  91. };
  92. #endif
  93. //
  94. // This level of dispatching is required for Borland. We might save
  95. // an instantiation by removing it for others.
  96. //
  97. template <class It>
  98. struct is_readable_lvalue_iterator_impl
  99. : is_lvalue_iterator_impl<
  100. BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
  101. >::template rebind<It>
  102. {};
  103. template <class It>
  104. struct is_non_const_lvalue_iterator_impl
  105. : is_lvalue_iterator_impl<
  106. BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type
  107. >::template rebind<It>
  108. {};
  109. } // namespace detail
  110. // Define the trait with full mpl lambda capability and various broken
  111. // compiler workarounds
  112. BOOST_TT_AUX_BOOL_TRAIT_DEF1(
  113. is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
  114. BOOST_TT_AUX_BOOL_TRAIT_DEF1(
  115. is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
  116. } // namespace boost
  117. #endif
  118. #include <boost/iterator/detail/config_undef.hpp>
  119. #include <boost/type_traits/detail/bool_trait_undef.hpp>
  120. #endif // IS_LVALUE_ITERATOR_DWA2003112_HPP