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