iterator_adaptor.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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_ADAPTOR_23022003THW_HPP
  8. #define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
  9. #include <boost/static_assert.hpp>
  10. #include <boost/iterator.hpp>
  11. #include <boost/detail/iterator.hpp>
  12. #include <boost/iterator/iterator_categories.hpp>
  13. #include <boost/iterator/iterator_facade.hpp>
  14. #include <boost/iterator/detail/enable_if.hpp>
  15. #include <boost/mpl/and.hpp>
  16. #include <boost/mpl/not.hpp>
  17. #include <boost/mpl/or.hpp>
  18. #include <boost/type_traits/is_same.hpp>
  19. #include <boost/type_traits/is_convertible.hpp>
  20. #ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
  21. # include <boost/type_traits/remove_reference.hpp>
  22. # if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
  23. # include <boost/type_traits/add_reference.hpp>
  24. # endif
  25. #else
  26. # include <boost/type_traits/add_reference.hpp>
  27. #endif
  28. #include <boost/iterator/detail/config_def.hpp>
  29. #include <boost/iterator/iterator_traits.hpp>
  30. namespace boost
  31. {
  32. // Used as a default template argument internally, merely to
  33. // indicate "use the default", this can also be passed by users
  34. // explicitly in order to specify that the default should be used.
  35. struct use_default;
  36. # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  37. // the incompleteness of use_default causes massive problems for
  38. // is_convertible (naturally). This workaround is fortunately not
  39. // needed for vc6/vc7.
  40. template<class To>
  41. struct is_convertible<use_default,To>
  42. : mpl::false_ {};
  43. # endif
  44. namespace detail
  45. {
  46. //
  47. // Result type used in enable_if_convertible meta function.
  48. // This can be an incomplete type, as only pointers to
  49. // enable_if_convertible< ... >::type are used.
  50. // We could have used void for this, but conversion to
  51. // void* is just to easy.
  52. //
  53. struct enable_type;
  54. }
  55. //
  56. // enable_if for use in adapted iterators constructors.
  57. //
  58. // In order to provide interoperability between adapted constant and
  59. // mutable iterators, adapted iterators will usually provide templated
  60. // conversion constructors of the following form
  61. //
  62. // template <class BaseIterator>
  63. // class adapted_iterator :
  64. // public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
  65. // {
  66. // public:
  67. //
  68. // ...
  69. //
  70. // template <class OtherIterator>
  71. // adapted_iterator(
  72. // OtherIterator const& it
  73. // , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
  74. //
  75. // ...
  76. // };
  77. //
  78. // enable_if_convertible is used to remove those overloads from the overload
  79. // set that cannot be instantiated. For all practical purposes only overloads
  80. // for constant/mutable interaction will remain. This has the advantage that
  81. // meta functions like boost::is_convertible do not return false positives,
  82. // as they can only look at the signature of the conversion constructor
  83. // and not at the actual instantiation.
  84. //
  85. // enable_if_interoperable can be safely used in user code. It falls back to
  86. // always enabled for compilers that don't support enable_if or is_convertible.
  87. // There is no need for compiler specific workarounds in user code.
  88. //
  89. // The operators implementation relies on boost::is_convertible not returning
  90. // false positives for user/library defined iterator types. See comments
  91. // on operator implementation for consequences.
  92. //
  93. # if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  94. template<typename From, typename To>
  95. struct enable_if_convertible
  96. {
  97. typedef typename mpl::if_<
  98. mpl::or_<
  99. is_same<From,To>
  100. , is_convertible<From, To>
  101. >
  102. , boost::detail::enable_type
  103. , int&
  104. >::type type;
  105. };
  106. # elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
  107. template <class From, class To>
  108. struct enable_if_convertible
  109. {
  110. typedef boost::detail::enable_type type;
  111. };
  112. # elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
  113. // For some reason vc7.1 needs us to "cut off" instantiation
  114. // of is_convertible in a few cases.
  115. template<typename From, typename To>
  116. struct enable_if_convertible
  117. : iterators::enable_if<
  118. mpl::or_<
  119. is_same<From,To>
  120. , is_convertible<From, To>
  121. >
  122. , boost::detail::enable_type
  123. >
  124. {};
  125. # else
  126. template<typename From, typename To>
  127. struct enable_if_convertible
  128. : iterators::enable_if<
  129. is_convertible<From, To>
  130. , boost::detail::enable_type
  131. >
  132. {};
  133. # endif
  134. //
  135. // Default template argument handling for iterator_adaptor
  136. //
  137. namespace detail
  138. {
  139. // If T is use_default, return the result of invoking
  140. // DefaultNullaryFn, otherwise return T.
  141. template <class T, class DefaultNullaryFn>
  142. struct ia_dflt_help
  143. : mpl::eval_if<
  144. is_same<T, use_default>
  145. , DefaultNullaryFn
  146. , mpl::identity<T>
  147. >
  148. {
  149. };
  150. // A metafunction which computes an iterator_adaptor's base class,
  151. // a specialization of iterator_facade.
  152. template <
  153. class Derived
  154. , class Base
  155. , class Value
  156. , class Traversal
  157. , class Reference
  158. , class Difference
  159. >
  160. struct iterator_adaptor_base
  161. {
  162. typedef iterator_facade<
  163. Derived
  164. # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
  165. , typename boost::detail::ia_dflt_help<
  166. Value
  167. , mpl::eval_if<
  168. is_same<Reference,use_default>
  169. , iterator_value<Base>
  170. , remove_reference<Reference>
  171. >
  172. >::type
  173. # else
  174. , typename boost::detail::ia_dflt_help<
  175. Value, iterator_value<Base>
  176. >::type
  177. # endif
  178. , typename boost::detail::ia_dflt_help<
  179. Traversal
  180. , iterator_traversal<Base>
  181. >::type
  182. , typename boost::detail::ia_dflt_help<
  183. Reference
  184. , mpl::eval_if<
  185. is_same<Value,use_default>
  186. , iterator_reference<Base>
  187. , add_reference<Value>
  188. >
  189. >::type
  190. , typename boost::detail::ia_dflt_help<
  191. Difference, iterator_difference<Base>
  192. >::type
  193. >
  194. type;
  195. };
  196. // workaround for aC++ CR JAGaf33512
  197. template <class Tr1, class Tr2>
  198. inline void iterator_adaptor_assert_traversal ()
  199. {
  200. BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
  201. }
  202. }
  203. //
  204. // Iterator Adaptor
  205. //
  206. // The parameter ordering changed slightly with respect to former
  207. // versions of iterator_adaptor The idea is that when the user needs
  208. // to fiddle with the reference type it is highly likely that the
  209. // iterator category has to be adjusted as well. Any of the
  210. // following four template arguments may be ommitted or explicitly
  211. // replaced by use_default.
  212. //
  213. // Value - if supplied, the value_type of the resulting iterator, unless
  214. // const. If const, a conforming compiler strips constness for the
  215. // value_type. If not supplied, iterator_traits<Base>::value_type is used
  216. //
  217. // Category - the traversal category of the resulting iterator. If not
  218. // supplied, iterator_traversal<Base>::type is used.
  219. //
  220. // Reference - the reference type of the resulting iterator, and in
  221. // particular, the result type of operator*(). If not supplied but
  222. // Value is supplied, Value& is used. Otherwise
  223. // iterator_traits<Base>::reference is used.
  224. //
  225. // Difference - the difference_type of the resulting iterator. If not
  226. // supplied, iterator_traits<Base>::difference_type is used.
  227. //
  228. template <
  229. class Derived
  230. , class Base
  231. , class Value = use_default
  232. , class Traversal = use_default
  233. , class Reference = use_default
  234. , class Difference = use_default
  235. >
  236. class iterator_adaptor
  237. : public boost::detail::iterator_adaptor_base<
  238. Derived, Base, Value, Traversal, Reference, Difference
  239. >::type
  240. {
  241. friend class iterator_core_access;
  242. protected:
  243. typedef typename boost::detail::iterator_adaptor_base<
  244. Derived, Base, Value, Traversal, Reference, Difference
  245. >::type super_t;
  246. public:
  247. iterator_adaptor() {}
  248. explicit iterator_adaptor(Base const &iter)
  249. : m_iterator(iter)
  250. {
  251. }
  252. typedef Base base_type;
  253. Base const& base() const
  254. { return m_iterator; }
  255. protected:
  256. // for convenience in derived classes
  257. typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
  258. //
  259. // lvalue access to the Base object for Derived
  260. //
  261. Base const& base_reference() const
  262. { return m_iterator; }
  263. Base& base_reference()
  264. { return m_iterator; }
  265. private:
  266. //
  267. // Core iterator interface for iterator_facade. This is private
  268. // to prevent temptation for Derived classes to use it, which
  269. // will often result in an error. Derived classes should use
  270. // base_reference(), above, to get direct access to m_iterator.
  271. //
  272. typename super_t::reference dereference() const
  273. { return *m_iterator; }
  274. template <
  275. class OtherDerived, class OtherIterator, class V, class C, class R, class D
  276. >
  277. bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
  278. {
  279. // Maybe readd with same_distance
  280. // BOOST_STATIC_ASSERT(
  281. // (detail::same_category_and_difference<Derived,OtherDerived>::value)
  282. // );
  283. return m_iterator == x.base();
  284. }
  285. typedef typename iterator_category_to_traversal<
  286. typename super_t::iterator_category
  287. >::type my_traversal;
  288. # define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
  289. boost::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
  290. void advance(typename super_t::difference_type n)
  291. {
  292. BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
  293. m_iterator += n;
  294. }
  295. void increment() { ++m_iterator; }
  296. void decrement()
  297. {
  298. BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
  299. --m_iterator;
  300. }
  301. template <
  302. class OtherDerived, class OtherIterator, class V, class C, class R, class D
  303. >
  304. typename super_t::difference_type distance_to(
  305. iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
  306. {
  307. BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
  308. // Maybe readd with same_distance
  309. // BOOST_STATIC_ASSERT(
  310. // (detail::same_category_and_difference<Derived,OtherDerived>::value)
  311. // );
  312. return y.base() - m_iterator;
  313. }
  314. # undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
  315. private: // data members
  316. Base m_iterator;
  317. };
  318. } // namespace boost
  319. #include <boost/iterator/detail/config_undef.hpp>
  320. #endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP