iterator_adaptor.hpp 11 KB

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