1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2005-2009. 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_CONTAINERS_DETAIL_ITERATORS_HPP 15 #define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP 16 17 #if (defined _MSC_VER) && (_MSC_VER >= 1200) 18 # pragma once 19 #endif 20 21 #include "config_begin.hpp" 22 #include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP 23 #include INCLUDE_BOOST_CONTAINER_MOVE_HPP 24 25 #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING 26 #include INCLUDE_BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP 27 #include INCLUDE_BOOST_CONTAINER_DETAIL_STORED_REF_HPP 28 #else 29 #include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP 30 #endif 31 32 #include <iterator> 33 34 namespace boost { 35 namespace container { 36 37 template <class T, class Difference = std::ptrdiff_t> 38 class constant_iterator 39 : public std::iterator 40 <std::random_access_iterator_tag, T, Difference, const T*, const T &> 41 { 42 typedef constant_iterator<T, Difference> this_type; 43 44 public: constant_iterator(const T & ref,Difference range_size)45 explicit constant_iterator(const T &ref, Difference range_size) 46 : m_ptr(&ref), m_num(range_size){} 47 48 //Constructors constant_iterator()49 constant_iterator() 50 : m_ptr(0), m_num(0){} 51 operator ++()52 constant_iterator& operator++() 53 { increment(); return *this; } 54 operator ++(int)55 constant_iterator operator++(int) 56 { 57 constant_iterator result (*this); 58 increment(); 59 return result; 60 } 61 operator --()62 constant_iterator& operator--() 63 { decrement(); return *this; } 64 operator --(int)65 constant_iterator operator--(int) 66 { 67 constant_iterator result (*this); 68 decrement(); 69 return result; 70 } 71 operator ==(const constant_iterator & i,const constant_iterator & i2)72 friend bool operator== (const constant_iterator& i, const constant_iterator& i2) 73 { return i.equal(i2); } 74 operator !=(const constant_iterator & i,const constant_iterator & i2)75 friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) 76 { return !(i == i2); } 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.less(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 i2 < i; } 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 > 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 !(i < i2); } 89 operator -(const constant_iterator & i,const constant_iterator & i2)90 friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) 91 { return i2.distance_to(i); } 92 93 //Arithmetic operator +=(Difference off)94 constant_iterator& operator+=(Difference off) 95 { this->advance(off); return *this; } 96 operator +(Difference off) const97 constant_iterator operator+(Difference off) const 98 { 99 constant_iterator other(*this); 100 other.advance(off); 101 return other; 102 } 103 operator +(Difference off,const constant_iterator & right)104 friend constant_iterator operator+(Difference off, const constant_iterator& right) 105 { return right + off; } 106 operator -=(Difference off)107 constant_iterator& operator-=(Difference off) 108 { this->advance(-off); return *this; } 109 operator -(Difference off) const110 constant_iterator operator-(Difference off) const 111 { return *this + (-off); } 112 operator *() const113 const T& operator*() const 114 { return dereference(); } 115 operator [](Difference n) const116 const T& operator[] (Difference n) const 117 { return dereference(); } 118 operator ->() const119 const T* operator->() const 120 { return &(dereference()); } 121 122 private: 123 const T * m_ptr; 124 Difference m_num; 125 increment()126 void increment() 127 { --m_num; } 128 decrement()129 void decrement() 130 { ++m_num; } 131 equal(const this_type & other) const132 bool equal(const this_type &other) const 133 { return m_num == other.m_num; } 134 less(const this_type & other) const135 bool less(const this_type &other) const 136 { return other.m_num < m_num; } 137 dereference() const138 const T & dereference() const 139 { return *m_ptr; } 140 advance(Difference n)141 void advance(Difference n) 142 { m_num -= n; } 143 distance_to(const this_type & other) const144 Difference distance_to(const this_type &other)const 145 { return m_num - other.m_num; } 146 }; 147 148 template <class T, class Difference = std::ptrdiff_t> 149 class default_construct_iterator 150 : public std::iterator 151 <std::random_access_iterator_tag, T, Difference, const T*, const T &> 152 { 153 typedef default_construct_iterator<T, Difference> this_type; 154 155 public: default_construct_iterator(Difference range_size)156 explicit default_construct_iterator(Difference range_size) 157 : m_num(range_size){} 158 159 //Constructors default_construct_iterator()160 default_construct_iterator() 161 : m_num(0){} 162 operator ++()163 default_construct_iterator& operator++() 164 { increment(); return *this; } 165 operator ++(int)166 default_construct_iterator operator++(int) 167 { 168 default_construct_iterator result (*this); 169 increment(); 170 return result; 171 } 172 operator --()173 default_construct_iterator& operator--() 174 { decrement(); return *this; } 175 operator --(int)176 default_construct_iterator operator--(int) 177 { 178 default_construct_iterator result (*this); 179 decrement(); 180 return result; 181 } 182 operator ==(const default_construct_iterator & i,const default_construct_iterator & i2)183 friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2) 184 { return i.equal(i2); } 185 operator !=(const default_construct_iterator & i,const default_construct_iterator & i2)186 friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2) 187 { return !(i == i2); } 188 operator <(const default_construct_iterator & i,const default_construct_iterator & i2)189 friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2) 190 { return i.less(i2); } 191 operator >(const default_construct_iterator & i,const default_construct_iterator & i2)192 friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2) 193 { return i2 < i; } 194 operator <=(const default_construct_iterator & i,const default_construct_iterator & i2)195 friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2) 196 { return !(i > i2); } 197 operator >=(const default_construct_iterator & i,const default_construct_iterator & i2)198 friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2) 199 { return !(i < i2); } 200 operator -(const default_construct_iterator & i,const default_construct_iterator & i2)201 friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2) 202 { return i2.distance_to(i); } 203 204 //Arithmetic operator +=(Difference off)205 default_construct_iterator& operator+=(Difference off) 206 { this->advance(off); return *this; } 207 operator +(Difference off) const208 default_construct_iterator operator+(Difference off) const 209 { 210 default_construct_iterator other(*this); 211 other.advance(off); 212 return other; 213 } 214 operator +(Difference off,const default_construct_iterator & right)215 friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right) 216 { return right + off; } 217 operator -=(Difference off)218 default_construct_iterator& operator-=(Difference off) 219 { this->advance(-off); return *this; } 220 operator -(Difference off) const221 default_construct_iterator operator-(Difference off) const 222 { return *this + (-off); } 223 operator *() const224 const T& operator*() const 225 { return dereference(); } 226 operator ->() const227 const T* operator->() const 228 { return &(dereference()); } 229 operator [](Difference n) const230 const T& operator[] (Difference n) const 231 { return dereference(); } 232 233 private: 234 Difference m_num; 235 increment()236 void increment() 237 { --m_num; } 238 decrement()239 void decrement() 240 { ++m_num; } 241 equal(const this_type & other) const242 bool equal(const this_type &other) const 243 { return m_num == other.m_num; } 244 less(const this_type & other) const245 bool less(const this_type &other) const 246 { return other.m_num < m_num; } 247 dereference() const248 const T & dereference() const 249 { 250 static T dummy; 251 return dummy; 252 } 253 advance(Difference n)254 void advance(Difference n) 255 { m_num -= n; } 256 distance_to(const this_type & other) const257 Difference distance_to(const this_type &other)const 258 { return m_num - other.m_num; } 259 }; 260 261 template <class T, class Difference = std::ptrdiff_t> 262 class repeat_iterator 263 : public std::iterator 264 <std::random_access_iterator_tag, T, Difference> 265 { 266 typedef repeat_iterator<T, Difference> this_type; 267 public: repeat_iterator(T & ref,Difference range_size)268 explicit repeat_iterator(T &ref, Difference range_size) 269 : m_ptr(&ref), m_num(range_size){} 270 271 //Constructors repeat_iterator()272 repeat_iterator() 273 : m_ptr(0), m_num(0){} 274 operator ++()275 this_type& operator++() 276 { increment(); return *this; } 277 operator ++(int)278 this_type operator++(int) 279 { 280 this_type result (*this); 281 increment(); 282 return result; 283 } 284 operator --()285 this_type& operator--() 286 { increment(); return *this; } 287 operator --(int)288 this_type operator--(int) 289 { 290 this_type result (*this); 291 increment(); 292 return result; 293 } 294 operator ==(const this_type & i,const this_type & i2)295 friend bool operator== (const this_type& i, const this_type& i2) 296 { return i.equal(i2); } 297 operator !=(const this_type & i,const this_type & i2)298 friend bool operator!= (const this_type& i, const this_type& i2) 299 { return !(i == i2); } 300 operator <(const this_type & i,const this_type & i2)301 friend bool operator< (const this_type& i, const this_type& i2) 302 { return i.less(i2); } 303 operator >(const this_type & i,const this_type & i2)304 friend bool operator> (const this_type& i, const this_type& i2) 305 { return i2 < i; } 306 operator <=(const this_type & i,const this_type & i2)307 friend bool operator<= (const this_type& i, const this_type& i2) 308 { return !(i > i2); } 309 operator >=(const this_type & i,const this_type & i2)310 friend bool operator>= (const this_type& i, const this_type& i2) 311 { return !(i < i2); } 312 operator -(const this_type & i,const this_type & i2)313 friend Difference operator- (const this_type& i, const this_type& i2) 314 { return i2.distance_to(i); } 315 316 //Arithmetic operator +=(Difference off)317 this_type& operator+=(Difference off) 318 { this->advance(off); return *this; } 319 operator +(Difference off) const320 this_type operator+(Difference off) const 321 { 322 this_type other(*this); 323 other.advance(off); 324 return other; 325 } 326 operator +(Difference off,const this_type & right)327 friend this_type operator+(Difference off, const this_type& right) 328 { return right + off; } 329 operator -=(Difference off)330 this_type& operator-=(Difference off) 331 { this->advance(-off); return *this; } 332 operator -(Difference off) const333 this_type operator-(Difference off) const 334 { return *this + (-off); } 335 operator *() const336 T& operator*() const 337 { return dereference(); } 338 operator [](Difference n) const339 T& operator[] (Difference n) const 340 { return dereference(); } 341 operator ->() const342 T *operator->() const 343 { return &(dereference()); } 344 345 private: 346 T * m_ptr; 347 Difference m_num; 348 increment()349 void increment() 350 { --m_num; } 351 decrement()352 void decrement() 353 { ++m_num; } 354 equal(const this_type & other) const355 bool equal(const this_type &other) const 356 { return m_num == other.m_num; } 357 less(const this_type & other) const358 bool less(const this_type &other) const 359 { return other.m_num < m_num; } 360 dereference() const361 T & dereference() const 362 { return *m_ptr; } 363 advance(Difference n)364 void advance(Difference n) 365 { m_num -= n; } 366 distance_to(const this_type & other) const367 Difference distance_to(const this_type &other)const 368 { return m_num - other.m_num; } 369 }; 370 371 template <class T, class E> 372 class emplace_iterator 373 : public std::iterator 374 <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> 375 { 376 typedef emplace_iterator this_type; 377 378 public: emplace_iterator(E & e)379 explicit emplace_iterator(E&e) 380 : m_num(1), m_pe(&e){} 381 emplace_iterator()382 emplace_iterator() 383 : m_num(0), m_pe(0){} 384 operator ++()385 this_type& operator++() 386 { increment(); return *this; } 387 operator ++(int)388 this_type operator++(int) 389 { 390 this_type result (*this); 391 increment(); 392 return result; 393 } 394 operator --()395 this_type& operator--() 396 { decrement(); return *this; } 397 operator --(int)398 this_type operator--(int) 399 { 400 this_type result (*this); 401 decrement(); 402 return result; 403 } 404 operator ==(const this_type & i,const this_type & i2)405 friend bool operator== (const this_type& i, const this_type& i2) 406 { return i.equal(i2); } 407 operator !=(const this_type & i,const this_type & i2)408 friend bool operator!= (const this_type& i, const this_type& i2) 409 { return !(i == i2); } 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.less(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 i2 < i; } 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 > 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 !(i < i2); } 422 operator -(const this_type & i,const this_type & i2)423 friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2) 424 { return i2.distance_to(i); } 425 426 //Arithmetic operator +=(std::ptrdiff_t off)427 this_type& operator+=(std::ptrdiff_t off) 428 { this->advance(off); return *this; } 429 operator +(std::ptrdiff_t off) const430 this_type operator+(std::ptrdiff_t off) const 431 { 432 this_type other(*this); 433 other.advance(off); 434 return other; 435 } 436 operator +(std::ptrdiff_t off,const this_type & right)437 friend this_type operator+(std::ptrdiff_t off, const this_type& right) 438 { return right + off; } 439 operator -=(std::ptrdiff_t off)440 this_type& operator-=(std::ptrdiff_t off) 441 { this->advance(-off); return *this; } 442 operator -(std::ptrdiff_t off) const443 this_type operator-(std::ptrdiff_t off) const 444 { return *this + (-off); } 445 operator *() const446 const T& operator*() const 447 { return dereference(); } 448 operator [](std::ptrdiff_t) const449 const T& operator[](std::ptrdiff_t) const 450 { return dereference(); } 451 operator ->() const452 const T* operator->() const 453 { return &(dereference()); } 454 construct_in_place(T * ptr)455 void construct_in_place(T* ptr) 456 { (*m_pe)(ptr); } 457 458 private: 459 std::ptrdiff_t m_num; 460 E * m_pe; 461 increment()462 void increment() 463 { --m_num; } 464 decrement()465 void decrement() 466 { ++m_num; } 467 equal(const this_type & other) const468 bool equal(const this_type &other) const 469 { return m_num == other.m_num; } 470 less(const this_type & other) const471 bool less(const this_type &other) const 472 { return other.m_num < m_num; } 473 dereference() const474 const T & dereference() const 475 { 476 static T dummy; 477 return dummy; 478 } 479 advance(std::ptrdiff_t n)480 void advance(std::ptrdiff_t n) 481 { m_num -= n; } 482 distance_to(const this_type & other) const483 std::ptrdiff_t distance_to(const this_type &other)const 484 { return m_num - other.m_num; } 485 }; 486 487 #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING 488 489 template<class T, class ...Args> 490 struct emplace_functor 491 { 492 typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t; 493 emplace_functorboost::container::emplace_functor494 emplace_functor(Args&&... args) 495 : args_(args...) 496 {} 497 operator ()boost::container::emplace_functor498 void operator()(T *ptr) 499 { emplace_functor::inplace_impl(ptr, index_tuple_t()); } 500 501 template<int ...IdxPack> inplace_implboost::container::emplace_functor502 void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&) 503 { ::new(ptr) T(containers_detail::stored_ref<Args>::forward(containers_detail::get<IdxPack>(args_))...); } 504 505 containers_detail::tuple<Args&...> args_; 506 }; 507 508 #else 509 510 template<class T> 511 struct emplace_functor 512 { emplace_functorboost::container::emplace_functor513 emplace_functor() 514 {} operator ()boost::container::emplace_functor515 void operator()(T *ptr) 516 { new(ptr) T(); } 517 }; 518 519 #define BOOST_PP_LOCAL_MACRO(n) \ 520 template <class T, BOOST_PP_ENUM_PARAMS(n, class P) > \ 521 struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ 522 { \ 523 BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ 524 ( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \ 525 : BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \ 526 \ 527 void operator()(T *ptr) \ 528 { \ 529 new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \ 530 } \ 531 BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \ 532 }; \ 533 //! 534 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS) 535 #include BOOST_PP_LOCAL_ITERATE() 536 537 #endif 538 539 } //namespace container { 540 } //namespace boost { 541 542 #include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP 543 544 #endif //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP 545 546