iterator.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Boost.TypeErasure library
  2. //
  3. // Copyright 2011 Steven Watanabe
  4. //
  5. // Distributed under the Boost Software License Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // $Id$
  10. #ifndef BOOST_TYPE_ERASURE_ITERATOR_HPP_INCLUDED
  11. #define BOOST_TYPE_ERASURE_ITERATOR_HPP_INCLUDED
  12. #include <iterator>
  13. #include <boost/mpl/vector.hpp>
  14. #include <boost/mpl/if.hpp>
  15. #include <boost/iterator/iterator_adaptor.hpp>
  16. #include <boost/iterator/iterator_categories.hpp>
  17. #include <boost/type_traits/remove_const.hpp>
  18. #include <boost/type_traits/remove_reference.hpp>
  19. #include <boost/type_erasure/operators.hpp>
  20. #include <boost/type_erasure/builtin.hpp>
  21. #include <boost/type_erasure/deduced.hpp>
  22. #include <boost/type_erasure/is_placeholder.hpp>
  23. namespace boost {
  24. namespace type_erasure {
  25. /** INTERNAL ONLY */
  26. template<>
  27. struct is_placeholder< ::boost::use_default> : ::boost::mpl::false_ {};
  28. namespace detail {
  29. template<class T>
  30. struct iterator_value_type_impl
  31. {
  32. typedef typename ::std::iterator_traits<T>::value_type type;
  33. };
  34. }
  35. /** INTERNAL ONLY */
  36. template<class T>
  37. struct iterator_value_type
  38. {
  39. typedef typename ::boost::mpl::eval_if<
  40. ::boost::type_erasure::is_placeholder<T>,
  41. ::boost::mpl::identity<void>,
  42. ::boost::type_erasure::detail::iterator_value_type_impl<T>
  43. >::type type;
  44. };
  45. template<
  46. class Traversal,
  47. class T = _self,
  48. class Reference = ::boost::use_default,
  49. class DifferenceType = ::std::ptrdiff_t,
  50. class ValueType = typename deduced<iterator_value_type<T> >::type
  51. >
  52. struct iterator;
  53. #ifdef BOOST_TYPE_ERASURE_DOXYGEN
  54. /**
  55. * The @ref iterator concept can be used for any iterator category.
  56. *
  57. * \tparam Traversal must be one of @c boost::incrementable_traversal_tag,
  58. * @c boost::single_pass_traversal_tag, @c boost::forward_traversal_tag,
  59. * @c boost::bidirectional_traversal_tag, and @c boost::random_access_traversal_tag.
  60. * \tparam T The placeholder representing the iterator.
  61. * \tparam Reference The reference type. If it is boost::use_default, then
  62. * reference will be value_type&.
  63. * \tparam DifferenceType The iterator's difference type.
  64. *
  65. * The value_type of the iterator is deduced. To force it to be
  66. * a specific type, use the @ref same_type concept.
  67. *
  68. * Example:
  69. *
  70. * \code
  71. * mpl::vector<
  72. * iterator<boost::forward_traversal_tag>,
  73. * same_type<iterator<boost::forward_traversal_tag>::value_type, int> > int_it;
  74. * \endcode
  75. */
  76. template<
  77. class Traversal,
  78. class T = _self,
  79. class Reference = boost::use_default,
  80. class DifferenceType = std::ptrdiff_t
  81. >
  82. struct iterator
  83. {
  84. typedef detail::unspecified value_type;
  85. typedef Reference reference;
  86. typedef DifferenceType difference_type;
  87. };
  88. template<
  89. class T = _self,
  90. class Reference = boost::use_default,
  91. class DifferenceType = std::ptrdiff_t
  92. >
  93. struct forward_iterator :
  94. iterator<boost::forward_traversal_tag, T, Reference, DifferenceType>
  95. {};
  96. template<
  97. class T = _self,
  98. class Reference = boost::use_default,
  99. class DifferenceType = std::ptrdiff_t
  100. >
  101. struct bidirectional_iterator :
  102. iterator<boost::bidirectional_traversal_tag, T, Reference, DifferenceType>
  103. {};
  104. template<
  105. class T = _self,
  106. class Reference = boost::use_default,
  107. class DifferenceType = std::ptrdiff_t
  108. >
  109. struct random_access_iterator :
  110. iterator<boost::random_access_traversal_tag, T, Reference, DifferenceType>
  111. {
  112. };
  113. #else
  114. /** INTERNAL ONLY */
  115. template<class Reference, class ValueType>
  116. struct iterator_reference
  117. {
  118. typedef Reference type;
  119. };
  120. /** INTERNAL ONLY */
  121. template<class ValueType>
  122. struct iterator_reference< ::boost::use_default, ValueType>
  123. {
  124. typedef ValueType& type;
  125. };
  126. template<class T, class Reference, class DifferenceType, class ValueType>
  127. struct iterator< ::boost::no_traversal_tag, T, Reference, DifferenceType, ValueType> :
  128. boost::mpl::vector<
  129. copy_constructible<T>,
  130. constructible<T()>,
  131. equality_comparable<T>,
  132. dereferenceable<typename iterator_reference<Reference, ValueType>::type, T>,
  133. assignable<T>
  134. >
  135. {
  136. typedef ValueType value_type;
  137. typedef typename iterator_reference<Reference, ValueType>::type reference;
  138. typedef DifferenceType difference_type;
  139. };
  140. template<class T, class Reference, class DifferenceType, class ValueType>
  141. struct iterator< ::boost::incrementable_traversal_tag, T, Reference, DifferenceType, ValueType> :
  142. boost::mpl::vector<
  143. iterator< ::boost::no_traversal_tag, T, Reference, DifferenceType>,
  144. incrementable<T>
  145. >
  146. {
  147. typedef ValueType value_type;
  148. typedef typename iterator_reference<Reference, ValueType>::type reference;
  149. typedef DifferenceType difference_type;
  150. };
  151. template<class T, class Reference, class DifferenceType, class ValueType>
  152. struct iterator< ::boost::single_pass_traversal_tag, T, Reference, DifferenceType, ValueType> :
  153. iterator< ::boost::incrementable_traversal_tag, T, Reference, DifferenceType, ValueType>
  154. {};
  155. template<class T, class Reference, class DifferenceType, class ValueType>
  156. struct iterator< ::boost::forward_traversal_tag, T, Reference, DifferenceType, ValueType> :
  157. iterator< ::boost::incrementable_traversal_tag, T, Reference, DifferenceType, ValueType>
  158. {};
  159. template<class T, class Reference, class DifferenceType, class ValueType>
  160. struct iterator< ::boost::bidirectional_traversal_tag, T, Reference, DifferenceType, ValueType> :
  161. boost::mpl::vector<
  162. iterator< ::boost::incrementable_traversal_tag, T, Reference, DifferenceType, ValueType>,
  163. decrementable<T>
  164. >
  165. {
  166. typedef ValueType value_type;
  167. typedef typename iterator_reference<Reference, ValueType>::type reference;
  168. typedef DifferenceType difference_type;
  169. };
  170. template<class T, class Reference, class DifferenceType, class ValueType>
  171. struct iterator< ::boost::random_access_traversal_tag, T, Reference, DifferenceType, ValueType> :
  172. boost::mpl::vector<
  173. iterator< ::boost::bidirectional_traversal_tag, T, Reference, DifferenceType, ValueType>,
  174. addable<T, DifferenceType, T>,
  175. addable<DifferenceType, T, T>,
  176. subtractable<T, DifferenceType, T>,
  177. subtractable<T, T, DifferenceType>,
  178. subscriptable<typename iterator_reference<Reference, ValueType>::type, T, DifferenceType>
  179. >
  180. {
  181. typedef ValueType value_type;
  182. typedef typename iterator_reference<Reference, ValueType>::type reference;
  183. typedef DifferenceType difference_type;
  184. };
  185. template<
  186. class T = _self,
  187. class Reference = ::boost::use_default,
  188. class DifferenceType = ::std::ptrdiff_t,
  189. class ValueType = typename deduced<iterator_value_type<T> >::type
  190. >
  191. struct forward_iterator :
  192. iterator< ::boost::forward_traversal_tag, T, Reference, DifferenceType, ValueType>
  193. {};
  194. template<
  195. class T = _self,
  196. class Reference = ::boost::use_default,
  197. class DifferenceType = ::std::ptrdiff_t,
  198. class ValueType = typename deduced<iterator_value_type<T> >::type
  199. >
  200. struct bidirectional_iterator :
  201. iterator< ::boost::bidirectional_traversal_tag, T, Reference, DifferenceType, ValueType>
  202. {};
  203. template<
  204. class T = _self,
  205. class Reference = ::boost::use_default,
  206. class DifferenceType = ::std::ptrdiff_t,
  207. class ValueType = typename deduced<iterator_value_type<T> >::type
  208. >
  209. struct random_access_iterator :
  210. iterator< ::boost::random_access_traversal_tag, T, Reference, DifferenceType, ValueType>
  211. {
  212. };
  213. #endif
  214. /// \cond show_operators
  215. template<class T, class Reference, class DifferenceType, class ValueType, class Base>
  216. struct concept_interface<iterator< ::boost::no_traversal_tag, T, Reference, DifferenceType, ValueType>, Base, T>
  217. : Base
  218. {
  219. typedef typename rebind_any<Base, ValueType>::type value_type;
  220. typedef typename rebind_any<
  221. Base,
  222. typename iterator_reference<Reference, ValueType>::type
  223. >::type reference;
  224. typedef DifferenceType difference_type;
  225. typedef typename ::boost::mpl::if_< ::boost::is_reference<reference>,
  226. typename ::boost::remove_reference<reference>::type*,
  227. value_type*
  228. >::type pointer;
  229. };
  230. template<class T, class Reference, class DifferenceType, class ValueType, class Base>
  231. struct concept_interface<iterator< ::boost::forward_traversal_tag, T, Reference, DifferenceType, ValueType>, Base, T>
  232. : Base
  233. {
  234. typedef std::forward_iterator_tag iterator_category;
  235. };
  236. template<class T, class Reference, class DifferenceType, class ValueType, class Base>
  237. struct concept_interface<forward_iterator<T, Reference, DifferenceType, ValueType>, Base, T>
  238. : Base
  239. {
  240. typedef std::forward_iterator_tag iterator_category;
  241. };
  242. template<class T, class Reference, class DifferenceType, class ValueType, class Base>
  243. struct concept_interface<iterator< ::boost::bidirectional_traversal_tag, T, Reference, DifferenceType, ValueType>, Base, T>
  244. : Base
  245. {
  246. typedef std::bidirectional_iterator_tag iterator_category;
  247. };
  248. template<class T, class Reference, class DifferenceType, class ValueType, class Base>
  249. struct concept_interface<bidirectional_iterator<T, Reference, DifferenceType, ValueType>, Base, T>
  250. : Base
  251. {
  252. typedef std::bidirectional_iterator_tag iterator_category;
  253. };
  254. template<class T, class Reference, class DifferenceType, class ValueType, class Base>
  255. struct concept_interface<iterator< ::boost::random_access_traversal_tag, T, Reference, DifferenceType, ValueType>, Base, T>
  256. : Base
  257. {
  258. typedef std::random_access_iterator_tag iterator_category;
  259. };
  260. template<class T, class Reference, class DifferenceType, class ValueType, class Base>
  261. struct concept_interface<random_access_iterator<T, Reference, DifferenceType, ValueType>, Base, T>
  262. : Base
  263. {
  264. typedef std::random_access_iterator_tag iterator_category;
  265. };
  266. /// \endcond
  267. }
  268. }
  269. #endif