iterators.hpp 27 KB

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