iterator_facade.hpp 29 KB

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