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_READABLE_ITERATOR_DWA2003112_HPP |
5 | # define IS_READABLE_ITERATOR_DWA2003112_HPP |
6 | |
7 | #include <boost/mpl/bool.hpp> |
8 | #include <boost/mpl/aux_/lambda_support.hpp> |
9 | #include <boost/detail/iterator.hpp> |
10 | #include <boost/type_traits/add_lvalue_reference.hpp> |
11 | |
12 | #include <boost/iterator/detail/any_conversion_eater.hpp> |
13 | |
14 | // should be the last #include |
15 | #include <boost/type_traits/integral_constant.hpp> |
16 | #include <boost/iterator/detail/config_def.hpp> |
17 | |
18 | #ifndef BOOST_NO_IS_CONVERTIBLE |
19 | |
20 | namespace boost { |
21 | |
22 | namespace iterators { |
23 | |
24 | namespace detail |
25 | { |
26 | // Guts of is_readable_iterator. Value is the iterator's value_type |
27 | // and the result is computed in the nested rebind template. |
28 | template <class Value> |
29 | struct is_readable_iterator_impl |
30 | { |
31 | static char tester(typename add_lvalue_reference<Value>::type, int); |
32 | static char (& tester(any_conversion_eater, ...) )[2]; |
33 | |
34 | template <class It> |
35 | struct rebind |
36 | { |
37 | static It& x; |
38 | |
39 | BOOST_STATIC_CONSTANT( |
40 | bool |
41 | , value = ( |
42 | sizeof( |
43 | is_readable_iterator_impl<Value>::tester(*x, 1) |
44 | ) == 1 |
45 | ) |
46 | ); |
47 | }; |
48 | }; |
49 | |
50 | #undef BOOST_READABLE_PRESERVER |
51 | |
52 | // |
53 | // void specializations to handle std input and output iterators |
54 | // |
55 | template <> |
56 | struct is_readable_iterator_impl<void> |
57 | { |
58 | template <class It> |
59 | struct rebind : boost::mpl::false_ |
60 | {}; |
61 | }; |
62 | |
63 | #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS |
64 | template <> |
65 | struct is_readable_iterator_impl<const void> |
66 | { |
67 | template <class It> |
68 | struct rebind : boost::mpl::false_ |
69 | {}; |
70 | }; |
71 | |
72 | template <> |
73 | struct is_readable_iterator_impl<volatile void> |
74 | { |
75 | template <class It> |
76 | struct rebind : boost::mpl::false_ |
77 | {}; |
78 | }; |
79 | |
80 | template <> |
81 | struct is_readable_iterator_impl<const volatile void> |
82 | { |
83 | template <class It> |
84 | struct rebind : boost::mpl::false_ |
85 | {}; |
86 | }; |
87 | #endif |
88 | |
89 | // |
90 | // This level of dispatching is required for Borland. We might save |
91 | // an instantiation by removing it for others. |
92 | // |
93 | template <class It> |
94 | struct is_readable_iterator_impl2 |
95 | : is_readable_iterator_impl< |
96 | BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<It>::value_type const |
97 | >::template rebind<It> |
98 | {}; |
99 | } // namespace detail |
100 | |
101 | template< typename T > struct is_readable_iterator |
102 | : public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_iterator_impl2<T>::value> |
103 | { |
104 | public: |
105 | BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_readable_iterator,(T)) |
106 | }; |
107 | |
108 | } // namespace iterators |
109 | |
110 | using iterators::is_readable_iterator; |
111 | |
112 | } // namespace boost |
113 | |
114 | #endif |
115 | |
116 | #include <boost/iterator/detail/config_undef.hpp> |
117 | |
118 | #endif // IS_READABLE_ITERATOR_DWA2003112_HPP |
119 |