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