1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2005-2013. 4 // (C) Copyright Gennaro Prota 2003 - 2004. 5 // 6 // Distributed under the Boost Software License, Version 1.0. 7 // (See accompanying file LICENSE_1_0.txt or copy at 8 // http://www.boost.org/LICENSE_1_0.txt) 9 // 10 // See http://www.boost.org/libs/container for documentation. 11 // 12 ////////////////////////////////////////////////////////////////////////////// 13 14 #ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP 15 #define BOOST_CONTAINER_DETAIL_ITERATORS_HPP 16 17 #ifndef BOOST_CONFIG_HPP 18 # include <boost/config.hpp> 19 #endif 20 21 #if defined(BOOST_HAS_PRAGMA_ONCE) 22 # pragma once 23 #endif 24 25 #include <boost/container/detail/config_begin.hpp> 26 #include <boost/container/detail/workaround.hpp> 27 #include <boost/container/allocator_traits.hpp> 28 #include <boost/container/detail/type_traits.hpp> 29 #include <boost/static_assert.hpp> 30 #include <boost/move/utility_core.hpp> 31 #include <boost/intrusive/detail/reverse_iterator.hpp> 32 33 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 34 #include <boost/move/detail/fwd_macros.hpp> 35 #else 36 #include <boost/container/detail/variadic_templates_tools.hpp> 37 #endif 38 #include <boost/container/detail/iterator.hpp> 39 40 namespace boost { 41 namespace container { 42 43 template <class T, class Difference = std::ptrdiff_t> 44 class constant_iterator 45 : public ::boost::container::iterator 46 <std::random_access_iterator_tag, T, Difference, const T*, const T &> 47 { 48 typedef constant_iterator<T, Difference> this_type; 49 50 public: constant_iterator(const T & ref,Difference range_size)51 explicit constant_iterator(const T &ref, Difference range_size) 52 : m_ptr(&ref), m_num(range_size){} 53 54 //Constructors constant_iterator()55 constant_iterator() 56 : m_ptr(0), m_num(0){} 57 operator ++()58 constant_iterator& operator++() 59 { increment(); return *this; } 60 operator ++(int)61 constant_iterator operator++(int) 62 { 63 constant_iterator result (*this); 64 increment(); 65 return result; 66 } 67 operator --()68 constant_iterator& operator--() 69 { decrement(); return *this; } 70 operator --(int)71 constant_iterator operator--(int) 72 { 73 constant_iterator result (*this); 74 decrement(); 75 return result; 76 } 77 operator ==(const constant_iterator & i,const constant_iterator & i2)78 friend bool operator== (const constant_iterator& i, const constant_iterator& i2) 79 { return i.equal(i2); } 80 operator !=(const constant_iterator & i,const constant_iterator & i2)81 friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) 82 { return !(i == i2); } 83 operator <(const constant_iterator & i,const constant_iterator & i2)84 friend bool operator< (const constant_iterator& i, const constant_iterator& i2) 85 { return i.less(i2); } 86 operator >(const constant_iterator & i,const constant_iterator & i2)87 friend bool operator> (const constant_iterator& i, const constant_iterator& i2) 88 { return i2 < i; } 89 operator <=(const constant_iterator & i,const constant_iterator & i2)90 friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) 91 { return !(i > i2); } 92 operator >=(const constant_iterator & i,const constant_iterator & i2)93 friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) 94 { return !(i < i2); } 95 operator -(const constant_iterator & i,const constant_iterator & i2)96 friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) 97 { return i2.distance_to(i); } 98 99 //Arithmetic operator +=(Difference off)100 constant_iterator& operator+=(Difference off) 101 { this->advance(off); return *this; } 102 operator +(Difference off) const103 constant_iterator operator+(Difference off) const 104 { 105 constant_iterator other(*this); 106 other.advance(off); 107 return other; 108 } 109 operator +(Difference off,const constant_iterator & right)110 friend constant_iterator operator+(Difference off, const constant_iterator& right) 111 { return right + off; } 112 operator -=(Difference off)113 constant_iterator& operator-=(Difference off) 114 { this->advance(-off); return *this; } 115 operator -(Difference off) const116 constant_iterator operator-(Difference off) const 117 { return *this + (-off); } 118 operator *() const119 const T& operator*() const 120 { return dereference(); } 121 operator [](Difference) const122 const T& operator[] (Difference ) const 123 { return dereference(); } 124 operator ->() const125 const T* operator->() const 126 { return &(dereference()); } 127 128 private: 129 const T * m_ptr; 130 Difference m_num; 131 increment()132 void increment() 133 { --m_num; } 134 decrement()135 void decrement() 136 { ++m_num; } 137 equal(const this_type & other) const138 bool equal(const this_type &other) const 139 { return m_num == other.m_num; } 140 less(const this_type & other) const141 bool less(const this_type &other) const 142 { return other.m_num < m_num; } 143 dereference() const144 const T & dereference() const 145 { return *m_ptr; } 146 advance(Difference n)147 void advance(Difference n) 148 { m_num -= n; } 149 distance_to(const this_type & other) const150 Difference distance_to(const this_type &other)const 151 { return m_num - other.m_num; } 152 }; 153 154 template <class T, class Difference> 155 class value_init_construct_iterator 156 : public ::boost::container::iterator 157 <std::random_access_iterator_tag, T, Difference, const T*, const T &> 158 { 159 typedef value_init_construct_iterator<T, Difference> this_type; 160 161 public: value_init_construct_iterator(Difference range_size)162 explicit value_init_construct_iterator(Difference range_size) 163 : m_num(range_size){} 164 165 //Constructors value_init_construct_iterator()166 value_init_construct_iterator() 167 : m_num(0){} 168 operator ++()169 value_init_construct_iterator& operator++() 170 { increment(); return *this; } 171 operator ++(int)172 value_init_construct_iterator operator++(int) 173 { 174 value_init_construct_iterator result (*this); 175 increment(); 176 return result; 177 } 178 operator --()179 value_init_construct_iterator& operator--() 180 { decrement(); return *this; } 181 operator --(int)182 value_init_construct_iterator operator--(int) 183 { 184 value_init_construct_iterator result (*this); 185 decrement(); 186 return result; 187 } 188 operator ==(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)189 friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) 190 { return i.equal(i2); } 191 operator !=(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)192 friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) 193 { return !(i == i2); } 194 operator <(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)195 friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) 196 { return i.less(i2); } 197 operator >(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)198 friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) 199 { return i2 < i; } 200 operator <=(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)201 friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) 202 { return !(i > i2); } 203 operator >=(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)204 friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) 205 { return !(i < i2); } 206 operator -(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)207 friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) 208 { return i2.distance_to(i); } 209 210 //Arithmetic operator +=(Difference off)211 value_init_construct_iterator& operator+=(Difference off) 212 { this->advance(off); return *this; } 213 operator +(Difference off) const214 value_init_construct_iterator operator+(Difference off) const 215 { 216 value_init_construct_iterator other(*this); 217 other.advance(off); 218 return other; 219 } 220 operator +(Difference off,const value_init_construct_iterator & right)221 friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right) 222 { return right + off; } 223 operator -=(Difference off)224 value_init_construct_iterator& operator-=(Difference off) 225 { this->advance(-off); return *this; } 226 operator -(Difference off) const227 value_init_construct_iterator operator-(Difference off) const 228 { return *this + (-off); } 229 230 //This pseudo-iterator's dereference operations have no sense since value is not 231 //constructed until ::boost::container::construct_in_place is called. 232 //So comment them to catch bad uses 233 //const T& operator*() const; 234 //const T& operator[](difference_type) const; 235 //const T* operator->() const; 236 237 private: 238 Difference m_num; 239 increment()240 void increment() 241 { --m_num; } 242 decrement()243 void decrement() 244 { ++m_num; } 245 equal(const this_type & other) const246 bool equal(const this_type &other) const 247 { return m_num == other.m_num; } 248 less(const this_type & other) const249 bool less(const this_type &other) const 250 { return other.m_num < m_num; } 251 dereference() const252 const T & dereference() const 253 { 254 static T dummy; 255 return dummy; 256 } 257 advance(Difference n)258 void advance(Difference n) 259 { m_num -= n; } 260 distance_to(const this_type & other) const261 Difference distance_to(const this_type &other)const 262 { return m_num - other.m_num; } 263 }; 264 265 template <class T, class Difference> 266 class default_init_construct_iterator 267 : public ::boost::container::iterator 268 <std::random_access_iterator_tag, T, Difference, const T*, const T &> 269 { 270 typedef default_init_construct_iterator<T, Difference> this_type; 271 272 public: default_init_construct_iterator(Difference range_size)273 explicit default_init_construct_iterator(Difference range_size) 274 : m_num(range_size){} 275 276 //Constructors default_init_construct_iterator()277 default_init_construct_iterator() 278 : m_num(0){} 279 operator ++()280 default_init_construct_iterator& operator++() 281 { increment(); return *this; } 282 operator ++(int)283 default_init_construct_iterator operator++(int) 284 { 285 default_init_construct_iterator result (*this); 286 increment(); 287 return result; 288 } 289 operator --()290 default_init_construct_iterator& operator--() 291 { decrement(); return *this; } 292 operator --(int)293 default_init_construct_iterator operator--(int) 294 { 295 default_init_construct_iterator result (*this); 296 decrement(); 297 return result; 298 } 299 operator ==(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)300 friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) 301 { return i.equal(i2); } 302 operator !=(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)303 friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) 304 { return !(i == i2); } 305 operator <(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)306 friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) 307 { return i.less(i2); } 308 operator >(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)309 friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) 310 { return i2 < i; } 311 operator <=(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)312 friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) 313 { return !(i > i2); } 314 operator >=(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)315 friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) 316 { return !(i < i2); } 317 operator -(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)318 friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) 319 { return i2.distance_to(i); } 320 321 //Arithmetic operator +=(Difference off)322 default_init_construct_iterator& operator+=(Difference off) 323 { this->advance(off); return *this; } 324 operator +(Difference off) const325 default_init_construct_iterator operator+(Difference off) const 326 { 327 default_init_construct_iterator other(*this); 328 other.advance(off); 329 return other; 330 } 331 operator +(Difference off,const default_init_construct_iterator & right)332 friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right) 333 { return right + off; } 334 operator -=(Difference off)335 default_init_construct_iterator& operator-=(Difference off) 336 { this->advance(-off); return *this; } 337 operator -(Difference off) const338 default_init_construct_iterator operator-(Difference off) const 339 { return *this + (-off); } 340 341 //This pseudo-iterator's dereference operations have no sense since value is not 342 //constructed until ::boost::container::construct_in_place is called. 343 //So comment them to catch bad uses 344 //const T& operator*() const; 345 //const T& operator[](difference_type) const; 346 //const T* operator->() const; 347 348 private: 349 Difference m_num; 350 increment()351 void increment() 352 { --m_num; } 353 decrement()354 void decrement() 355 { ++m_num; } 356 equal(const this_type & other) const357 bool equal(const this_type &other) const 358 { return m_num == other.m_num; } 359 less(const this_type & other) const360 bool less(const this_type &other) const 361 { return other.m_num < m_num; } 362 dereference() const363 const T & dereference() const 364 { 365 static T dummy; 366 return dummy; 367 } 368 advance(Difference n)369 void advance(Difference n) 370 { m_num -= n; } 371 distance_to(const this_type & other) const372 Difference distance_to(const this_type &other)const 373 { return m_num - other.m_num; } 374 }; 375 376 377 template <class T, class Difference = std::ptrdiff_t> 378 class repeat_iterator 379 : public ::boost::container::iterator 380 <std::random_access_iterator_tag, T, Difference> 381 { 382 typedef repeat_iterator<T, Difference> this_type; 383 public: repeat_iterator(T & ref,Difference range_size)384 explicit repeat_iterator(T &ref, Difference range_size) 385 : m_ptr(&ref), m_num(range_size){} 386 387 //Constructors repeat_iterator()388 repeat_iterator() 389 : m_ptr(0), m_num(0){} 390 operator ++()391 this_type& operator++() 392 { increment(); return *this; } 393 operator ++(int)394 this_type operator++(int) 395 { 396 this_type result (*this); 397 increment(); 398 return result; 399 } 400 operator --()401 this_type& operator--() 402 { increment(); return *this; } 403 operator --(int)404 this_type operator--(int) 405 { 406 this_type result (*this); 407 increment(); 408 return result; 409 } 410 operator ==(const this_type & i,const this_type & i2)411 friend bool operator== (const this_type& i, const this_type& i2) 412 { return i.equal(i2); } 413 operator !=(const this_type & i,const this_type & i2)414 friend bool operator!= (const this_type& i, const this_type& i2) 415 { return !(i == i2); } 416 operator <(const this_type & i,const this_type & i2)417 friend bool operator< (const this_type& i, const this_type& i2) 418 { return i.less(i2); } 419 operator >(const this_type & i,const this_type & i2)420 friend bool operator> (const this_type& i, const this_type& i2) 421 { return i2 < i; } 422 operator <=(const this_type & i,const this_type & i2)423 friend bool operator<= (const this_type& i, const this_type& i2) 424 { return !(i > i2); } 425 operator >=(const this_type & i,const this_type & i2)426 friend bool operator>= (const this_type& i, const this_type& i2) 427 { return !(i < i2); } 428 operator -(const this_type & i,const this_type & i2)429 friend Difference operator- (const this_type& i, const this_type& i2) 430 { return i2.distance_to(i); } 431 432 //Arithmetic operator +=(Difference off)433 this_type& operator+=(Difference off) 434 { this->advance(off); return *this; } 435 operator +(Difference off) const436 this_type operator+(Difference off) const 437 { 438 this_type other(*this); 439 other.advance(off); 440 return other; 441 } 442 operator +(Difference off,const this_type & right)443 friend this_type operator+(Difference off, const this_type& right) 444 { return right + off; } 445 operator -=(Difference off)446 this_type& operator-=(Difference off) 447 { this->advance(-off); return *this; } 448 operator -(Difference off) const449 this_type operator-(Difference off) const 450 { return *this + (-off); } 451 operator *() const452 T& operator*() const 453 { return dereference(); } 454 operator [](Difference) const455 T& operator[] (Difference ) const 456 { return dereference(); } 457 operator ->() const458 T *operator->() const 459 { return &(dereference()); } 460 461 private: 462 T * m_ptr; 463 Difference m_num; 464 increment()465 void increment() 466 { --m_num; } 467 decrement()468 void decrement() 469 { ++m_num; } 470 equal(const this_type & other) const471 bool equal(const this_type &other) const 472 { return m_num == other.m_num; } 473 less(const this_type & other) const474 bool less(const this_type &other) const 475 { return other.m_num < m_num; } 476 dereference() const477 T & dereference() const 478 { return *m_ptr; } 479 advance(Difference n)480 void advance(Difference n) 481 { m_num -= n; } 482 distance_to(const this_type & other) const483 Difference distance_to(const this_type &other)const 484 { return m_num - other.m_num; } 485 }; 486 487 template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/> 488 class emplace_iterator 489 : public ::boost::container::iterator 490 <std::random_access_iterator_tag, T, Difference, const T*, const T &> 491 { 492 typedef emplace_iterator this_type; 493 494 public: 495 typedef Difference difference_type; emplace_iterator(EmplaceFunctor & e)496 explicit emplace_iterator(EmplaceFunctor&e) 497 : m_num(1), m_pe(&e){} 498 emplace_iterator()499 emplace_iterator() 500 : m_num(0), m_pe(0){} 501 operator ++()502 this_type& operator++() 503 { increment(); return *this; } 504 operator ++(int)505 this_type operator++(int) 506 { 507 this_type result (*this); 508 increment(); 509 return result; 510 } 511 operator --()512 this_type& operator--() 513 { decrement(); return *this; } 514 operator --(int)515 this_type operator--(int) 516 { 517 this_type result (*this); 518 decrement(); 519 return result; 520 } 521 operator ==(const this_type & i,const this_type & i2)522 friend bool operator== (const this_type& i, const this_type& i2) 523 { return i.equal(i2); } 524 operator !=(const this_type & i,const this_type & i2)525 friend bool operator!= (const this_type& i, const this_type& i2) 526 { return !(i == i2); } 527 operator <(const this_type & i,const this_type & i2)528 friend bool operator< (const this_type& i, const this_type& i2) 529 { return i.less(i2); } 530 operator >(const this_type & i,const this_type & i2)531 friend bool operator> (const this_type& i, const this_type& i2) 532 { return i2 < i; } 533 operator <=(const this_type & i,const this_type & i2)534 friend bool operator<= (const this_type& i, const this_type& i2) 535 { return !(i > i2); } 536 operator >=(const this_type & i,const this_type & i2)537 friend bool operator>= (const this_type& i, const this_type& i2) 538 { return !(i < i2); } 539 operator -(const this_type & i,const this_type & i2)540 friend difference_type operator- (const this_type& i, const this_type& i2) 541 { return i2.distance_to(i); } 542 543 //Arithmetic operator +=(difference_type off)544 this_type& operator+=(difference_type off) 545 { this->advance(off); return *this; } 546 operator +(difference_type off) const547 this_type operator+(difference_type off) const 548 { 549 this_type other(*this); 550 other.advance(off); 551 return other; 552 } 553 operator +(difference_type off,const this_type & right)554 friend this_type operator+(difference_type off, const this_type& right) 555 { return right + off; } 556 operator -=(difference_type off)557 this_type& operator-=(difference_type off) 558 { this->advance(-off); return *this; } 559 operator -(difference_type off) const560 this_type operator-(difference_type off) const 561 { return *this + (-off); } 562 563 //This pseudo-iterator's dereference operations have no sense since value is not 564 //constructed until ::boost::container::construct_in_place is called. 565 //So comment them to catch bad uses 566 //const T& operator*() const; 567 //const T& operator[](difference_type) const; 568 //const T* operator->() const; 569 570 template<class Allocator> construct_in_place(Allocator & a,T * ptr)571 void construct_in_place(Allocator &a, T* ptr) 572 { (*m_pe)(a, ptr); } 573 574 private: 575 difference_type m_num; 576 EmplaceFunctor * m_pe; 577 increment()578 void increment() 579 { --m_num; } 580 decrement()581 void decrement() 582 { ++m_num; } 583 equal(const this_type & other) const584 bool equal(const this_type &other) const 585 { return m_num == other.m_num; } 586 less(const this_type & other) const587 bool less(const this_type &other) const 588 { return other.m_num < m_num; } 589 dereference() const590 const T & dereference() const 591 { 592 static T dummy; 593 return dummy; 594 } 595 advance(difference_type n)596 void advance(difference_type n) 597 { m_num -= n; } 598 distance_to(const this_type & other) const599 difference_type distance_to(const this_type &other)const 600 { return difference_type(m_num - other.m_num); } 601 }; 602 603 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 604 605 template<class ...Args> 606 struct emplace_functor 607 { 608 typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t; 609 emplace_functorboost::container::emplace_functor610 emplace_functor(BOOST_FWD_REF(Args)... args) 611 : args_(args...) 612 {} 613 614 template<class Allocator, class T> operator ()boost::container::emplace_functor615 void operator()(Allocator &a, T *ptr) 616 { emplace_functor::inplace_impl(a, ptr, index_tuple_t()); } 617 618 template<class Allocator, class T, int ...IdxPack> inplace_implboost::container::emplace_functor619 void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&) 620 { 621 allocator_traits<Allocator>::construct 622 (a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...); 623 } 624 625 container_detail::tuple<Args&...> args_; 626 }; 627 628 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 629 630 #define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \ 631 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ 632 struct emplace_functor##N\ 633 {\ 634 explicit emplace_functor##N( BOOST_MOVE_UREF##N )\ 635 BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ 636 \ 637 template<class Allocator, class T>\ 638 void operator()(Allocator &a, T *ptr)\ 639 { allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\ 640 \ 641 BOOST_MOVE_MREF##N\ 642 };\ 643 // 644 BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE) 645 #undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE 646 647 #endif 648 649 namespace container_detail { 650 651 template<class T> 652 struct has_iterator_category 653 { 654 struct two { char _[2]; }; 655 656 template <typename X> 657 static char test(int, typename X::iterator_category*); 658 659 template <typename X> 660 static two test(int, ...); 661 662 static const bool value = (1 == sizeof(test<T>(0, 0))); 663 }; 664 665 666 template<class T, bool = has_iterator_category<T>::value > 667 struct is_input_iterator 668 { 669 static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value; 670 }; 671 672 template<class T> 673 struct is_input_iterator<T, false> 674 { 675 static const bool value = false; 676 }; 677 678 template<class T> 679 struct is_not_input_iterator 680 { 681 static const bool value = !is_input_iterator<T>::value; 682 }; 683 684 template<class T, bool = has_iterator_category<T>::value > 685 struct is_forward_iterator 686 { 687 static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value; 688 }; 689 690 template<class T> 691 struct is_forward_iterator<T, false> 692 { 693 static const bool value = false; 694 }; 695 696 template<class T, bool = has_iterator_category<T>::value > 697 struct is_bidirectional_iterator 698 { 699 static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value; 700 }; 701 702 template<class T> 703 struct is_bidirectional_iterator<T, false> 704 { 705 static const bool value = false; 706 }; 707 708 template<class IINodeType> 709 struct iiterator_node_value_type { 710 typedef typename IINodeType::value_type type; 711 }; 712 713 template<class IIterator> 714 struct iiterator_types 715 { 716 typedef typename IIterator::value_type it_value_type; 717 typedef typename iiterator_node_value_type<it_value_type>::type value_type; 718 typedef typename boost::container::iterator_traits<IIterator>::pointer it_pointer; 719 typedef typename boost::container::iterator_traits<IIterator>::difference_type difference_type; 720 typedef typename ::boost::intrusive::pointer_traits<it_pointer>:: 721 template rebind_pointer<value_type>::type pointer; 722 typedef typename ::boost::intrusive::pointer_traits<it_pointer>:: 723 template rebind_pointer<const value_type>::type const_pointer; 724 typedef typename ::boost::intrusive:: 725 pointer_traits<pointer>::reference reference; 726 typedef typename ::boost::intrusive:: 727 pointer_traits<const_pointer>::reference const_reference; 728 typedef typename IIterator::iterator_category iterator_category; 729 }; 730 731 template<class IIterator, bool IsConst> 732 struct iterator_types 733 { 734 typedef typename ::boost::container::iterator 735 < typename iiterator_types<IIterator>::iterator_category 736 , typename iiterator_types<IIterator>::value_type 737 , typename iiterator_types<IIterator>::difference_type 738 , typename iiterator_types<IIterator>::const_pointer 739 , typename iiterator_types<IIterator>::const_reference> type; 740 }; 741 742 template<class IIterator> 743 struct iterator_types<IIterator, false> 744 { 745 typedef typename ::boost::container::iterator 746 < typename iiterator_types<IIterator>::iterator_category 747 , typename iiterator_types<IIterator>::value_type 748 , typename iiterator_types<IIterator>::difference_type 749 , typename iiterator_types<IIterator>::pointer 750 , typename iiterator_types<IIterator>::reference> type; 751 }; 752 753 template<class IIterator, bool IsConst> 754 class iterator_from_iiterator 755 { 756 typedef typename iterator_types<IIterator, IsConst>::type types_t; 757 758 public: 759 typedef typename types_t::pointer pointer; 760 typedef typename types_t::reference reference; 761 typedef typename types_t::difference_type difference_type; 762 typedef typename types_t::iterator_category iterator_category; 763 typedef typename types_t::value_type value_type; 764 iterator_from_iiterator()765 iterator_from_iiterator() 766 {} 767 iterator_from_iiterator(IIterator iit)768 explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW 769 : m_iit(iit) 770 {} 771 iterator_from_iiterator(iterator_from_iiterator<IIterator,false> const & other)772 iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW 773 : m_iit(other.get()) 774 {} 775 operator ++()776 iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW 777 { ++this->m_iit; return *this; } 778 operator ++(int)779 iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW 780 { 781 iterator_from_iiterator result (*this); 782 ++this->m_iit; 783 return result; 784 } 785 operator --()786 iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW 787 { 788 //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist 789 BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value)); 790 --this->m_iit; return *this; 791 } 792 operator --(int)793 iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW 794 { 795 iterator_from_iiterator result (*this); 796 --this->m_iit; 797 return result; 798 } 799 operator ==(const iterator_from_iiterator & l,const iterator_from_iiterator & r)800 friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW 801 { return l.m_iit == r.m_iit; } 802 operator !=(const iterator_from_iiterator & l,const iterator_from_iiterator & r)803 friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW 804 { return !(l == r); } 805 operator *() const806 reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW 807 { return this->m_iit->get_data(); } 808 operator ->() const809 pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW 810 { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); } 811 get() const812 const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW 813 { return this->m_iit; } 814 815 private: 816 IIterator m_iit; 817 }; 818 819 } //namespace container_detail { 820 821 using ::boost::intrusive::reverse_iterator; 822 823 } //namespace container { 824 } //namespace boost { 825 826 #include <boost/container/detail/config_end.hpp> 827 828 #endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP 829