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