]> git.lyx.org Git - lyx.git/blob - boost/boost/iterator/is_lvalue_iterator.hpp
How about if we write a script to do some of this and stop doing it
[lyx.git] / boost / boost / iterator / is_lvalue_iterator.hpp
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
6 \r
7 #include <boost/iterator.hpp>\r
8 \r
9 #include <boost/detail/workaround.hpp>\r
10 #include <boost/detail/iterator.hpp>\r
11 \r
12 #include <boost/iterator/detail/any_conversion_eater.hpp>\r
13 \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
17 \r
18 #ifndef BOOST_NO_IS_CONVERTIBLE\r
19 \r
20 namespace boost {\r
21  \r
22 namespace detail\r
23 {\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
29   \r
30   template <class T>\r
31   T& lvalue_preserver(T&, int);\r
32   \r
33   template <class U>\r
34   not_an_lvalue lvalue_preserver(U const&, ...);\r
35   \r
36 # define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0)\r
37   \r
38 #else\r
39   \r
40 # define BOOST_LVALUE_PRESERVER(expr) expr\r
41   \r
42 #endif \r
43 \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
48   {\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
52       {\r
53           conversion_eater(Value&);\r
54       };\r
55 \r
56       static char tester(conversion_eater, int);\r
57       static char (& tester(any_conversion_eater, ...) )[2];\r
58     \r
59       template <class It>\r
60       struct rebind\r
61       {\r
62           static It& x;\r
63           \r
64           BOOST_STATIC_CONSTANT(\r
65               bool\r
66             , value = (\r
67                 sizeof(\r
68                     is_lvalue_iterator_impl<Value>::tester(\r
69                         BOOST_LVALUE_PRESERVER(*x), 0\r
70                     )\r
71                 ) == 1\r
72             )\r
73           );\r
74       };\r
75   };\r
76 \r
77 #undef BOOST_LVALUE_PRESERVER\r
78   \r
79   //\r
80   // void specializations to handle std input and output iterators\r
81   //\r
82   template <>\r
83   struct is_lvalue_iterator_impl<void>\r
84   {\r
85       template <class It>\r
86       struct rebind : boost::mpl::false_\r
87       {};\r
88   };\r
89 \r
90 #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS\r
91   template <>\r
92   struct is_lvalue_iterator_impl<const void>\r
93   {\r
94       template <class It>\r
95       struct rebind : boost::mpl::false_\r
96       {};\r
97   };\r
98 \r
99   template <>\r
100   struct is_lvalue_iterator_impl<volatile void>\r
101   {\r
102       template <class It>\r
103       struct rebind : boost::mpl::false_\r
104       {};\r
105   };\r
106 \r
107   template <>\r
108   struct is_lvalue_iterator_impl<const volatile void>\r
109   {\r
110       template <class It>\r
111       struct rebind : boost::mpl::false_\r
112       {};\r
113   };\r
114 #endif\r
115 \r
116   //\r
117   // This level of dispatching is required for Borland.  We might save\r
118   // an instantiation by removing it for others.\r
119   //\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
125   {};\r
126 \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
132   {};\r
133 } // namespace detail\r
134 \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
139     \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
142     \r
143 } // namespace boost\r
144 \r
145 #endif\r
146 \r
147 #include <boost/iterator/detail/config_undef.hpp>\r
148 #include <boost/type_traits/detail/bool_trait_undef.hpp>\r
149 \r
150 #endif // IS_LVALUE_ITERATOR_DWA2003112_HPP\r