iterator_facade.hpp 34 KB

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