1 // Copyright David Abrahams 2003. Use, modification and distribution is
\r
2 // subject to the Boost Software License, Version 1.0. (See accompanying
\r
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
\r
4 #ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
\r
5 # define IS_LVALUE_ITERATOR_DWA2003112_HPP
\r
7 #include <boost/iterator.hpp>
\r
9 #include <boost/detail/workaround.hpp>
\r
10 #include <boost/detail/iterator.hpp>
\r
12 #include <boost/iterator/detail/any_conversion_eater.hpp>
\r
14 // should be the last #includes
\r
15 #include <boost/type_traits/detail/bool_trait_def.hpp>
\r
16 #include <boost/iterator/detail/config_def.hpp>
\r
18 #ifndef BOOST_NO_IS_CONVERTIBLE
\r
24 #ifndef BOOST_NO_LVALUE_RETURN_DETECTION
\r
25 // Calling lvalue_preserver( <expression>, 0 ) returns a reference
\r
26 // to the expression's result if <expression> is an lvalue, or
\r
27 // not_an_lvalue() otherwise.
\r
28 struct not_an_lvalue {};
\r
31 T& lvalue_preserver(T&, int);
\r
34 not_an_lvalue lvalue_preserver(U const&, ...);
\r
36 # define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0)
\r
40 # define BOOST_LVALUE_PRESERVER(expr) expr
\r
44 // Guts of is_lvalue_iterator. Value is the iterator's value_type
\r
45 // and the result is computed in the nested rebind template.
\r
46 template <class Value>
\r
47 struct is_lvalue_iterator_impl
\r
49 // Eat implicit conversions so we don't report true for things
\r
50 // convertible to Value const&
\r
51 struct conversion_eater
\r
53 conversion_eater(Value&);
\r
56 static char tester(conversion_eater, int);
\r
57 static char (& tester(any_conversion_eater, ...) )[2];
\r
64 BOOST_STATIC_CONSTANT(
\r
68 is_lvalue_iterator_impl<Value>::tester(
\r
69 BOOST_LVALUE_PRESERVER(*x), 0
\r
77 #undef BOOST_LVALUE_PRESERVER
\r
80 // void specializations to handle std input and output iterators
\r
83 struct is_lvalue_iterator_impl<void>
\r
86 struct rebind : boost::mpl::false_
\r
90 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
\r
92 struct is_lvalue_iterator_impl<const void>
\r
95 struct rebind : boost::mpl::false_
\r
100 struct is_lvalue_iterator_impl<volatile void>
\r
102 template <class It>
\r
103 struct rebind : boost::mpl::false_
\r
108 struct is_lvalue_iterator_impl<const volatile void>
\r
110 template <class It>
\r
111 struct rebind : boost::mpl::false_
\r
117 // This level of dispatching is required for Borland. We might save
\r
118 // an instantiation by removing it for others.
\r
120 template <class It>
\r
121 struct is_readable_lvalue_iterator_impl
\r
122 : is_lvalue_iterator_impl<
\r
123 BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const
\r
124 >::template rebind<It>
\r
127 template <class It>
\r
128 struct is_non_const_lvalue_iterator_impl
\r
129 : is_lvalue_iterator_impl<
\r
130 BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type
\r
131 >::template rebind<It>
\r
133 } // namespace detail
\r
135 // Define the trait with full mpl lambda capability and various broken
\r
136 // compiler workarounds
\r
137 BOOST_TT_AUX_BOOL_TRAIT_DEF1(
\r
138 is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
\r
140 BOOST_TT_AUX_BOOL_TRAIT_DEF1(
\r
141 is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
\r
143 } // namespace boost
\r
147 #include <boost/iterator/detail/config_undef.hpp>
\r
148 #include <boost/type_traits/detail/bool_trait_undef.hpp>
\r
150 #endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
\r