iterator_facade.hpp 28 KB

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