iterators.hpp 29 KB

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