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