1 // (C) Copyright David Abrahams 2002. 2 // (C) Copyright Jeremy Siek 2002. 3 // (C) Copyright Thomas Witt 2002. 4 // Distributed under the Boost Software License, Version 1.0. (See 5 // accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP 8 #define BOOST_ITERATOR_FACADE_23022003THW_HPP 9 10 #include <boost/config.hpp> 11 #include <boost/iterator/interoperable.hpp> 12 #include <boost/iterator/iterator_traits.hpp> 13 #include <boost/iterator/iterator_categories.hpp> 14 15 #include <boost/iterator/detail/facade_iterator_category.hpp> 16 #include <boost/iterator/detail/enable_if.hpp> 17 18 #include <boost/static_assert.hpp> 19 #include <boost/core/addressof.hpp> 20 21 #include <boost/type_traits/is_same.hpp> 22 #include <boost/type_traits/add_const.hpp> 23 #include <boost/type_traits/add_pointer.hpp> 24 #include <boost/type_traits/add_lvalue_reference.hpp> 25 #include <boost/type_traits/remove_const.hpp> 26 #include <boost/type_traits/remove_reference.hpp> 27 #include <boost/type_traits/is_convertible.hpp> 28 #include <boost/type_traits/is_pod.hpp> 29 30 #include <boost/mpl/eval_if.hpp> 31 #include <boost/mpl/if.hpp> 32 #include <boost/mpl/or.hpp> 33 #include <boost/mpl/and.hpp> 34 #include <boost/mpl/not.hpp> 35 #include <boost/mpl/always.hpp> 36 #include <boost/mpl/apply.hpp> 37 #include <boost/mpl/identity.hpp> 38 39 #include <cstddef> 40 41 #include <boost/iterator/detail/config_def.hpp> // this goes last 42 43 namespace boost { 44 namespace iterators { 45 46 // This forward declaration is required for the friend declaration 47 // in iterator_core_access 48 template <class I, class V, class TC, class R, class D> class iterator_facade; 49 50 namespace detail 51 { 52 // A binary metafunction class that always returns bool. VC6 53 // ICEs on mpl::always<bool>, probably because of the default 54 // parameters. 55 struct always_bool2 56 { 57 template <class T, class U> 58 struct apply 59 { 60 typedef bool type; 61 }; 62 }; 63 64 // The type trait checks if the category or traversal is at least as advanced as the specified required traversal 65 template< typename CategoryOrTraversal, typename Required > 66 struct is_traversal_at_least : 67 public boost::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required > 68 {}; 69 70 // 71 // enable if for use in operator implementation. 72 // 73 template < 74 class Facade1 75 , class Facade2 76 , class Return 77 > 78 struct enable_if_interoperable : 79 public boost::iterators::enable_if< 80 is_interoperable< Facade1, Facade2 > 81 , Return 82 > 83 {}; 84 85 // 86 // enable if for use in implementation of operators specific for random access traversal. 87 // 88 template < 89 class Facade1 90 , class Facade2 91 , class Return 92 > 93 struct enable_if_interoperable_and_random_access_traversal : 94 public boost::iterators::enable_if< 95 mpl::and_< 96 is_interoperable< Facade1, Facade2 > 97 , is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag > 98 , is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag > 99 > 100 , Return 101 > 102 {}; 103 104 // 105 // Generates associated types for an iterator_facade with the 106 // given parameters. 107 // 108 template < 109 class ValueParam 110 , class CategoryOrTraversal 111 , class Reference 112 , class Difference 113 > 114 struct iterator_facade_types 115 { 116 typedef typename facade_iterator_category< 117 CategoryOrTraversal, ValueParam, Reference 118 >::type iterator_category; 119 120 typedef typename remove_const<ValueParam>::type value_type; 121 122 // Not the real associated pointer type 123 typedef typename mpl::eval_if< 124 boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference> 125 , add_pointer<const value_type> 126 , add_pointer<value_type> 127 >::type pointer; 128 129 # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ 130 && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \ 131 || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \ 132 || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \ 133 || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310) 134 135 // To interoperate with some broken library/compiler 136 // combinations, user-defined iterators must be derived from 137 // std::iterator. It is possible to implement a standard 138 // library for broken compilers without this limitation. 139 # define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1 140 141 typedef 142 iterator<iterator_category, value_type, Difference, pointer, Reference> 143 base; 144 # endif 145 }; 146 147 // iterators whose dereference operators reference the same value 148 // for all iterators into the same sequence (like many input 149 // iterators) need help with their postfix ++: the referenced 150 // value must be read and stored away before the increment occurs 151 // so that *a++ yields the originally referenced element and not 152 // the next one. 153 template <class Iterator> 154 class postfix_increment_proxy 155 { 156 typedef typename iterator_value<Iterator>::type value_type; 157 public: postfix_increment_proxy(Iterator const & x)158 explicit postfix_increment_proxy(Iterator const& x) 159 : stored_value(*x) 160 {} 161 162 // Returning a mutable reference allows nonsense like 163 // (*r++).mutate(), but it imposes fewer assumptions about the 164 // behavior of the value_type. In particular, recall that 165 // (*r).mutate() is legal if operator* returns by value. 166 value_type& operator *() const167 operator*() const 168 { 169 return this->stored_value; 170 } 171 private: 172 mutable value_type stored_value; 173 }; 174 175 // 176 // In general, we can't determine that such an iterator isn't 177 // writable -- we also need to store a copy of the old iterator so 178 // that it can be written into. 179 template <class Iterator> 180 class writable_postfix_increment_proxy 181 { 182 typedef typename iterator_value<Iterator>::type value_type; 183 public: writable_postfix_increment_proxy(Iterator const & x)184 explicit writable_postfix_increment_proxy(Iterator const& x) 185 : stored_value(*x) 186 , stored_iterator(x) 187 {} 188 189 // Dereferencing must return a proxy so that both *r++ = o and 190 // value_type(*r++) can work. In this case, *r is the same as 191 // *r++, and the conversion operator below is used to ensure 192 // readability. 193 writable_postfix_increment_proxy const& operator *() const194 operator*() const 195 { 196 return *this; 197 } 198 199 // Provides readability of *r++ operator value_type&() const200 operator value_type&() const 201 { 202 return stored_value; 203 } 204 205 // Provides writability of *r++ 206 template <class T> operator =(T const & x) const207 T const& operator=(T const& x) const 208 { 209 *this->stored_iterator = x; 210 return x; 211 } 212 213 // This overload just in case only non-const objects are writable 214 template <class T> operator =(T & x) const215 T& operator=(T& x) const 216 { 217 *this->stored_iterator = x; 218 return x; 219 } 220 221 // Provides X(r++) operator Iterator const&() const222 operator Iterator const&() const 223 { 224 return stored_iterator; 225 } 226 227 private: 228 mutable value_type stored_value; 229 Iterator stored_iterator; 230 }; 231 232 # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 233 234 template <class Reference, class Value> 235 struct is_non_proxy_reference_impl 236 { 237 static Reference r; 238 239 template <class R> 240 static typename mpl::if_< 241 is_convertible< 242 R const volatile* 243 , Value const volatile* 244 > 245 , char[1] 246 , char[2] 247 >::type& helper(R const&); 248 249 BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1); 250 }; 251 252 template <class Reference, class Value> 253 struct is_non_proxy_reference 254 : mpl::bool_< 255 is_non_proxy_reference_impl<Reference, Value>::value 256 > 257 {}; 258 # else 259 template <class Reference, class Value> 260 struct is_non_proxy_reference 261 : is_convertible< 262 typename remove_reference<Reference>::type 263 const volatile* 264 , Value const volatile* 265 > 266 {}; 267 # endif 268 269 // A metafunction to choose the result type of postfix ++ 270 // 271 // Because the C++98 input iterator requirements say that *r++ has 272 // type T (value_type), implementations of some standard 273 // algorithms like lexicographical_compare may use constructions 274 // like: 275 // 276 // *r++ < *s++ 277 // 278 // If *r++ returns a proxy (as required if r is writable but not 279 // multipass), this sort of expression will fail unless the proxy 280 // supports the operator<. Since there are any number of such 281 // operations, we're not going to try to support them. Therefore, 282 // even if r++ returns a proxy, *r++ will only return a proxy if 283 // *r also returns a proxy. 284 template <class Iterator, class Value, class Reference, class CategoryOrTraversal> 285 struct postfix_increment_result 286 : mpl::eval_if< 287 mpl::and_< 288 // A proxy is only needed for readable iterators 289 is_convertible< 290 Reference 291 // Use add_lvalue_reference to form `reference to Value` due to 292 // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject 293 // 'reference-to-reference' in the template which described in CWG 294 // DR106. 295 // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106 296 , typename add_lvalue_reference<Value const>::type 297 > 298 299 // No multipass iterator can have values that disappear 300 // before positions can be re-visited 301 , mpl::not_< 302 is_convertible< 303 typename iterator_category_to_traversal<CategoryOrTraversal>::type 304 , forward_traversal_tag 305 > 306 > 307 > 308 , mpl::if_< 309 is_non_proxy_reference<Reference,Value> 310 , postfix_increment_proxy<Iterator> 311 , writable_postfix_increment_proxy<Iterator> 312 > 313 , mpl::identity<Iterator> 314 > 315 {}; 316 317 // operator->() needs special support for input iterators to strictly meet the 318 // standard's requirements. If *i is not a reference type, we must still 319 // produce an lvalue to which a pointer can be formed. We do that by 320 // returning a proxy object containing an instance of the reference object. 321 template <class Reference, class Pointer> 322 struct operator_arrow_dispatch // proxy references 323 { 324 struct proxy 325 { proxyboost::iterators::detail::operator_arrow_dispatch::proxy326 explicit proxy(Reference const & x) : m_ref(x) {} operator ->boost::iterators::detail::operator_arrow_dispatch::proxy327 Reference* operator->() { return boost::addressof(m_ref); } 328 // This function is needed for MWCW and BCC, which won't call 329 // operator-> again automatically per 13.3.1.2 para 8 operator Reference*boost::iterators::detail::operator_arrow_dispatch::proxy330 operator Reference*() { return boost::addressof(m_ref); } 331 Reference m_ref; 332 }; 333 typedef proxy result_type; applyboost::iterators::detail::operator_arrow_dispatch334 static result_type apply(Reference const & x) 335 { 336 return result_type(x); 337 } 338 }; 339 340 template <class T, class Pointer> 341 struct operator_arrow_dispatch<T&, Pointer> // "real" references 342 { 343 typedef Pointer result_type; applyboost::iterators::detail::operator_arrow_dispatch344 static result_type apply(T& x) 345 { 346 return boost::addressof(x); 347 } 348 }; 349 350 // A proxy return type for operator[], needed to deal with 351 // iterators that may invalidate referents upon destruction. 352 // Consider the temporary iterator in *(a + n) 353 template <class Iterator> 354 class operator_brackets_proxy 355 { 356 // Iterator is actually an iterator_facade, so we do not have to 357 // go through iterator_traits to access the traits. 358 typedef typename Iterator::reference reference; 359 typedef typename Iterator::value_type value_type; 360 361 public: operator_brackets_proxy(Iterator const & iter)362 operator_brackets_proxy(Iterator const& iter) 363 : m_iter(iter) 364 {} 365 operator reference() const366 operator reference() const 367 { 368 return *m_iter; 369 } 370 operator =(value_type const & val)371 operator_brackets_proxy& operator=(value_type const& val) 372 { 373 *m_iter = val; 374 return *this; 375 } 376 377 private: 378 Iterator m_iter; 379 }; 380 381 // A metafunction that determines whether operator[] must return a 382 // proxy, or whether it can simply return a copy of the value_type. 383 template <class ValueType, class Reference> 384 struct use_operator_brackets_proxy 385 : mpl::not_< 386 mpl::and_< 387 // Really we want an is_copy_constructible trait here, 388 // but is_POD will have to suffice in the meantime. 389 boost::is_POD<ValueType> 390 , iterator_writability_disabled<ValueType,Reference> 391 > 392 > 393 {}; 394 395 template <class Iterator, class Value, class Reference> 396 struct operator_brackets_result 397 { 398 typedef typename mpl::if_< 399 use_operator_brackets_proxy<Value,Reference> 400 , operator_brackets_proxy<Iterator> 401 , Value 402 >::type type; 403 }; 404 405 template <class Iterator> make_operator_brackets_result(Iterator const & iter,mpl::true_)406 operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_) 407 { 408 return operator_brackets_proxy<Iterator>(iter); 409 } 410 411 template <class Iterator> make_operator_brackets_result(Iterator const & iter,mpl::false_)412 typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_) 413 { 414 return *iter; 415 } 416 417 struct choose_difference_type 418 { 419 template <class I1, class I2> 420 struct apply 421 : 422 # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP 423 iterator_difference<I1> 424 # else 425 mpl::eval_if< 426 is_convertible<I2,I1> 427 , iterator_difference<I1> 428 , iterator_difference<I2> 429 > 430 # endif 431 {}; 432 433 }; 434 435 template < 436 class Derived 437 , class Value 438 , class CategoryOrTraversal 439 , class Reference 440 , class Difference 441 , bool IsBidirectionalTraversal 442 , bool IsRandomAccessTraversal 443 > 444 class iterator_facade_base; 445 446 } // namespace detail 447 448 449 // Macros which describe the declarations of binary operators 450 # ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY 451 # define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \ 452 template < \ 453 class Derived1, class V1, class TC1, class Reference1, class Difference1 \ 454 , class Derived2, class V2, class TC2, class Reference2, class Difference2 \ 455 > \ 456 prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \ 457 operator op( \ 458 iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \ 459 , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs) 460 # else 461 # define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \ 462 template < \ 463 class Derived1, class V1, class TC1, class Reference1, class Difference1 \ 464 , class Derived2, class V2, class TC2, class Reference2, class Difference2 \ 465 > \ 466 prefix typename enabler< \ 467 Derived1, Derived2 \ 468 , typename mpl::apply2<result_type,Derived1,Derived2>::type \ 469 >::type \ 470 operator op( \ 471 iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \ 472 , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs) 473 # endif 474 475 # define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \ 476 BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable) 477 478 # define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type) \ 479 BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal) 480 481 # define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \ 482 template <class Derived, class V, class TC, class R, class D> \ 483 prefix typename boost::iterators::enable_if< \ 484 boost::iterators::detail::is_traversal_at_least< TC, boost::iterators::random_access_traversal_tag >, \ 485 Derived \ 486 >::type operator+ args 487 488 // 489 // Helper class for granting access to the iterator core interface. 490 // 491 // The simple core interface is used by iterator_facade. The core 492 // interface of a user/library defined iterator type should not be made public 493 // so that it does not clutter the public interface. Instead iterator_core_access 494 // should be made friend so that iterator_facade can access the core 495 // interface through iterator_core_access. 496 // 497 class iterator_core_access 498 { 499 # if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) 500 // Tasteless as this may seem, making all members public allows member templates 501 // to work in the absence of member template friends. 502 public: 503 # else 504 505 template <class I, class V, class TC, class R, class D> friend class iterator_facade; 506 template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal> 507 friend class detail::iterator_facade_base; 508 509 # define BOOST_ITERATOR_FACADE_RELATION(op) \ 510 BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::iterators::detail::always_bool2); 511 512 BOOST_ITERATOR_FACADE_RELATION(==) 513 BOOST_ITERATOR_FACADE_RELATION(!=) 514 515 # undef BOOST_ITERATOR_FACADE_RELATION 516 517 # define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \ 518 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend,op, boost::iterators::detail::always_bool2); 519 520 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<) 521 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>) 522 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=) 523 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=) 524 525 # undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION 526 527 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD( 528 friend, -, boost::iterators::detail::choose_difference_type) 529 ; 530 531 BOOST_ITERATOR_FACADE_PLUS_HEAD( 532 friend inline 533 , (iterator_facade<Derived, V, TC, R, D> const& 534 , typename Derived::difference_type) 535 ) 536 ; 537 538 BOOST_ITERATOR_FACADE_PLUS_HEAD( 539 friend inline 540 , (typename Derived::difference_type 541 , iterator_facade<Derived, V, TC, R, D> const&) 542 ) 543 ; 544 545 # endif 546 547 template <class Facade> dereference(Facade const & f)548 static typename Facade::reference dereference(Facade const& f) 549 { 550 return f.dereference(); 551 } 552 553 template <class Facade> increment(Facade & f)554 static void increment(Facade& f) 555 { 556 f.increment(); 557 } 558 559 template <class Facade> decrement(Facade & f)560 static void decrement(Facade& f) 561 { 562 f.decrement(); 563 } 564 565 template <class Facade1, class Facade2> equal(Facade1 const & f1,Facade2 const & f2,mpl::true_)566 static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_) 567 { 568 return f1.equal(f2); 569 } 570 571 template <class Facade1, class Facade2> equal(Facade1 const & f1,Facade2 const & f2,mpl::false_)572 static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_) 573 { 574 return f2.equal(f1); 575 } 576 577 template <class Facade> advance(Facade & f,typename Facade::difference_type n)578 static void advance(Facade& f, typename Facade::difference_type n) 579 { 580 f.advance(n); 581 } 582 583 template <class Facade1, class Facade2> distance_from(Facade1 const & f1,Facade2 const & f2,mpl::true_)584 static typename Facade1::difference_type distance_from( 585 Facade1 const& f1, Facade2 const& f2, mpl::true_) 586 { 587 return -f1.distance_to(f2); 588 } 589 590 template <class Facade1, class Facade2> distance_from(Facade1 const & f1,Facade2 const & f2,mpl::false_)591 static typename Facade2::difference_type distance_from( 592 Facade1 const& f1, Facade2 const& f2, mpl::false_) 593 { 594 return f2.distance_to(f1); 595 } 596 597 // 598 // Curiously Recurring Template interface. 599 // 600 template <class I, class V, class TC, class R, class D> derived(iterator_facade<I,V,TC,R,D> & facade)601 static I& derived(iterator_facade<I,V,TC,R,D>& facade) 602 { 603 return *static_cast<I*>(&facade); 604 } 605 606 template <class I, class V, class TC, class R, class D> derived(iterator_facade<I,V,TC,R,D> const & facade)607 static I const& derived(iterator_facade<I,V,TC,R,D> const& facade) 608 { 609 return *static_cast<I const*>(&facade); 610 } 611 612 // objects of this class are useless 613 BOOST_DELETED_FUNCTION(iterator_core_access()) 614 }; 615 616 namespace detail { 617 618 // Implementation for forward traversal iterators 619 template < 620 class Derived 621 , class Value 622 , class CategoryOrTraversal 623 , class Reference 624 , class Difference 625 > 626 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false > 627 # ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 628 : public boost::iterators::detail::iterator_facade_types< 629 Value, CategoryOrTraversal, Reference, Difference 630 >::base 631 # undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 632 # endif 633 { 634 private: 635 typedef boost::iterators::detail::iterator_facade_types< 636 Value, CategoryOrTraversal, Reference, Difference 637 > associated_types; 638 639 typedef boost::iterators::detail::operator_arrow_dispatch< 640 Reference 641 , typename associated_types::pointer 642 > operator_arrow_dispatch_; 643 644 public: 645 typedef typename associated_types::value_type value_type; 646 typedef Reference reference; 647 typedef Difference difference_type; 648 649 typedef typename operator_arrow_dispatch_::result_type pointer; 650 651 typedef typename associated_types::iterator_category iterator_category; 652 653 public: operator *() const654 reference operator*() const 655 { 656 return iterator_core_access::dereference(this->derived()); 657 } 658 operator ->() const659 pointer operator->() const 660 { 661 return operator_arrow_dispatch_::apply(*this->derived()); 662 } 663 operator ++()664 Derived& operator++() 665 { 666 iterator_core_access::increment(this->derived()); 667 return this->derived(); 668 } 669 670 protected: 671 // 672 // Curiously Recurring Template interface. 673 // derived()674 Derived& derived() 675 { 676 return *static_cast<Derived*>(this); 677 } 678 derived() const679 Derived const& derived() const 680 { 681 return *static_cast<Derived const*>(this); 682 } 683 }; 684 685 // Implementation for bidirectional traversal iterators 686 template < 687 class Derived 688 , class Value 689 , class CategoryOrTraversal 690 , class Reference 691 , class Difference 692 > 693 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > : 694 public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false > 695 { 696 public: operator --()697 Derived& operator--() 698 { 699 iterator_core_access::decrement(this->derived()); 700 return this->derived(); 701 } 702 operator --(int)703 Derived operator--(int) 704 { 705 Derived tmp(this->derived()); 706 --*this; 707 return tmp; 708 } 709 }; 710 711 // Implementation for random access traversal iterators 712 template < 713 class Derived 714 , class Value 715 , class CategoryOrTraversal 716 , class Reference 717 , class Difference 718 > 719 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > : 720 public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > 721 { 722 private: 723 typedef iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > base_type; 724 725 public: 726 typedef typename base_type::reference reference; 727 typedef typename base_type::difference_type difference_type; 728 729 public: 730 typename boost::iterators::detail::operator_brackets_result<Derived, Value, reference>::type operator [](difference_type n) const731 operator[](difference_type n) const 732 { 733 typedef boost::iterators::detail::use_operator_brackets_proxy<Value, Reference> use_proxy; 734 735 return boost::iterators::detail::make_operator_brackets_result<Derived>( 736 this->derived() + n 737 , use_proxy() 738 ); 739 } 740 operator +=(difference_type n)741 Derived& operator+=(difference_type n) 742 { 743 iterator_core_access::advance(this->derived(), n); 744 return this->derived(); 745 } 746 operator -=(difference_type n)747 Derived& operator-=(difference_type n) 748 { 749 iterator_core_access::advance(this->derived(), -n); 750 return this->derived(); 751 } 752 operator -(difference_type x) const753 Derived operator-(difference_type x) const 754 { 755 Derived result(this->derived()); 756 return result -= x; 757 } 758 }; 759 760 } // namespace detail 761 762 // 763 // iterator_facade - use as a public base class for defining new 764 // standard-conforming iterators. 765 // 766 template < 767 class Derived // The derived iterator type being constructed 768 , class Value 769 , class CategoryOrTraversal 770 , class Reference = Value& 771 , class Difference = std::ptrdiff_t 772 > 773 class iterator_facade : 774 public detail::iterator_facade_base< 775 Derived, 776 Value, 777 CategoryOrTraversal, 778 Reference, 779 Difference, 780 detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value, 781 detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value 782 > 783 { 784 protected: 785 // For use by derived classes 786 typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_; 787 }; 788 789 template <class I, class V, class TC, class R, class D> 790 inline typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type operator ++(iterator_facade<I,V,TC,R,D> & i,int)791 operator++( 792 iterator_facade<I,V,TC,R,D>& i 793 , int 794 ) 795 { 796 typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type 797 tmp(*static_cast<I*>(&i)); 798 799 ++i; 800 801 return tmp; 802 } 803 804 805 // 806 // Comparison operator implementation. The library supplied operators 807 // enables the user to provide fully interoperable constant/mutable 808 // iterator types. I.e. the library provides all operators 809 // for all mutable/constant iterator combinations. 810 // 811 // Note though that this kind of interoperability for constant/mutable 812 // iterators is not required by the standard for container iterators. 813 // All the standard asks for is a conversion mutable -> constant. 814 // Most standard library implementations nowadays provide fully interoperable 815 // iterator implementations, but there are still heavily used implementations 816 // that do not provide them. (Actually it's even worse, they do not provide 817 // them for only a few iterators.) 818 // 819 // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should 820 // enable the user to turn off mixed type operators 821 // 822 // The library takes care to provide only the right operator overloads. 823 // I.e. 824 // 825 // bool operator==(Iterator, Iterator); 826 // bool operator==(ConstIterator, Iterator); 827 // bool operator==(Iterator, ConstIterator); 828 // bool operator==(ConstIterator, ConstIterator); 829 // 830 // ... 831 // 832 // In order to do so it uses c++ idioms that are not yet widely supported 833 // by current compiler releases. The library is designed to degrade gracefully 834 // in the face of compiler deficiencies. In general compiler 835 // deficiencies result in less strict error checking and more obscure 836 // error messages, functionality is not affected. 837 // 838 // For full operation compiler support for "Substitution Failure Is Not An Error" 839 // (aka. enable_if) and boost::is_convertible is required. 840 // 841 // The following problems occur if support is lacking. 842 // 843 // Pseudo code 844 // 845 // --------------- 846 // AdaptorA<Iterator1> a1; 847 // AdaptorA<Iterator2> a2; 848 // 849 // // This will result in a no such overload error in full operation 850 // // If enable_if or is_convertible is not supported 851 // // The instantiation will fail with an error hopefully indicating that 852 // // there is no operator== for Iterator1, Iterator2 853 // // The same will happen if no enable_if is used to remove 854 // // false overloads from the templated conversion constructor 855 // // of AdaptorA. 856 // 857 // a1 == a2; 858 // ---------------- 859 // 860 // AdaptorA<Iterator> a; 861 // AdaptorB<Iterator> b; 862 // 863 // // This will result in a no such overload error in full operation 864 // // If enable_if is not supported the static assert used 865 // // in the operator implementation will fail. 866 // // This will accidently work if is_convertible is not supported. 867 // 868 // a == b; 869 // ---------------- 870 // 871 872 # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP 873 # define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_() 874 # else 875 # define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>() 876 # endif 877 878 # define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \ 879 BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \ 880 { \ 881 /* For those compilers that do not support enable_if */ \ 882 BOOST_STATIC_ASSERT(( \ 883 is_interoperable< Derived1, Derived2 >::value \ 884 )); \ 885 return_prefix iterator_core_access::base_op( \ 886 *static_cast<Derived1 const*>(&lhs) \ 887 , *static_cast<Derived2 const*>(&rhs) \ 888 , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \ 889 ); \ 890 } 891 892 # define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \ 893 BOOST_ITERATOR_FACADE_INTEROP( \ 894 op \ 895 , boost::iterators::detail::always_bool2 \ 896 , return_prefix \ 897 , base_op \ 898 ) 899 900 BOOST_ITERATOR_FACADE_RELATION(==, return, equal) 901 BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal) 902 903 # undef BOOST_ITERATOR_FACADE_RELATION 904 905 906 # define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \ 907 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \ 908 { \ 909 /* For those compilers that do not support enable_if */ \ 910 BOOST_STATIC_ASSERT(( \ 911 is_interoperable< Derived1, Derived2 >::value && \ 912 boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived1 >::type, random_access_traversal_tag >::value && \ 913 boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived2 >::type, random_access_traversal_tag >::value \ 914 )); \ 915 return_prefix iterator_core_access::base_op( \ 916 *static_cast<Derived1 const*>(&lhs) \ 917 , *static_cast<Derived2 const*>(&rhs) \ 918 , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \ 919 ); \ 920 } 921 922 # define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \ 923 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \ 924 op \ 925 , boost::iterators::detail::always_bool2 \ 926 , return_prefix \ 927 , base_op \ 928 ) 929 930 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from) 931 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from) 932 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from) 933 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from) 934 935 # undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION 936 937 // operator- requires an additional part in the static assertion 938 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( 939 - 940 , boost::iterators::detail::choose_difference_type 941 , return 942 , distance_from 943 ) 944 945 # undef BOOST_ITERATOR_FACADE_INTEROP 946 # undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS 947 948 # define BOOST_ITERATOR_FACADE_PLUS(args) \ 949 BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \ 950 { \ 951 Derived tmp(static_cast<Derived const&>(i)); \ 952 return tmp += n; \ 953 } 954 955 BOOST_ITERATOR_FACADE_PLUS(( 956 iterator_facade<Derived, V, TC, R, D> const& i 957 , typename Derived::difference_type n 958 )) 959 960 BOOST_ITERATOR_FACADE_PLUS(( 961 typename Derived::difference_type n 962 , iterator_facade<Derived, V, TC, R, D> const& i 963 )) 964 965 # undef BOOST_ITERATOR_FACADE_PLUS 966 # undef BOOST_ITERATOR_FACADE_PLUS_HEAD 967 968 # undef BOOST_ITERATOR_FACADE_INTEROP_HEAD 969 # undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD 970 # undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL 971 972 } // namespace iterators 973 974 using iterators::iterator_core_access; 975 using iterators::iterator_facade; 976 977 } // namespace boost 978 979 #include <boost/iterator/detail/config_undef.hpp> 980 981 #endif // BOOST_ITERATOR_FACADE_23022003THW_HPP 982