annotate DEPENDENCIES/generic/include/boost/iterator/iterator_adaptor.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // (C) Copyright David Abrahams 2002.
Chris@16 2 // (C) Copyright Jeremy Siek 2002.
Chris@16 3 // (C) Copyright Thomas Witt 2002.
Chris@16 4 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 5 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7 #ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
Chris@16 8 #define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
Chris@16 9
Chris@16 10 #include <boost/static_assert.hpp>
Chris@16 11 #include <boost/iterator.hpp>
Chris@16 12 #include <boost/detail/iterator.hpp>
Chris@16 13
Chris@16 14 #include <boost/iterator/iterator_categories.hpp>
Chris@16 15 #include <boost/iterator/iterator_facade.hpp>
Chris@16 16 #include <boost/iterator/detail/enable_if.hpp>
Chris@16 17
Chris@16 18 #include <boost/mpl/and.hpp>
Chris@16 19 #include <boost/mpl/not.hpp>
Chris@16 20 #include <boost/mpl/or.hpp>
Chris@16 21
Chris@16 22 #include <boost/type_traits/is_same.hpp>
Chris@16 23 #include <boost/type_traits/is_convertible.hpp>
Chris@16 24
Chris@16 25 #ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
Chris@16 26 # include <boost/type_traits/remove_reference.hpp>
Chris@16 27 #endif
Chris@16 28
Chris@16 29 #include <boost/type_traits/add_reference.hpp>
Chris@16 30 #include <boost/iterator/detail/config_def.hpp>
Chris@16 31
Chris@16 32 #include <boost/iterator/iterator_traits.hpp>
Chris@16 33
Chris@101 34 namespace boost {
Chris@101 35 namespace iterators {
Chris@101 36
Chris@16 37 // Used as a default template argument internally, merely to
Chris@16 38 // indicate "use the default", this can also be passed by users
Chris@16 39 // explicitly in order to specify that the default should be used.
Chris@16 40 struct use_default;
Chris@101 41
Chris@101 42 } // namespace iterators
Chris@101 43
Chris@101 44 using iterators::use_default;
Chris@101 45
Chris@101 46 // the incompleteness of use_default causes massive problems for
Chris@101 47 // is_convertible (naturally). This workaround is fortunately not
Chris@101 48 // needed for vc6/vc7.
Chris@101 49 template<class To>
Chris@101 50 struct is_convertible<use_default,To>
Chris@101 51 : mpl::false_ {};
Chris@101 52
Chris@101 53 namespace iterators {
Chris@101 54
Chris@16 55 namespace detail
Chris@16 56 {
Chris@16 57
Chris@101 58 //
Chris@16 59 // Result type used in enable_if_convertible meta function.
Chris@101 60 // This can be an incomplete type, as only pointers to
Chris@16 61 // enable_if_convertible< ... >::type are used.
Chris@16 62 // We could have used void for this, but conversion to
Chris@16 63 // void* is just to easy.
Chris@16 64 //
Chris@16 65 struct enable_type;
Chris@16 66 }
Chris@16 67
Chris@16 68
Chris@16 69 //
Chris@16 70 // enable_if for use in adapted iterators constructors.
Chris@16 71 //
Chris@16 72 // In order to provide interoperability between adapted constant and
Chris@16 73 // mutable iterators, adapted iterators will usually provide templated
Chris@16 74 // conversion constructors of the following form
Chris@16 75 //
Chris@16 76 // template <class BaseIterator>
Chris@16 77 // class adapted_iterator :
Chris@16 78 // public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
Chris@16 79 // {
Chris@16 80 // public:
Chris@101 81 //
Chris@16 82 // ...
Chris@16 83 //
Chris@16 84 // template <class OtherIterator>
Chris@16 85 // adapted_iterator(
Chris@16 86 // OtherIterator const& it
Chris@16 87 // , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
Chris@16 88 //
Chris@16 89 // ...
Chris@16 90 // };
Chris@16 91 //
Chris@16 92 // enable_if_convertible is used to remove those overloads from the overload
Chris@16 93 // set that cannot be instantiated. For all practical purposes only overloads
Chris@16 94 // for constant/mutable interaction will remain. This has the advantage that
Chris@16 95 // meta functions like boost::is_convertible do not return false positives,
Chris@16 96 // as they can only look at the signature of the conversion constructor
Chris@16 97 // and not at the actual instantiation.
Chris@16 98 //
Chris@16 99 // enable_if_interoperable can be safely used in user code. It falls back to
Chris@101 100 // always enabled for compilers that don't support enable_if or is_convertible.
Chris@101 101 // There is no need for compiler specific workarounds in user code.
Chris@16 102 //
Chris@16 103 // The operators implementation relies on boost::is_convertible not returning
Chris@16 104 // false positives for user/library defined iterator types. See comments
Chris@16 105 // on operator implementation for consequences.
Chris@16 106 //
Chris@101 107 # if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
Chris@101 108
Chris@16 109 template <class From, class To>
Chris@16 110 struct enable_if_convertible
Chris@16 111 {
Chris@101 112 typedef boost::iterators::detail::enable_type type;
Chris@16 113 };
Chris@101 114
Chris@101 115 # elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292))
Chris@101 116
Chris@16 117 // For some reason vc7.1 needs us to "cut off" instantiation
Chris@16 118 // of is_convertible in a few cases.
Chris@16 119 template<typename From, typename To>
Chris@16 120 struct enable_if_convertible
Chris@16 121 : iterators::enable_if<
Chris@16 122 mpl::or_<
Chris@16 123 is_same<From,To>
Chris@16 124 , is_convertible<From, To>
Chris@16 125 >
Chris@101 126 , boost::iterators::detail::enable_type
Chris@16 127 >
Chris@16 128 {};
Chris@101 129
Chris@101 130 # else
Chris@101 131
Chris@16 132 template<typename From, typename To>
Chris@16 133 struct enable_if_convertible
Chris@16 134 : iterators::enable_if<
Chris@16 135 is_convertible<From, To>
Chris@101 136 , boost::iterators::detail::enable_type
Chris@16 137 >
Chris@16 138 {};
Chris@101 139
Chris@16 140 # endif
Chris@101 141
Chris@16 142 //
Chris@16 143 // Default template argument handling for iterator_adaptor
Chris@16 144 //
Chris@16 145 namespace detail
Chris@16 146 {
Chris@16 147 // If T is use_default, return the result of invoking
Chris@16 148 // DefaultNullaryFn, otherwise return T.
Chris@16 149 template <class T, class DefaultNullaryFn>
Chris@16 150 struct ia_dflt_help
Chris@16 151 : mpl::eval_if<
Chris@16 152 is_same<T, use_default>
Chris@16 153 , DefaultNullaryFn
Chris@16 154 , mpl::identity<T>
Chris@16 155 >
Chris@16 156 {
Chris@16 157 };
Chris@16 158
Chris@16 159 // A metafunction which computes an iterator_adaptor's base class,
Chris@16 160 // a specialization of iterator_facade.
Chris@16 161 template <
Chris@16 162 class Derived
Chris@16 163 , class Base
Chris@16 164 , class Value
Chris@16 165 , class Traversal
Chris@16 166 , class Reference
Chris@16 167 , class Difference
Chris@16 168 >
Chris@16 169 struct iterator_adaptor_base
Chris@16 170 {
Chris@16 171 typedef iterator_facade<
Chris@16 172 Derived
Chris@101 173
Chris@16 174 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
Chris@101 175 , typename boost::iterators::detail::ia_dflt_help<
Chris@16 176 Value
Chris@16 177 , mpl::eval_if<
Chris@16 178 is_same<Reference,use_default>
Chris@16 179 , iterator_value<Base>
Chris@16 180 , remove_reference<Reference>
Chris@16 181 >
Chris@16 182 >::type
Chris@16 183 # else
Chris@101 184 , typename boost::iterators::detail::ia_dflt_help<
Chris@16 185 Value, iterator_value<Base>
Chris@16 186 >::type
Chris@16 187 # endif
Chris@101 188
Chris@101 189 , typename boost::iterators::detail::ia_dflt_help<
Chris@16 190 Traversal
Chris@16 191 , iterator_traversal<Base>
Chris@16 192 >::type
Chris@16 193
Chris@101 194 , typename boost::iterators::detail::ia_dflt_help<
Chris@16 195 Reference
Chris@16 196 , mpl::eval_if<
Chris@16 197 is_same<Value,use_default>
Chris@16 198 , iterator_reference<Base>
Chris@16 199 , add_reference<Value>
Chris@16 200 >
Chris@16 201 >::type
Chris@16 202
Chris@101 203 , typename boost::iterators::detail::ia_dflt_help<
Chris@16 204 Difference, iterator_difference<Base>
Chris@16 205 >::type
Chris@16 206 >
Chris@16 207 type;
Chris@16 208 };
Chris@101 209
Chris@16 210 // workaround for aC++ CR JAGaf33512
Chris@16 211 template <class Tr1, class Tr2>
Chris@16 212 inline void iterator_adaptor_assert_traversal ()
Chris@16 213 {
Chris@16 214 BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
Chris@16 215 }
Chris@16 216 }
Chris@101 217
Chris@16 218 //
Chris@16 219 // Iterator Adaptor
Chris@16 220 //
Chris@16 221 // The parameter ordering changed slightly with respect to former
Chris@16 222 // versions of iterator_adaptor The idea is that when the user needs
Chris@16 223 // to fiddle with the reference type it is highly likely that the
Chris@16 224 // iterator category has to be adjusted as well. Any of the
Chris@16 225 // following four template arguments may be ommitted or explicitly
Chris@16 226 // replaced by use_default.
Chris@16 227 //
Chris@16 228 // Value - if supplied, the value_type of the resulting iterator, unless
Chris@16 229 // const. If const, a conforming compiler strips constness for the
Chris@16 230 // value_type. If not supplied, iterator_traits<Base>::value_type is used
Chris@16 231 //
Chris@16 232 // Category - the traversal category of the resulting iterator. If not
Chris@16 233 // supplied, iterator_traversal<Base>::type is used.
Chris@16 234 //
Chris@16 235 // Reference - the reference type of the resulting iterator, and in
Chris@16 236 // particular, the result type of operator*(). If not supplied but
Chris@16 237 // Value is supplied, Value& is used. Otherwise
Chris@16 238 // iterator_traits<Base>::reference is used.
Chris@16 239 //
Chris@16 240 // Difference - the difference_type of the resulting iterator. If not
Chris@16 241 // supplied, iterator_traits<Base>::difference_type is used.
Chris@16 242 //
Chris@16 243 template <
Chris@16 244 class Derived
Chris@16 245 , class Base
Chris@16 246 , class Value = use_default
Chris@16 247 , class Traversal = use_default
Chris@16 248 , class Reference = use_default
Chris@16 249 , class Difference = use_default
Chris@16 250 >
Chris@16 251 class iterator_adaptor
Chris@101 252 : public boost::iterators::detail::iterator_adaptor_base<
Chris@16 253 Derived, Base, Value, Traversal, Reference, Difference
Chris@16 254 >::type
Chris@16 255 {
Chris@16 256 friend class iterator_core_access;
Chris@16 257
Chris@16 258 protected:
Chris@101 259 typedef typename boost::iterators::detail::iterator_adaptor_base<
Chris@16 260 Derived, Base, Value, Traversal, Reference, Difference
Chris@16 261 >::type super_t;
Chris@16 262 public:
Chris@16 263 iterator_adaptor() {}
Chris@16 264
Chris@16 265 explicit iterator_adaptor(Base const &iter)
Chris@16 266 : m_iterator(iter)
Chris@16 267 {
Chris@16 268 }
Chris@16 269
Chris@16 270 typedef Base base_type;
Chris@16 271
Chris@16 272 Base const& base() const
Chris@16 273 { return m_iterator; }
Chris@16 274
Chris@16 275 protected:
Chris@16 276 // for convenience in derived classes
Chris@16 277 typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
Chris@101 278
Chris@16 279 //
Chris@16 280 // lvalue access to the Base object for Derived
Chris@16 281 //
Chris@16 282 Base const& base_reference() const
Chris@16 283 { return m_iterator; }
Chris@16 284
Chris@16 285 Base& base_reference()
Chris@16 286 { return m_iterator; }
Chris@16 287
Chris@16 288 private:
Chris@16 289 //
Chris@16 290 // Core iterator interface for iterator_facade. This is private
Chris@16 291 // to prevent temptation for Derived classes to use it, which
Chris@16 292 // will often result in an error. Derived classes should use
Chris@16 293 // base_reference(), above, to get direct access to m_iterator.
Chris@101 294 //
Chris@16 295 typename super_t::reference dereference() const
Chris@16 296 { return *m_iterator; }
Chris@16 297
Chris@16 298 template <
Chris@16 299 class OtherDerived, class OtherIterator, class V, class C, class R, class D
Chris@101 300 >
Chris@16 301 bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
Chris@16 302 {
Chris@16 303 // Maybe readd with same_distance
Chris@16 304 // BOOST_STATIC_ASSERT(
Chris@16 305 // (detail::same_category_and_difference<Derived,OtherDerived>::value)
Chris@16 306 // );
Chris@16 307 return m_iterator == x.base();
Chris@16 308 }
Chris@16 309
Chris@16 310 typedef typename iterator_category_to_traversal<
Chris@16 311 typename super_t::iterator_category
Chris@16 312 >::type my_traversal;
Chris@16 313
Chris@16 314 # define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
Chris@101 315 boost::iterators::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
Chris@16 316
Chris@16 317 void advance(typename super_t::difference_type n)
Chris@16 318 {
Chris@16 319 BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
Chris@16 320 m_iterator += n;
Chris@16 321 }
Chris@101 322
Chris@16 323 void increment() { ++m_iterator; }
Chris@16 324
Chris@101 325 void decrement()
Chris@16 326 {
Chris@16 327 BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
Chris@16 328 --m_iterator;
Chris@16 329 }
Chris@16 330
Chris@16 331 template <
Chris@16 332 class OtherDerived, class OtherIterator, class V, class C, class R, class D
Chris@101 333 >
Chris@16 334 typename super_t::difference_type distance_to(
Chris@16 335 iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
Chris@16 336 {
Chris@16 337 BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
Chris@16 338 // Maybe readd with same_distance
Chris@16 339 // BOOST_STATIC_ASSERT(
Chris@16 340 // (detail::same_category_and_difference<Derived,OtherDerived>::value)
Chris@16 341 // );
Chris@16 342 return y.base() - m_iterator;
Chris@16 343 }
Chris@16 344
Chris@16 345 # undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
Chris@101 346
Chris@16 347 private: // data members
Chris@16 348 Base m_iterator;
Chris@16 349 };
Chris@16 350
Chris@101 351 } // namespace iterators
Chris@101 352
Chris@101 353 using iterators::iterator_adaptor;
Chris@101 354 using iterators::enable_if_convertible;
Chris@101 355
Chris@16 356 } // namespace boost
Chris@16 357
Chris@16 358 #include <boost/iterator/detail/config_undef.hpp>
Chris@16 359
Chris@16 360 #endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP