any_iterator.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2010. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
  11. #define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED
  12. #include <boost/cast.hpp>
  13. #include <boost/mpl/and.hpp>
  14. #include <boost/mpl/or.hpp>
  15. #include <boost/mpl/not.hpp>
  16. #include <boost/iterator/iterator_facade.hpp>
  17. #include <boost/type_traits/is_const.hpp>
  18. #include <boost/type_traits/is_reference.hpp>
  19. #include <boost/type_traits/remove_reference.hpp>
  20. #include <boost/range/detail/any_iterator_buffer.hpp>
  21. #include <boost/range/detail/any_iterator_interface.hpp>
  22. #include <boost/range/detail/any_iterator_wrapper.hpp>
  23. #include <boost/utility/enable_if.hpp>
  24. namespace boost
  25. {
  26. namespace range_detail
  27. {
  28. // metafunction to determine if T is a const reference
  29. template<class T>
  30. struct is_const_reference
  31. {
  32. typedef typename mpl::and_<
  33. typename is_reference<T>::type,
  34. typename is_const<
  35. typename remove_reference<T>::type
  36. >::type
  37. >::type type;
  38. };
  39. // metafunction to determine if T is a mutable reference
  40. template<class T>
  41. struct is_mutable_reference
  42. {
  43. typedef typename mpl::and_<
  44. typename is_reference<T>::type,
  45. typename mpl::not_<
  46. typename is_const<
  47. typename remove_reference<T>::type
  48. >::type
  49. >::type
  50. >::type type;
  51. };
  52. // metafunction to evaluate if a source 'reference' can be
  53. // converted to a target 'reference' as a value.
  54. //
  55. // This is true, when the target reference type is actually
  56. // not a reference, and the source reference is convertible
  57. // to the target type.
  58. template<class SourceReference, class TargetReference>
  59. struct is_convertible_to_value_as_reference
  60. {
  61. typedef typename mpl::and_<
  62. typename mpl::not_<
  63. typename is_reference<TargetReference>::type
  64. >::type
  65. , typename is_convertible<
  66. SourceReference
  67. , TargetReference
  68. >::type
  69. >::type type;
  70. };
  71. template<
  72. class Value
  73. , class Traversal
  74. , class Reference
  75. , class Difference
  76. , class Buffer = any_iterator_default_buffer
  77. >
  78. class any_iterator;
  79. // metafunction to determine if SomeIterator is an
  80. // any_iterator.
  81. //
  82. // This is the general implementation which evaluates to false.
  83. template<class SomeIterator>
  84. struct is_any_iterator
  85. : mpl::bool_<false>
  86. {
  87. };
  88. // specialization of is_any_iterator to return true for
  89. // any_iterator classes regardless of template parameters.
  90. template<
  91. class Value
  92. , class Traversal
  93. , class Reference
  94. , class Difference
  95. , class Buffer
  96. >
  97. struct is_any_iterator<
  98. any_iterator<
  99. Value
  100. , Traversal
  101. , Reference
  102. , Difference
  103. , Buffer
  104. >
  105. >
  106. : mpl::bool_<true>
  107. {
  108. };
  109. } // namespace range_detail
  110. namespace detail
  111. {
  112. // Rationale:
  113. // These are specialized since the iterator_facade versions lack
  114. // the requisite typedefs to allow wrapping to determine the types
  115. // if a user copy constructs from a postfix increment.
  116. template<
  117. class Value
  118. , class Traversal
  119. , class Reference
  120. , class Difference
  121. , class Buffer
  122. >
  123. class postfix_increment_proxy<
  124. range_detail::any_iterator<
  125. Value
  126. , Traversal
  127. , Reference
  128. , Difference
  129. , Buffer
  130. >
  131. >
  132. {
  133. typedef range_detail::any_iterator<
  134. Value
  135. , Traversal
  136. , Reference
  137. , Difference
  138. , Buffer
  139. > any_iterator_type;
  140. public:
  141. typedef Value value_type;
  142. typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
  143. typedef Difference difference_type;
  144. typedef typename iterator_pointer<any_iterator_type>::type pointer;
  145. typedef Reference reference;
  146. explicit postfix_increment_proxy(any_iterator_type const& x)
  147. : stored_value(*x)
  148. {}
  149. value_type&
  150. operator*() const
  151. {
  152. return this->stored_value;
  153. }
  154. private:
  155. mutable value_type stored_value;
  156. };
  157. template<
  158. class Value
  159. , class Traversal
  160. , class Reference
  161. , class Difference
  162. , class Buffer
  163. >
  164. class writable_postfix_increment_proxy<
  165. range_detail::any_iterator<
  166. Value
  167. , Traversal
  168. , Reference
  169. , Difference
  170. , Buffer
  171. >
  172. >
  173. {
  174. typedef range_detail::any_iterator<
  175. Value
  176. , Traversal
  177. , Reference
  178. , Difference
  179. , Buffer
  180. > any_iterator_type;
  181. public:
  182. typedef Value value_type;
  183. typedef typename std::iterator_traits<any_iterator_type>::iterator_category iterator_category;
  184. typedef Difference difference_type;
  185. typedef typename iterator_pointer<any_iterator_type>::type pointer;
  186. typedef Reference reference;
  187. explicit writable_postfix_increment_proxy(any_iterator_type const& x)
  188. : stored_value(*x)
  189. , stored_iterator(x)
  190. {}
  191. // Dereferencing must return a proxy so that both *r++ = o and
  192. // value_type(*r++) can work. In this case, *r is the same as
  193. // *r++, and the conversion operator below is used to ensure
  194. // readability.
  195. writable_postfix_increment_proxy const&
  196. operator*() const
  197. {
  198. return *this;
  199. }
  200. // Provides readability of *r++
  201. operator value_type&() const
  202. {
  203. return stored_value;
  204. }
  205. // Provides writability of *r++
  206. template <class T>
  207. T const& operator=(T const& x) const
  208. {
  209. *this->stored_iterator = x;
  210. return x;
  211. }
  212. // This overload just in case only non-const objects are writable
  213. template <class T>
  214. T& operator=(T& x) const
  215. {
  216. *this->stored_iterator = x;
  217. return x;
  218. }
  219. // Provides X(r++)
  220. operator any_iterator_type const&() const
  221. {
  222. return stored_iterator;
  223. }
  224. private:
  225. mutable value_type stored_value;
  226. any_iterator_type stored_iterator;
  227. };
  228. }
  229. namespace range_detail
  230. {
  231. template<
  232. class Value
  233. , class Traversal
  234. , class Reference
  235. , class Difference
  236. , class Buffer
  237. >
  238. class any_iterator
  239. : public iterator_facade<
  240. any_iterator<
  241. Value
  242. , Traversal
  243. , Reference
  244. , Difference
  245. , Buffer
  246. >
  247. , Value
  248. , Traversal
  249. , Reference
  250. , Difference
  251. >
  252. {
  253. template<
  254. class OtherValue
  255. , class OtherTraversal
  256. , class OtherReference
  257. , class OtherDifference
  258. , class OtherBuffer
  259. >
  260. friend class any_iterator;
  261. struct enabler {};
  262. struct disabler {};
  263. typedef typename any_iterator_interface_type_generator<
  264. Traversal
  265. , Reference
  266. , Difference
  267. , Buffer
  268. >::type abstract_base_type;
  269. typedef iterator_facade<
  270. any_iterator<
  271. Value
  272. , Traversal
  273. , Reference
  274. , Difference
  275. , Buffer
  276. >
  277. , Value
  278. , Traversal
  279. , Reference
  280. , Difference
  281. > base_type;
  282. typedef Buffer buffer_type;
  283. public:
  284. typedef typename base_type::value_type value_type;
  285. typedef typename base_type::reference reference;
  286. typedef typename base_type::difference_type difference_type;
  287. // Default constructor
  288. any_iterator()
  289. : m_impl(0) {}
  290. // Simple copy construction without conversion
  291. any_iterator(const any_iterator& other)
  292. : base_type(other)
  293. , m_impl(other.m_impl
  294. ? other.m_impl->clone(m_buffer)
  295. : 0)
  296. {
  297. }
  298. // Simple assignment operator without conversion
  299. any_iterator& operator=(const any_iterator& other)
  300. {
  301. if (this != &other)
  302. {
  303. if (m_impl)
  304. m_impl->~abstract_base_type();
  305. m_buffer.deallocate();
  306. m_impl = 0;
  307. if (other.m_impl)
  308. m_impl = other.m_impl->clone(m_buffer);
  309. }
  310. return *this;
  311. }
  312. // Implicit conversion from another any_iterator where the
  313. // conversion is from a non-const reference to a const reference
  314. template<
  315. class OtherValue
  316. , class OtherTraversal
  317. , class OtherReference
  318. , class OtherDifference
  319. >
  320. any_iterator(const any_iterator<
  321. OtherValue,
  322. OtherTraversal,
  323. OtherReference,
  324. OtherDifference,
  325. Buffer
  326. >& other,
  327. typename enable_if<
  328. typename mpl::and_<
  329. typename is_mutable_reference<OtherReference>::type,
  330. typename is_const_reference<Reference>::type
  331. >::type,
  332. enabler
  333. >::type* = 0
  334. )
  335. : m_impl(other.m_impl
  336. ? other.m_impl->clone_const_ref(m_buffer)
  337. : 0
  338. )
  339. {
  340. }
  341. // Implicit conversion from another any_iterator where the
  342. // reference types of the source and the target are references
  343. // that are either both const, or both non-const.
  344. template<
  345. class OtherValue
  346. , class OtherTraversal
  347. , class OtherReference
  348. , class OtherDifference
  349. >
  350. any_iterator(const any_iterator<
  351. OtherValue
  352. , OtherTraversal
  353. , OtherReference
  354. , OtherDifference
  355. , Buffer
  356. >& other,
  357. typename enable_if<
  358. typename mpl::or_<
  359. typename mpl::and_<
  360. typename is_mutable_reference<OtherReference>::type,
  361. typename is_mutable_reference<Reference>::type
  362. >::type,
  363. typename mpl::and_<
  364. typename is_const_reference<OtherReference>::type,
  365. typename is_const_reference<Reference>::type
  366. >::type
  367. >::type,
  368. enabler
  369. >::type* = 0
  370. )
  371. : m_impl(other.m_impl
  372. ? other.m_impl->clone(m_buffer)
  373. : 0
  374. )
  375. {
  376. }
  377. // Implicit conversion to an any_iterator that uses a value for
  378. // the reference type.
  379. template<
  380. class OtherValue
  381. , class OtherTraversal
  382. , class OtherReference
  383. , class OtherDifference
  384. >
  385. any_iterator(const any_iterator<
  386. OtherValue
  387. , OtherTraversal
  388. , OtherReference
  389. , OtherDifference
  390. , Buffer
  391. >& other,
  392. typename enable_if<
  393. typename is_convertible_to_value_as_reference<
  394. OtherReference
  395. , Reference
  396. >::type,
  397. enabler
  398. >::type* = 0
  399. )
  400. : m_impl(other.m_impl
  401. ? other.m_impl->clone_reference_as_value(m_buffer)
  402. : 0
  403. )
  404. {
  405. }
  406. any_iterator clone() const
  407. {
  408. any_iterator result;
  409. if (m_impl)
  410. result.m_impl = m_impl->clone(result.m_buffer);
  411. return result;
  412. }
  413. any_iterator<
  414. Value
  415. , Traversal
  416. , typename abstract_base_type::const_reference
  417. , Difference
  418. , Buffer
  419. >
  420. clone_const_ref() const
  421. {
  422. typedef any_iterator<
  423. Value
  424. , Traversal
  425. , typename abstract_base_type::const_reference
  426. , Difference
  427. , Buffer
  428. > result_type;
  429. result_type result;
  430. if (m_impl)
  431. result.m_impl = m_impl->clone_const_ref(result.m_buffer);
  432. return result;
  433. }
  434. // implicit conversion and construction from type-erasure-compatible
  435. // iterators
  436. template<class WrappedIterator>
  437. explicit any_iterator(
  438. const WrappedIterator& wrapped_iterator,
  439. typename disable_if<
  440. typename is_any_iterator<WrappedIterator>::type
  441. , disabler
  442. >::type* = 0
  443. )
  444. {
  445. typedef typename any_iterator_wrapper_type_generator<
  446. WrappedIterator
  447. , Traversal
  448. , Reference
  449. , Difference
  450. , Buffer
  451. >::type wrapper_type;
  452. void* ptr = m_buffer.allocate(sizeof(wrapper_type));
  453. m_impl = new(ptr) wrapper_type(wrapped_iterator);
  454. }
  455. ~any_iterator()
  456. {
  457. // manually run the destructor, the deallocation is automatically
  458. // handled by the any_iterator_small_buffer base class.
  459. if (m_impl)
  460. m_impl->~abstract_base_type();
  461. }
  462. private:
  463. friend class ::boost::iterator_core_access;
  464. Reference dereference() const
  465. {
  466. BOOST_ASSERT( m_impl );
  467. return m_impl->dereference();
  468. }
  469. bool equal(const any_iterator& other) const
  470. {
  471. return (m_impl == other.m_impl)
  472. || (m_impl && other.m_impl && m_impl->equal(*other.m_impl));
  473. }
  474. void increment()
  475. {
  476. BOOST_ASSERT( m_impl );
  477. m_impl->increment();
  478. }
  479. void decrement()
  480. {
  481. BOOST_ASSERT( m_impl );
  482. m_impl->decrement();
  483. }
  484. Difference distance_to(const any_iterator& other) const
  485. {
  486. return m_impl && other.m_impl
  487. ? m_impl->distance_to(*other.m_impl)
  488. : 0;
  489. }
  490. void advance(Difference offset)
  491. {
  492. BOOST_ASSERT( m_impl );
  493. m_impl->advance(offset);
  494. }
  495. any_iterator& swap(any_iterator& other)
  496. {
  497. BOOST_ASSERT( this != &other );
  498. // grab a temporary copy of the other iterator
  499. any_iterator tmp(other);
  500. // deallocate the other iterator, taking care to obey the
  501. // class-invariants in-case of exceptions later
  502. if (other.m_impl)
  503. {
  504. other.m_impl->~abstract_base_type();
  505. other.m_buffer.deallocate();
  506. other.m_impl = 0;
  507. }
  508. // If this is a non-null iterator then we need to put
  509. // a clone of this iterators implementation into the other
  510. // iterator.
  511. // We can't just swap because of the small buffer optimization.
  512. if (m_impl)
  513. {
  514. other.m_impl = m_impl->clone(other.m_buffer);
  515. m_impl->~abstract_base_type();
  516. m_buffer.deallocate();
  517. m_impl = 0;
  518. }
  519. // assign to this instance a clone of the temporarily held
  520. // tmp which represents the input other parameter at the
  521. // start of execution of this function.
  522. if (tmp.m_impl)
  523. m_impl = tmp.m_impl->clone(m_buffer);
  524. return *this;
  525. }
  526. buffer_type m_buffer;
  527. abstract_base_type* m_impl;
  528. };
  529. } // namespace range_detail
  530. } // namespace boost
  531. #endif // include guard