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 FACADE_ITERATOR_CATEGORY_DWA20031118_HPP 5 # define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP 6 7 # include <boost/core/use_default.hpp> 8 9 # include <boost/iterator/iterator_categories.hpp> 10 11 # include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic 12 # include <boost/mpl/and.hpp> 13 # include <boost/mpl/if.hpp> 14 # include <boost/mpl/eval_if.hpp> 15 # include <boost/mpl/identity.hpp> 16 # include <boost/mpl/assert.hpp> 17 18 # include <boost/type_traits/is_same.hpp> 19 # include <boost/type_traits/is_const.hpp> 20 # include <boost/type_traits/is_reference.hpp> 21 # include <boost/type_traits/is_convertible.hpp> 22 23 # include <boost/type_traits/is_same.hpp> 24 25 # include <boost/iterator/detail/config_def.hpp> // try to keep this last 26 27 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 28 # include <boost/detail/indirect_traits.hpp> 29 # endif 30 31 // 32 // iterator_category deduction for iterator_facade 33 // 34 35 namespace boost { 36 namespace iterators { 37 38 using boost::use_default; 39 40 namespace detail { 41 42 struct input_output_iterator_tag 43 : std::input_iterator_tag 44 { 45 // Using inheritance for only input_iterator_tag helps to avoid 46 // ambiguities when a stdlib implementation dispatches on a 47 // function which is overloaded on both input_iterator_tag and 48 // output_iterator_tag, as STLPort does, in its __valid_range 49 // function. I claim it's better to avoid the ambiguity in these 50 // cases. operator std::output_iterator_tagboost::iterators::detail::input_output_iterator_tag51 operator std::output_iterator_tag() const 52 { 53 return std::output_iterator_tag(); 54 } 55 }; 56 57 // 58 // True iff the user has explicitly disabled writability of this 59 // iterator. Pass the iterator_facade's Value parameter and its 60 // nested ::reference type. 61 // 62 template <class ValueParam, class Reference> 63 struct iterator_writability_disabled 64 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic? 65 : mpl::or_< 66 is_const<Reference> 67 , boost::detail::indirect_traits::is_reference_to_const<Reference> 68 , is_const<ValueParam> 69 > 70 # else 71 : is_const<ValueParam> 72 # endif 73 {}; 74 75 76 // 77 // Convert an iterator_facade's traversal category, Value parameter, 78 // and ::reference type to an appropriate old-style category. 79 // 80 // Due to changeset 21683, this now never results in a category convertible 81 // to output_iterator_tag. 82 // 83 // Change at: https://svn.boost.org/trac/boost/changeset/21683 84 template <class Traversal, class ValueParam, class Reference> 85 struct iterator_facade_default_category 86 : mpl::eval_if< 87 mpl::and_< 88 is_reference<Reference> 89 , is_convertible<Traversal,forward_traversal_tag> 90 > 91 , mpl::eval_if< 92 is_convertible<Traversal,random_access_traversal_tag> 93 , mpl::identity<std::random_access_iterator_tag> 94 , mpl::if_< 95 is_convertible<Traversal,bidirectional_traversal_tag> 96 , std::bidirectional_iterator_tag 97 , std::forward_iterator_tag 98 > 99 > 100 , typename mpl::eval_if< 101 mpl::and_< 102 is_convertible<Traversal, single_pass_traversal_tag> 103 104 // check for readability 105 , is_convertible<Reference, ValueParam> 106 > 107 , mpl::identity<std::input_iterator_tag> 108 , mpl::identity<Traversal> 109 > 110 > 111 { 112 }; 113 114 // True iff T is convertible to an old-style iterator category. 115 template <class T> 116 struct is_iterator_category 117 : mpl::or_< 118 is_convertible<T,std::input_iterator_tag> 119 , is_convertible<T,std::output_iterator_tag> 120 > 121 { 122 }; 123 124 template <class T> 125 struct is_iterator_traversal 126 : is_convertible<T,incrementable_traversal_tag> 127 {}; 128 129 // 130 // A composite iterator_category tag convertible to Category (a pure 131 // old-style category) and Traversal (a pure traversal tag). 132 // Traversal must be a strict increase of the traversal power given by 133 // Category. 134 // 135 template <class Category, class Traversal> 136 struct iterator_category_with_traversal 137 : Category, Traversal 138 { 139 // Make sure this isn't used to build any categories where 140 // convertibility to Traversal is redundant. Should just use the 141 // Category element in that case. 142 BOOST_MPL_ASSERT_NOT(( 143 is_convertible< 144 typename iterator_category_to_traversal<Category>::type 145 , Traversal 146 >)); 147 148 BOOST_MPL_ASSERT((is_iterator_category<Category>)); 149 BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>)); 150 BOOST_MPL_ASSERT_NOT((is_iterator_traversal<Category>)); 151 # if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) 152 BOOST_MPL_ASSERT((is_iterator_traversal<Traversal>)); 153 # endif 154 }; 155 156 // Computes an iterator_category tag whose traversal is Traversal and 157 // which is appropriate for an iterator 158 template <class Traversal, class ValueParam, class Reference> 159 struct facade_iterator_category_impl 160 { 161 BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>)); 162 163 typedef typename iterator_facade_default_category< 164 Traversal,ValueParam,Reference 165 >::type category; 166 167 typedef typename mpl::if_< 168 is_same< 169 Traversal 170 , typename iterator_category_to_traversal<category>::type 171 > 172 , category 173 , iterator_category_with_traversal<category,Traversal> 174 >::type type; 175 }; 176 177 // 178 // Compute an iterator_category for iterator_facade 179 // 180 template <class CategoryOrTraversal, class ValueParam, class Reference> 181 struct facade_iterator_category 182 : mpl::eval_if< 183 is_iterator_category<CategoryOrTraversal> 184 , mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is 185 , facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference> 186 > 187 { 188 }; 189 190 }}} // namespace boost::iterators::detail 191 192 # include <boost/iterator/detail/config_undef.hpp> 193 194 #endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP 195