iterators.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  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. #ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
  14. #define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
  15. #ifndef BOOST_CONFIG_HPP
  16. # include <boost/config.hpp>
  17. #endif
  18. #if defined(BOOST_HAS_PRAGMA_ONCE)
  19. # pragma once
  20. #endif
  21. #include <boost/container/detail/config_begin.hpp>
  22. #include <boost/container/detail/workaround.hpp>
  23. #include <boost/container/allocator_traits.hpp>
  24. #include <boost/container/detail/type_traits.hpp>
  25. #include <boost/static_assert.hpp>
  26. #include <boost/move/utility_core.hpp>
  27. #include <boost/intrusive/detail/reverse_iterator.hpp>
  28. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  29. #include <boost/move/detail/fwd_macros.hpp>
  30. #else
  31. #include <boost/container/detail/variadic_templates_tools.hpp>
  32. #endif
  33. #include <boost/container/detail/iterator.hpp>
  34. namespace boost {
  35. namespace container {
  36. template <class T, class Difference = std::ptrdiff_t>
  37. class constant_iterator
  38. : public ::boost::container::iterator
  39. <std::random_access_iterator_tag, T, Difference, const T*, const T &>
  40. {
  41. typedef constant_iterator<T, Difference> this_type;
  42. public:
  43. explicit constant_iterator(const T &ref, Difference range_size)
  44. : m_ptr(&ref), m_num(range_size){}
  45. //Constructors
  46. constant_iterator()
  47. : m_ptr(0), m_num(0){}
  48. constant_iterator& operator++()
  49. { increment(); return *this; }
  50. constant_iterator operator++(int)
  51. {
  52. constant_iterator result (*this);
  53. increment();
  54. return result;
  55. }
  56. constant_iterator& operator--()
  57. { decrement(); return *this; }
  58. constant_iterator operator--(int)
  59. {
  60. constant_iterator result (*this);
  61. decrement();
  62. return result;
  63. }
  64. friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
  65. { return i.equal(i2); }
  66. friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
  67. { return !(i == i2); }
  68. friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
  69. { return i.less(i2); }
  70. friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
  71. { return i2 < i; }
  72. friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
  73. { return !(i > i2); }
  74. friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
  75. { return !(i < i2); }
  76. friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
  77. { return i2.distance_to(i); }
  78. //Arithmetic
  79. constant_iterator& operator+=(Difference off)
  80. { this->advance(off); return *this; }
  81. constant_iterator operator+(Difference off) const
  82. {
  83. constant_iterator other(*this);
  84. other.advance(off);
  85. return other;
  86. }
  87. friend constant_iterator operator+(Difference off, const constant_iterator& right)
  88. { return right + off; }
  89. constant_iterator& operator-=(Difference off)
  90. { this->advance(-off); return *this; }
  91. constant_iterator operator-(Difference off) const
  92. { return *this + (-off); }
  93. const T& operator*() const
  94. { return dereference(); }
  95. const T& operator[] (Difference ) const
  96. { return dereference(); }
  97. const T* operator->() const
  98. { return &(dereference()); }
  99. private:
  100. const T * m_ptr;
  101. Difference m_num;
  102. void increment()
  103. { --m_num; }
  104. void decrement()
  105. { ++m_num; }
  106. bool equal(const this_type &other) const
  107. { return m_num == other.m_num; }
  108. bool less(const this_type &other) const
  109. { return other.m_num < m_num; }
  110. const T & dereference() const
  111. { return *m_ptr; }
  112. void advance(Difference n)
  113. { m_num -= n; }
  114. Difference distance_to(const this_type &other)const
  115. { return m_num - other.m_num; }
  116. };
  117. template <class T, class Difference>
  118. class value_init_construct_iterator
  119. : public ::boost::container::iterator
  120. <std::random_access_iterator_tag, T, Difference, const T*, const T &>
  121. {
  122. typedef value_init_construct_iterator<T, Difference> this_type;
  123. public:
  124. explicit value_init_construct_iterator(Difference range_size)
  125. : m_num(range_size){}
  126. //Constructors
  127. value_init_construct_iterator()
  128. : m_num(0){}
  129. value_init_construct_iterator& operator++()
  130. { increment(); return *this; }
  131. value_init_construct_iterator operator++(int)
  132. {
  133. value_init_construct_iterator result (*this);
  134. increment();
  135. return result;
  136. }
  137. value_init_construct_iterator& operator--()
  138. { decrement(); return *this; }
  139. value_init_construct_iterator operator--(int)
  140. {
  141. value_init_construct_iterator result (*this);
  142. decrement();
  143. return result;
  144. }
  145. friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
  146. { return i.equal(i2); }
  147. friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
  148. { return !(i == i2); }
  149. friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
  150. { return i.less(i2); }
  151. friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
  152. { return i2 < i; }
  153. friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
  154. { return !(i > i2); }
  155. friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
  156. { return !(i < i2); }
  157. friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
  158. { return i2.distance_to(i); }
  159. //Arithmetic
  160. value_init_construct_iterator& operator+=(Difference off)
  161. { this->advance(off); return *this; }
  162. value_init_construct_iterator operator+(Difference off) const
  163. {
  164. value_init_construct_iterator other(*this);
  165. other.advance(off);
  166. return other;
  167. }
  168. friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
  169. { return right + off; }
  170. value_init_construct_iterator& operator-=(Difference off)
  171. { this->advance(-off); return *this; }
  172. value_init_construct_iterator operator-(Difference off) const
  173. { return *this + (-off); }
  174. //This pseudo-iterator's dereference operations have no sense since value is not
  175. //constructed until ::boost::container::construct_in_place is called.
  176. //So comment them to catch bad uses
  177. //const T& operator*() const;
  178. //const T& operator[](difference_type) const;
  179. //const T* operator->() const;
  180. private:
  181. Difference m_num;
  182. void increment()
  183. { --m_num; }
  184. void decrement()
  185. { ++m_num; }
  186. bool equal(const this_type &other) const
  187. { return m_num == other.m_num; }
  188. bool less(const this_type &other) const
  189. { return other.m_num < m_num; }
  190. const T & dereference() const
  191. {
  192. static T dummy;
  193. return dummy;
  194. }
  195. void advance(Difference n)
  196. { m_num -= n; }
  197. Difference distance_to(const this_type &other)const
  198. { return m_num - other.m_num; }
  199. };
  200. template <class T, class Difference>
  201. class default_init_construct_iterator
  202. : public ::boost::container::iterator
  203. <std::random_access_iterator_tag, T, Difference, const T*, const T &>
  204. {
  205. typedef default_init_construct_iterator<T, Difference> this_type;
  206. public:
  207. explicit default_init_construct_iterator(Difference range_size)
  208. : m_num(range_size){}
  209. //Constructors
  210. default_init_construct_iterator()
  211. : m_num(0){}
  212. default_init_construct_iterator& operator++()
  213. { increment(); return *this; }
  214. default_init_construct_iterator operator++(int)
  215. {
  216. default_init_construct_iterator result (*this);
  217. increment();
  218. return result;
  219. }
  220. default_init_construct_iterator& operator--()
  221. { decrement(); return *this; }
  222. default_init_construct_iterator operator--(int)
  223. {
  224. default_init_construct_iterator result (*this);
  225. decrement();
  226. return result;
  227. }
  228. friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
  229. { return i.equal(i2); }
  230. friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
  231. { return !(i == i2); }
  232. friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
  233. { return i.less(i2); }
  234. friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
  235. { return i2 < i; }
  236. friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
  237. { return !(i > i2); }
  238. friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
  239. { return !(i < i2); }
  240. friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
  241. { return i2.distance_to(i); }
  242. //Arithmetic
  243. default_init_construct_iterator& operator+=(Difference off)
  244. { this->advance(off); return *this; }
  245. default_init_construct_iterator operator+(Difference off) const
  246. {
  247. default_init_construct_iterator other(*this);
  248. other.advance(off);
  249. return other;
  250. }
  251. friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
  252. { return right + off; }
  253. default_init_construct_iterator& operator-=(Difference off)
  254. { this->advance(-off); return *this; }
  255. default_init_construct_iterator operator-(Difference off) const
  256. { return *this + (-off); }
  257. //This pseudo-iterator's dereference operations have no sense since value is not
  258. //constructed until ::boost::container::construct_in_place is called.
  259. //So comment them to catch bad uses
  260. //const T& operator*() const;
  261. //const T& operator[](difference_type) const;
  262. //const T* operator->() const;
  263. private:
  264. Difference m_num;
  265. void increment()
  266. { --m_num; }
  267. void decrement()
  268. { ++m_num; }
  269. bool equal(const this_type &other) const
  270. { return m_num == other.m_num; }
  271. bool less(const this_type &other) const
  272. { return other.m_num < m_num; }
  273. const T & dereference() const
  274. {
  275. static T dummy;
  276. return dummy;
  277. }
  278. void advance(Difference n)
  279. { m_num -= n; }
  280. Difference distance_to(const this_type &other)const
  281. { return m_num - other.m_num; }
  282. };
  283. template <class T, class Difference = std::ptrdiff_t>
  284. class repeat_iterator
  285. : public ::boost::container::iterator
  286. <std::random_access_iterator_tag, T, Difference, T*, T&>
  287. {
  288. typedef repeat_iterator<T, Difference> this_type;
  289. public:
  290. explicit repeat_iterator(T &ref, Difference range_size)
  291. : m_ptr(&ref), m_num(range_size){}
  292. //Constructors
  293. repeat_iterator()
  294. : m_ptr(0), m_num(0){}
  295. this_type& operator++()
  296. { increment(); return *this; }
  297. this_type operator++(int)
  298. {
  299. this_type result (*this);
  300. increment();
  301. return result;
  302. }
  303. this_type& operator--()
  304. { increment(); return *this; }
  305. this_type operator--(int)
  306. {
  307. this_type result (*this);
  308. increment();
  309. return result;
  310. }
  311. friend bool operator== (const this_type& i, const this_type& i2)
  312. { return i.equal(i2); }
  313. friend bool operator!= (const this_type& i, const this_type& i2)
  314. { return !(i == i2); }
  315. friend bool operator< (const this_type& i, const this_type& i2)
  316. { return i.less(i2); }
  317. friend bool operator> (const this_type& i, const this_type& i2)
  318. { return i2 < i; }
  319. friend bool operator<= (const this_type& i, const this_type& i2)
  320. { return !(i > i2); }
  321. friend bool operator>= (const this_type& i, const this_type& i2)
  322. { return !(i < i2); }
  323. friend Difference operator- (const this_type& i, const this_type& i2)
  324. { return i2.distance_to(i); }
  325. //Arithmetic
  326. this_type& operator+=(Difference off)
  327. { this->advance(off); return *this; }
  328. this_type operator+(Difference off) const
  329. {
  330. this_type other(*this);
  331. other.advance(off);
  332. return other;
  333. }
  334. friend this_type operator+(Difference off, const this_type& right)
  335. { return right + off; }
  336. this_type& operator-=(Difference off)
  337. { this->advance(-off); return *this; }
  338. this_type operator-(Difference off) const
  339. { return *this + (-off); }
  340. T& operator*() const
  341. { return dereference(); }
  342. T& operator[] (Difference ) const
  343. { return dereference(); }
  344. T *operator->() const
  345. { return &(dereference()); }
  346. private:
  347. T * m_ptr;
  348. Difference m_num;
  349. void increment()
  350. { --m_num; }
  351. void decrement()
  352. { ++m_num; }
  353. bool equal(const this_type &other) const
  354. { return m_num == other.m_num; }
  355. bool less(const this_type &other) const
  356. { return other.m_num < m_num; }
  357. T & dereference() const
  358. { return *m_ptr; }
  359. void advance(Difference n)
  360. { m_num -= n; }
  361. Difference distance_to(const this_type &other)const
  362. { return m_num - other.m_num; }
  363. };
  364. template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/>
  365. class emplace_iterator
  366. : public ::boost::container::iterator
  367. <std::random_access_iterator_tag, T, Difference, const T*, const T &>
  368. {
  369. typedef emplace_iterator this_type;
  370. public:
  371. typedef Difference difference_type;
  372. BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e)
  373. : m_num(1), m_pe(&e){}
  374. BOOST_CONTAINER_FORCEINLINE emplace_iterator()
  375. : m_num(0), m_pe(0){}
  376. BOOST_CONTAINER_FORCEINLINE this_type& operator++()
  377. { increment(); return *this; }
  378. this_type operator++(int)
  379. {
  380. this_type result (*this);
  381. increment();
  382. return result;
  383. }
  384. BOOST_CONTAINER_FORCEINLINE this_type& operator--()
  385. { decrement(); return *this; }
  386. this_type operator--(int)
  387. {
  388. this_type result (*this);
  389. decrement();
  390. return result;
  391. }
  392. BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2)
  393. { return i.equal(i2); }
  394. BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2)
  395. { return !(i == i2); }
  396. BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2)
  397. { return i.less(i2); }
  398. BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2)
  399. { return i2 < i; }
  400. BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2)
  401. { return !(i > i2); }
  402. BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2)
  403. { return !(i < i2); }
  404. BOOST_CONTAINER_FORCEINLINE friend difference_type operator- (const this_type& i, const this_type& i2)
  405. { return i2.distance_to(i); }
  406. //Arithmetic
  407. BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off)
  408. { this->advance(off); return *this; }
  409. this_type operator+(difference_type off) const
  410. {
  411. this_type other(*this);
  412. other.advance(off);
  413. return other;
  414. }
  415. BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right)
  416. { return right + off; }
  417. BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off)
  418. { this->advance(-off); return *this; }
  419. BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const
  420. { return *this + (-off); }
  421. //This pseudo-iterator's dereference operations have no sense since value is not
  422. //constructed until ::boost::container::construct_in_place is called.
  423. //So comment them to catch bad uses
  424. //const T& operator*() const;
  425. //const T& operator[](difference_type) const;
  426. //const T* operator->() const;
  427. template<class Allocator>
  428. void construct_in_place(Allocator &a, T* ptr)
  429. { (*m_pe)(a, ptr); }
  430. private:
  431. difference_type m_num;
  432. EmplaceFunctor * m_pe;
  433. BOOST_CONTAINER_FORCEINLINE void increment()
  434. { --m_num; }
  435. BOOST_CONTAINER_FORCEINLINE void decrement()
  436. { ++m_num; }
  437. BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
  438. { return m_num == other.m_num; }
  439. BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
  440. { return other.m_num < m_num; }
  441. BOOST_CONTAINER_FORCEINLINE const T & dereference() const
  442. {
  443. static T dummy;
  444. return dummy;
  445. }
  446. BOOST_CONTAINER_FORCEINLINE void advance(difference_type n)
  447. { m_num -= n; }
  448. BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const
  449. { return difference_type(m_num - other.m_num); }
  450. };
  451. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  452. template<class ...Args>
  453. struct emplace_functor
  454. {
  455. typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
  456. emplace_functor(BOOST_FWD_REF(Args)... args)
  457. : args_(args...)
  458. {}
  459. template<class Allocator, class T>
  460. void operator()(Allocator &a, T *ptr)
  461. { emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
  462. template<class Allocator, class T, int ...IdxPack>
  463. BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
  464. {
  465. allocator_traits<Allocator>::construct
  466. (a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
  467. }
  468. container_detail::tuple<Args&...> args_;
  469. };
  470. #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  471. #define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
  472. BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
  473. struct emplace_functor##N\
  474. {\
  475. explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
  476. BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
  477. \
  478. template<class Allocator, class T>\
  479. void operator()(Allocator &a, T *ptr)\
  480. { allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
  481. \
  482. BOOST_MOVE_MREF##N\
  483. };\
  484. //
  485. BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
  486. #undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
  487. #endif
  488. namespace container_detail {
  489. template<class T>
  490. struct has_iterator_category
  491. {
  492. struct two { char _[2]; };
  493. template <typename X>
  494. static char test(int, typename X::iterator_category*);
  495. template <typename X>
  496. static two test(int, ...);
  497. static const bool value = (1 == sizeof(test<T>(0, 0)));
  498. };
  499. template<class T, bool = has_iterator_category<T>::value >
  500. struct is_input_iterator
  501. {
  502. static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value;
  503. };
  504. template<class T>
  505. struct is_input_iterator<T, false>
  506. {
  507. static const bool value = false;
  508. };
  509. template<class T>
  510. struct is_not_input_iterator
  511. {
  512. static const bool value = !is_input_iterator<T>::value;
  513. };
  514. template<class T, bool = has_iterator_category<T>::value >
  515. struct is_forward_iterator
  516. {
  517. static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value;
  518. };
  519. template<class T>
  520. struct is_forward_iterator<T, false>
  521. {
  522. static const bool value = false;
  523. };
  524. template<class T, bool = has_iterator_category<T>::value >
  525. struct is_bidirectional_iterator
  526. {
  527. static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value;
  528. };
  529. template<class T>
  530. struct is_bidirectional_iterator<T, false>
  531. {
  532. static const bool value = false;
  533. };
  534. template<class IINodeType>
  535. struct iiterator_node_value_type {
  536. typedef typename IINodeType::value_type type;
  537. };
  538. template<class IIterator>
  539. struct iiterator_types
  540. {
  541. typedef typename IIterator::value_type it_value_type;
  542. typedef typename iiterator_node_value_type<it_value_type>::type value_type;
  543. typedef typename boost::container::iterator_traits<IIterator>::pointer it_pointer;
  544. typedef typename boost::container::iterator_traits<IIterator>::difference_type difference_type;
  545. typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
  546. template rebind_pointer<value_type>::type pointer;
  547. typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
  548. template rebind_pointer<const value_type>::type const_pointer;
  549. typedef typename ::boost::intrusive::
  550. pointer_traits<pointer>::reference reference;
  551. typedef typename ::boost::intrusive::
  552. pointer_traits<const_pointer>::reference const_reference;
  553. typedef typename IIterator::iterator_category iterator_category;
  554. };
  555. template<class IIterator, bool IsConst>
  556. struct iterator_types
  557. {
  558. typedef typename ::boost::container::iterator
  559. < typename iiterator_types<IIterator>::iterator_category
  560. , typename iiterator_types<IIterator>::value_type
  561. , typename iiterator_types<IIterator>::difference_type
  562. , typename iiterator_types<IIterator>::const_pointer
  563. , typename iiterator_types<IIterator>::const_reference> type;
  564. };
  565. template<class IIterator>
  566. struct iterator_types<IIterator, false>
  567. {
  568. typedef typename ::boost::container::iterator
  569. < typename iiterator_types<IIterator>::iterator_category
  570. , typename iiterator_types<IIterator>::value_type
  571. , typename iiterator_types<IIterator>::difference_type
  572. , typename iiterator_types<IIterator>::pointer
  573. , typename iiterator_types<IIterator>::reference> type;
  574. };
  575. template<class IIterator, bool IsConst>
  576. class iterator_from_iiterator
  577. {
  578. typedef typename iterator_types<IIterator, IsConst>::type types_t;
  579. public:
  580. typedef typename types_t::pointer pointer;
  581. typedef typename types_t::reference reference;
  582. typedef typename types_t::difference_type difference_type;
  583. typedef typename types_t::iterator_category iterator_category;
  584. typedef typename types_t::value_type value_type;
  585. BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator()
  586. {}
  587. BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
  588. : m_iit(iit)
  589. {}
  590. BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
  591. : m_iit(other.get())
  592. {}
  593. BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
  594. { ++this->m_iit; return *this; }
  595. BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
  596. {
  597. iterator_from_iiterator result (*this);
  598. ++this->m_iit;
  599. return result;
  600. }
  601. BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
  602. {
  603. //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist
  604. BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value));
  605. --this->m_iit; return *this;
  606. }
  607. BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
  608. {
  609. iterator_from_iiterator result (*this);
  610. --this->m_iit;
  611. return result;
  612. }
  613. BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  614. { return l.m_iit == r.m_iit; }
  615. BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
  616. { return !(l == r); }
  617. BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
  618. { return this->m_iit->get_data(); }
  619. BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
  620. { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
  621. BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW
  622. { return this->m_iit; }
  623. private:
  624. IIterator m_iit;
  625. };
  626. } //namespace container_detail {
  627. using ::boost::intrusive::reverse_iterator;
  628. } //namespace container {
  629. } //namespace boost {
  630. #include <boost/container/detail/config_end.hpp>
  631. #endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP