iterator_facade.hpp 36 KB

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