iterator_facade.hpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. // (C) Copyright David Abrahams 2002.
  2. // (C) Copyright Jeremy Siek 2002.
  3. // (C) Copyright Thomas Witt 2002.
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
  8. #define BOOST_ITERATOR_FACADE_23022003THW_HPP
  9. #include <cstddef>
  10. #include <memory>
  11. #include <utility>
  12. #include <type_traits>
  13. #include <boost/config.hpp>
  14. #include <boost/mp11/utility.hpp>
  15. #include <boost/iterator/interoperable.hpp>
  16. #include <boost/iterator/iterator_traits.hpp>
  17. #include <boost/iterator/iterator_categories.hpp>
  18. #include <boost/iterator/detail/facade_iterator_category.hpp>
  19. #include <boost/iterator/detail/type_traits/conjunction.hpp>
  20. #include <boost/iterator/detail/type_traits/negation.hpp>
  21. namespace boost {
  22. namespace iterators {
  23. // This forward declaration is required for the friend declaration
  24. // in iterator_core_access
  25. template<
  26. typename Derived,
  27. typename Value,
  28. typename CategoryOrTraversal,
  29. typename Reference = Value&,
  30. typename Difference = std::ptrdiff_t
  31. >
  32. class iterator_facade;
  33. namespace detail {
  34. // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
  35. template< typename CategoryOrTraversal, typename Required >
  36. struct is_traversal_at_least :
  37. public std::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
  38. {};
  39. //
  40. // enable if for use in operator implementation.
  41. //
  42. template<
  43. typename Facade1,
  44. typename Facade2,
  45. typename Return
  46. >
  47. struct enable_if_interoperable :
  48. public std::enable_if<
  49. is_interoperable< Facade1, Facade2 >::value,
  50. Return
  51. >
  52. {};
  53. //
  54. // enable if for use in implementation of operators specific for random access traversal.
  55. //
  56. template<
  57. typename Facade1,
  58. typename Facade2,
  59. typename Return
  60. >
  61. struct enable_if_interoperable_and_random_access_traversal :
  62. public std::enable_if<
  63. detail::conjunction<
  64. is_interoperable< Facade1, Facade2 >,
  65. is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >,
  66. is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
  67. >::value,
  68. Return
  69. >
  70. {};
  71. //
  72. // Generates associated types for an iterator_facade with the
  73. // given parameters.
  74. //
  75. template<
  76. typename ValueParam,
  77. typename CategoryOrTraversal,
  78. typename Reference,
  79. typename Difference
  80. >
  81. struct iterator_facade_types
  82. {
  83. using iterator_category = typename facade_iterator_category<
  84. CategoryOrTraversal, ValueParam, Reference
  85. >::type;
  86. using value_type = typename std::remove_const< ValueParam >::type;
  87. // Not the real associated pointer type
  88. using pointer = typename std::add_pointer<
  89. typename std::conditional<
  90. boost::iterators::detail::iterator_writability_disabled< ValueParam, Reference >::value,
  91. const value_type,
  92. value_type
  93. >::type
  94. >::type;
  95. };
  96. // iterators whose dereference operators reference the same value
  97. // for all iterators into the same sequence (like many input
  98. // iterators) need help with their postfix ++: the referenced
  99. // value must be read and stored away before the increment occurs
  100. // so that *a++ yields the originally referenced element and not
  101. // the next one.
  102. template< typename Iterator >
  103. class postfix_increment_proxy
  104. {
  105. using value_type = typename iterator_value< Iterator >::type;
  106. public:
  107. explicit postfix_increment_proxy(Iterator const& x) :
  108. stored_iterator(x),
  109. stored_value(*x)
  110. {}
  111. // Returning a mutable reference allows nonsense like
  112. // (*r++).mutate(), but it imposes fewer assumptions about the
  113. // behavior of the value_type. In particular, recall that
  114. // (*r).mutate() is legal if operator* returns by value.
  115. // Provides readability of *r++
  116. value_type& operator*() const
  117. {
  118. return stored_value;
  119. }
  120. // Provides X(r++)
  121. operator Iterator const&() const
  122. {
  123. return stored_iterator;
  124. }
  125. // Provides (r++)->foo()
  126. value_type* operator->() const
  127. {
  128. return std::addressof(stored_value);
  129. }
  130. private:
  131. Iterator stored_iterator;
  132. mutable value_type stored_value;
  133. };
  134. template< typename Iterator >
  135. class writable_postfix_increment_dereference_proxy;
  136. template< typename T >
  137. struct is_not_writable_postfix_increment_dereference_proxy :
  138. public std::true_type
  139. {};
  140. template< typename Iterator >
  141. struct is_not_writable_postfix_increment_dereference_proxy<
  142. writable_postfix_increment_dereference_proxy< Iterator >
  143. > :
  144. public std::false_type
  145. {};
  146. template< typename Iterator >
  147. class writable_postfix_increment_proxy;
  148. //
  149. // In general, we can't determine that such an iterator isn't
  150. // writable -- we also need to store a copy of the old iterator so
  151. // that it can be written into.
  152. template< typename Iterator >
  153. class writable_postfix_increment_dereference_proxy
  154. {
  155. friend class writable_postfix_increment_proxy< Iterator >;
  156. using value_type = typename iterator_value< Iterator >::type;
  157. public:
  158. explicit writable_postfix_increment_dereference_proxy(Iterator const& x) :
  159. stored_iterator(x),
  160. stored_value(*x)
  161. {}
  162. // Provides readability of *r++
  163. operator value_type&() const
  164. {
  165. return this->stored_value;
  166. }
  167. template< typename OtherIterator >
  168. writable_postfix_increment_dereference_proxy const&
  169. operator=(writable_postfix_increment_dereference_proxy< OtherIterator > const& x) const
  170. {
  171. typedef typename iterator_value< OtherIterator >::type other_value_type;
  172. *this->stored_iterator = static_cast< other_value_type& >(x);
  173. return *this;
  174. }
  175. // Provides writability of *r++
  176. template< typename T >
  177. typename std::enable_if<
  178. is_not_writable_postfix_increment_dereference_proxy< T >::value,
  179. writable_postfix_increment_dereference_proxy const&
  180. >::type operator=(T&& x) const
  181. {
  182. *this->stored_iterator = static_cast< T&& >(x);
  183. return *this;
  184. }
  185. private:
  186. Iterator stored_iterator;
  187. mutable value_type stored_value;
  188. };
  189. template< typename Iterator >
  190. class writable_postfix_increment_proxy
  191. {
  192. using value_type = typename iterator_value< Iterator >::type;
  193. public:
  194. explicit writable_postfix_increment_proxy(Iterator const& x) :
  195. dereference_proxy(x)
  196. {}
  197. writable_postfix_increment_dereference_proxy< Iterator > const&
  198. operator*() const
  199. {
  200. return dereference_proxy;
  201. }
  202. // Provides X(r++)
  203. operator Iterator const&() const
  204. {
  205. return dereference_proxy.stored_iterator;
  206. }
  207. // Provides (r++)->foo()
  208. value_type* operator->() const
  209. {
  210. return std::addressof(dereference_proxy.stored_value);
  211. }
  212. private:
  213. writable_postfix_increment_dereference_proxy< Iterator > dereference_proxy;
  214. };
  215. template< typename Reference, typename Value >
  216. struct is_non_proxy_reference :
  217. public std::is_convertible<
  218. typename std::remove_reference< Reference >::type const volatile*,
  219. Value const volatile*
  220. >
  221. {};
  222. // A metafunction to choose the result type of postfix ++
  223. //
  224. // Because the C++98 input iterator requirements say that *r++ has
  225. // type T (value_type), implementations of some standard
  226. // algorithms like lexicographical_compare may use constructions
  227. // like:
  228. //
  229. // *r++ < *s++
  230. //
  231. // If *r++ returns a proxy (as required if r is writable but not
  232. // multipass), this sort of expression will fail unless the proxy
  233. // supports the operator<. Since there are any number of such
  234. // operations, we're not going to try to support them. Therefore,
  235. // even if r++ returns a proxy, *r++ will only return a proxy if
  236. // *r also returns a proxy.
  237. template< typename Iterator, typename Value, typename Reference, typename CategoryOrTraversal >
  238. struct postfix_increment_result
  239. {
  240. using type = mp11::mp_eval_if_not<
  241. detail::conjunction<
  242. // A proxy is only needed for readable iterators
  243. std::is_convertible<
  244. Reference,
  245. // Use add_lvalue_reference to form `reference to Value` due to
  246. // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
  247. // 'reference-to-reference' in the template which described in CWG
  248. // DR106.
  249. // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
  250. typename std::add_lvalue_reference< Value const >::type
  251. >,
  252. // No multipass iterator can have values that disappear
  253. // before positions can be re-visited
  254. detail::negation<
  255. detail::is_traversal_at_least< CategoryOrTraversal, forward_traversal_tag >
  256. >
  257. >,
  258. Iterator,
  259. mp11::mp_if,
  260. is_non_proxy_reference< Reference, Value >,
  261. postfix_increment_proxy< Iterator >,
  262. writable_postfix_increment_proxy< Iterator >
  263. >;
  264. };
  265. // operator->() needs special support for input iterators to strictly meet the
  266. // standard's requirements. If *i is not a reference type, we must still
  267. // produce an lvalue to which a pointer can be formed. We do that by
  268. // returning a proxy object containing an instance of the reference object.
  269. template< typename Reference, typename Pointer >
  270. struct operator_arrow_dispatch // proxy references
  271. {
  272. struct proxy
  273. {
  274. explicit proxy(Reference const& x) : m_ref(x) {}
  275. Reference* operator->() { return std::addressof(m_ref); }
  276. // This function is needed for MWCW and BCC, which won't call
  277. // operator-> again automatically per 13.3.1.2 para 8
  278. operator Reference*() { return std::addressof(m_ref); }
  279. Reference m_ref;
  280. };
  281. using result_type = proxy;
  282. static result_type apply(Reference const& x)
  283. {
  284. return result_type(x);
  285. }
  286. };
  287. template< typename T, typename Pointer >
  288. struct operator_arrow_dispatch< T&, Pointer > // "real" references
  289. {
  290. using result_type = Pointer;
  291. static result_type apply(T& x)
  292. {
  293. return std::addressof(x);
  294. }
  295. };
  296. // A proxy return type for operator[], needed to deal with
  297. // iterators that may invalidate referents upon destruction.
  298. // Consider the temporary iterator in *(a + n)
  299. template< typename Iterator >
  300. class operator_brackets_proxy
  301. {
  302. // Iterator is actually an iterator_facade, so we do not have to
  303. // go through iterator_traits to access the traits.
  304. using reference = typename Iterator::reference;
  305. public:
  306. explicit operator_brackets_proxy(Iterator const& iter) noexcept(std::is_nothrow_copy_constructible< Iterator >::value) :
  307. m_iter(iter)
  308. {}
  309. operator reference() const noexcept(noexcept(*std::declval< Iterator const& >()))
  310. {
  311. return *m_iter;
  312. }
  313. template< typename T >
  314. typename std::enable_if<
  315. detail::conjunction<
  316. detail::negation<
  317. std::is_same<
  318. operator_brackets_proxy< Iterator >,
  319. typename std::remove_cv< typename std::remove_reference< T >::type >::type
  320. >
  321. >,
  322. std::is_assignable< reference, T&& >
  323. >::value,
  324. operator_brackets_proxy&
  325. >::type operator= (T&& val) noexcept(noexcept(*std::declval< Iterator& >() = std::declval< T&& >()))
  326. {
  327. *m_iter = static_cast< T&& >(val);
  328. return *this;
  329. }
  330. // Provides it[n]->foo(). Leverages chaining of operator->.
  331. reference operator->() const noexcept(noexcept(*std::declval< Iterator const& >()))
  332. {
  333. return *m_iter;
  334. }
  335. // Provides (*it[n]).foo()
  336. template< typename Ref = reference, typename Result = decltype(*std::declval< Ref >()) >
  337. Result operator*() const noexcept(noexcept(**std::declval< Iterator const& >()))
  338. {
  339. return **m_iter;
  340. }
  341. private:
  342. Iterator m_iter;
  343. };
  344. // A binary metafunction class that always returns bool.
  345. template< typename Iterator1, typename Iterator2 >
  346. using always_bool_t = bool;
  347. template< typename Iterator1, typename Iterator2 >
  348. using choose_difference_type_t = typename std::conditional<
  349. std::is_convertible< Iterator2, Iterator1 >::value,
  350. iterator_difference< Iterator1 >,
  351. iterator_difference< Iterator2 >
  352. >::type::type;
  353. template<
  354. typename Derived,
  355. typename Value,
  356. typename CategoryOrTraversal,
  357. typename Reference,
  358. typename Difference,
  359. bool IsBidirectionalTraversal,
  360. bool IsRandomAccessTraversal
  361. >
  362. class iterator_facade_base;
  363. } // namespace detail
  364. // Macros which describe the declarations of binary operators
  365. #define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
  366. template< \
  367. typename Derived1, typename V1, typename TC1, typename Reference1, typename Difference1, \
  368. typename Derived2, typename V2, typename TC2, typename Reference2, typename Difference2 \
  369. > \
  370. prefix typename enabler< \
  371. Derived1, Derived2, \
  372. result_type< Derived1, Derived2 > \
  373. >::type \
  374. operator op( \
  375. iterator_facade< Derived1, V1, TC1, Reference1, Difference1 > const& lhs, \
  376. iterator_facade< Derived2, V2, TC2, Reference2, Difference2 > const& rhs)
  377. #define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
  378. BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
  379. #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type) \
  380. BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
  381. #define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
  382. template< typename Derived, typename V, typename TC, typename R, typename D > \
  383. prefix typename std::enable_if< \
  384. boost::iterators::detail::is_traversal_at_least< \
  385. TC, \
  386. boost::iterators::random_access_traversal_tag \
  387. >::value, \
  388. Derived \
  389. >::type operator+ args
  390. //
  391. // Helper class for granting access to the iterator core interface.
  392. //
  393. // The simple core interface is used by iterator_facade. The core
  394. // interface of a user/library defined iterator type should not be made public
  395. // so that it does not clutter the public interface. Instead iterator_core_access
  396. // should be made friend so that iterator_facade can access the core
  397. // interface through iterator_core_access.
  398. //
  399. class iterator_core_access
  400. {
  401. template< typename I, typename V, typename TC, typename R, typename D >
  402. friend class iterator_facade;
  403. template< typename I, typename V, typename TC, typename R, typename D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal >
  404. friend class detail::iterator_facade_base;
  405. #define BOOST_ITERATOR_FACADE_RELATION(op) \
  406. BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend, op, boost::iterators::detail::always_bool_t);
  407. BOOST_ITERATOR_FACADE_RELATION(==)
  408. BOOST_ITERATOR_FACADE_RELATION(!=)
  409. #undef BOOST_ITERATOR_FACADE_RELATION
  410. #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \
  411. BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, op, boost::iterators::detail::always_bool_t);
  412. BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
  413. BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
  414. BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
  415. BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
  416. #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
  417. BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, -, boost::iterators::detail::choose_difference_type_t);
  418. BOOST_ITERATOR_FACADE_PLUS_HEAD(
  419. friend inline,
  420. (iterator_facade< Derived, V, TC, R, D > const&, typename Derived::difference_type)
  421. );
  422. BOOST_ITERATOR_FACADE_PLUS_HEAD(
  423. friend inline,
  424. (typename Derived::difference_type, iterator_facade< Derived, V, TC, R, D > const&)
  425. );
  426. template< typename Facade >
  427. static typename Facade::reference dereference(Facade const& f)
  428. {
  429. return f.dereference();
  430. }
  431. template< typename Facade >
  432. static void increment(Facade& f)
  433. {
  434. f.increment();
  435. }
  436. template< typename Facade >
  437. static void decrement(Facade& f)
  438. {
  439. f.decrement();
  440. }
  441. template< typename Facade1, typename Facade2 >
  442. static bool equal(Facade1 const& f1, Facade2 const& f2, std::true_type)
  443. {
  444. return f1.equal(f2);
  445. }
  446. template< typename Facade1, typename Facade2 >
  447. static bool equal(Facade1 const& f1, Facade2 const& f2, std::false_type)
  448. {
  449. return f2.equal(f1);
  450. }
  451. template< typename Facade >
  452. static void advance(Facade& f, typename Facade::difference_type n)
  453. {
  454. f.advance(n);
  455. }
  456. template< typename Facade1, typename Facade2 >
  457. static typename Facade1::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::true_type)
  458. {
  459. return -f1.distance_to(f2);
  460. }
  461. template< typename Facade1, typename Facade2 >
  462. static typename Facade2::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::false_type)
  463. {
  464. return f2.distance_to(f1);
  465. }
  466. //
  467. // Curiously Recurring Template interface.
  468. //
  469. template< typename I, typename V, typename TC, typename R, typename D >
  470. static I& derived(iterator_facade< I, V, TC, R, D >& facade)
  471. {
  472. return *static_cast< I* >(&facade);
  473. }
  474. template< typename I, typename V, typename TC, typename R, typename D >
  475. static I const& derived(iterator_facade< I, V, TC, R, D > const& facade)
  476. {
  477. return *static_cast< I const* >(&facade);
  478. }
  479. // objects of this class are useless
  480. iterator_core_access() = delete;
  481. };
  482. namespace detail {
  483. // Implementation for forward traversal iterators
  484. template<
  485. typename Derived,
  486. typename Value,
  487. typename CategoryOrTraversal,
  488. typename Reference,
  489. typename Difference
  490. >
  491. class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
  492. {
  493. private:
  494. using associated_types = boost::iterators::detail::iterator_facade_types<
  495. Value, CategoryOrTraversal, Reference, Difference
  496. >;
  497. using operator_arrow_dispatch_ = boost::iterators::detail::operator_arrow_dispatch<
  498. Reference,
  499. typename associated_types::pointer
  500. >;
  501. public:
  502. using value_type = typename associated_types::value_type;
  503. using reference = Reference;
  504. using difference_type = Difference;
  505. using pointer = typename operator_arrow_dispatch_::result_type;
  506. using iterator_category = typename associated_types::iterator_category;
  507. public:
  508. reference operator*() const
  509. {
  510. return iterator_core_access::dereference(this->derived());
  511. }
  512. pointer operator->() const
  513. {
  514. return operator_arrow_dispatch_::apply(*this->derived());
  515. }
  516. Derived& operator++()
  517. {
  518. iterator_core_access::increment(this->derived());
  519. return this->derived();
  520. }
  521. protected:
  522. //
  523. // Curiously Recurring Template interface.
  524. //
  525. Derived& derived()
  526. {
  527. return *static_cast< Derived* >(this);
  528. }
  529. Derived const& derived() const
  530. {
  531. return *static_cast< Derived const* >(this);
  532. }
  533. };
  534. // Implementation for bidirectional traversal iterators
  535. template<
  536. typename Derived,
  537. typename Value,
  538. typename CategoryOrTraversal,
  539. typename Reference,
  540. typename Difference
  541. >
  542. class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
  543. public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
  544. {
  545. public:
  546. Derived& operator--()
  547. {
  548. iterator_core_access::decrement(this->derived());
  549. return this->derived();
  550. }
  551. Derived operator--(int)
  552. {
  553. Derived tmp(this->derived());
  554. --*this;
  555. return tmp;
  556. }
  557. };
  558. // Implementation for random access traversal iterators
  559. template<
  560. typename Derived,
  561. typename Value,
  562. typename CategoryOrTraversal,
  563. typename Reference,
  564. typename Difference
  565. >
  566. class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
  567. public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
  568. {
  569. private:
  570. using base_type = iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >;
  571. public:
  572. using reference = typename base_type::reference;
  573. using difference_type = typename base_type::difference_type;
  574. public:
  575. operator_brackets_proxy< Derived > operator[](difference_type n) const
  576. {
  577. return operator_brackets_proxy< Derived >(this->derived() + n);
  578. }
  579. Derived& operator+=(difference_type n)
  580. {
  581. iterator_core_access::advance(this->derived(), n);
  582. return this->derived();
  583. }
  584. Derived& operator-=(difference_type n)
  585. {
  586. iterator_core_access::advance(this->derived(), -n);
  587. return this->derived();
  588. }
  589. Derived operator-(difference_type x) const
  590. {
  591. Derived result(this->derived());
  592. return result -= x;
  593. }
  594. };
  595. } // namespace detail
  596. //
  597. // iterator_facade - use as a public base class for defining new
  598. // standard-conforming iterators.
  599. //
  600. template<
  601. typename Derived, // The derived iterator type being constructed
  602. typename Value,
  603. typename CategoryOrTraversal,
  604. typename Reference,
  605. typename Difference
  606. >
  607. class iterator_facade :
  608. public detail::iterator_facade_base<
  609. Derived,
  610. Value,
  611. CategoryOrTraversal,
  612. Reference,
  613. Difference,
  614. detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
  615. detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
  616. >
  617. {
  618. protected:
  619. // For use by derived classes
  620. using iterator_facade_ = iterator_facade< Derived, Value, CategoryOrTraversal, Reference, Difference >;
  621. };
  622. template< typename I, typename V, typename TC, typename R, typename D >
  623. inline typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
  624. operator++(iterator_facade< I, V, TC, R, D >& i, int)
  625. {
  626. typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
  627. tmp(*static_cast< I* >(&i));
  628. ++i;
  629. return tmp;
  630. }
  631. //
  632. // Comparison operator implementation. The library supplied operators
  633. // enables the user to provide fully interoperable constant/mutable
  634. // iterator types. I.e. the library provides all operators
  635. // for all mutable/constant iterator combinations.
  636. //
  637. // Note though that this kind of interoperability for constant/mutable
  638. // iterators is not required by the standard for container iterators.
  639. // All the standard asks for is a conversion mutable -> constant.
  640. // Most standard library implementations nowadays provide fully interoperable
  641. // iterator implementations, but there are still heavily used implementations
  642. // that do not provide them. (Actually it's even worse, they do not provide
  643. // them for only a few iterators.)
  644. //
  645. // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
  646. // enable the user to turn off mixed type operators
  647. //
  648. // The library takes care to provide only the right operator overloads.
  649. // I.e.
  650. //
  651. // bool operator==(Iterator, Iterator);
  652. // bool operator==(ConstIterator, Iterator);
  653. // bool operator==(Iterator, ConstIterator);
  654. // bool operator==(ConstIterator, ConstIterator);
  655. //
  656. // ...
  657. //
  658. // In order to do so it uses c++ idioms that are not yet widely supported
  659. // by current compiler releases. The library is designed to degrade gracefully
  660. // in the face of compiler deficiencies. In general compiler
  661. // deficiencies result in less strict error checking and more obscure
  662. // error messages, functionality is not affected.
  663. //
  664. // For full operation compiler support for "Substitution Failure Is Not An Error"
  665. // (aka. enable_if) and boost::is_convertible is required.
  666. //
  667. // The following problems occur if support is lacking.
  668. //
  669. // Pseudo code
  670. //
  671. // ---------------
  672. // AdaptorA<Iterator1> a1;
  673. // AdaptorA<Iterator2> a2;
  674. //
  675. // // This will result in a no such overload error in full operation
  676. // // If enable_if or is_convertible is not supported
  677. // // The instantiation will fail with an error hopefully indicating that
  678. // // there is no operator== for Iterator1, Iterator2
  679. // // The same will happen if no enable_if is used to remove
  680. // // false overloads from the templated conversion constructor
  681. // // of AdaptorA.
  682. //
  683. // a1 == a2;
  684. // ----------------
  685. //
  686. // AdaptorA<Iterator> a;
  687. // AdaptorB<Iterator> b;
  688. //
  689. // // This will result in a no such overload error in full operation
  690. // // If enable_if is not supported the static assert used
  691. // // in the operator implementation will fail.
  692. // // This will accidently work if is_convertible is not supported.
  693. //
  694. // a == b;
  695. // ----------------
  696. //
  697. #define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
  698. BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
  699. { \
  700. return_prefix iterator_core_access::base_op( \
  701. *static_cast< Derived1 const* >(&lhs), \
  702. *static_cast< Derived2 const* >(&rhs), \
  703. std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
  704. ); \
  705. }
  706. #define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
  707. BOOST_ITERATOR_FACADE_INTEROP( \
  708. op, \
  709. boost::iterators::detail::always_bool_t, \
  710. return_prefix, \
  711. base_op \
  712. )
  713. BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
  714. BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
  715. #undef BOOST_ITERATOR_FACADE_RELATION
  716. #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
  717. BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \
  718. { \
  719. return_prefix iterator_core_access::base_op( \
  720. *static_cast< Derived1 const* >(&lhs), \
  721. *static_cast< Derived2 const* >(&rhs), \
  722. std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
  723. ); \
  724. }
  725. #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
  726. BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \
  727. op, \
  728. boost::iterators::detail::always_bool_t, \
  729. return_prefix, \
  730. base_op \
  731. )
  732. BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
  733. BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
  734. BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
  735. BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
  736. #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
  737. // operator- requires an additional part in the static assertion
  738. BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
  739. -,
  740. boost::iterators::detail::choose_difference_type_t,
  741. return,
  742. distance_from
  743. )
  744. #undef BOOST_ITERATOR_FACADE_INTEROP
  745. #undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
  746. #define BOOST_ITERATOR_FACADE_PLUS(args) \
  747. BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
  748. { \
  749. Derived tmp(static_cast< Derived const& >(i)); \
  750. return tmp += n; \
  751. }
  752. BOOST_ITERATOR_FACADE_PLUS((iterator_facade< Derived, V, TC, R, D > const& i, typename Derived::difference_type n))
  753. BOOST_ITERATOR_FACADE_PLUS((typename Derived::difference_type n, iterator_facade< Derived, V, TC, R, D > const& i))
  754. #undef BOOST_ITERATOR_FACADE_PLUS
  755. #undef BOOST_ITERATOR_FACADE_PLUS_HEAD
  756. #undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
  757. #undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
  758. #undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
  759. } // namespace iterators
  760. using iterators::iterator_core_access;
  761. using iterators::iterator_facade;
  762. } // namespace boost
  763. #endif // BOOST_ITERATOR_FACADE_23022003THW_HPP