iterators.hpp 31 KB

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