iterator_concepts.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // (C) Copyright Jeremy Siek 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_ITERATOR_CONCEPTS_HPP
  6. #define BOOST_ITERATOR_CONCEPTS_HPP
  7. #include <boost/concept_check.hpp>
  8. #include <boost/iterator/iterator_categories.hpp>
  9. // Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
  10. #include <boost/detail/iterator.hpp>
  11. #include <boost/type_traits/is_same.hpp>
  12. #include <boost/type_traits/is_integral.hpp>
  13. #include <boost/mpl/bool.hpp>
  14. #include <boost/mpl/if.hpp>
  15. #include <boost/mpl/and.hpp>
  16. #include <boost/mpl/or.hpp>
  17. #include <boost/static_assert.hpp>
  18. // Use boost/limits to work around missing limits headers on some compilers
  19. #include <boost/limits.hpp>
  20. #include <boost/config.hpp>
  21. #include <algorithm>
  22. #include <boost/concept/detail/concept_def.hpp>
  23. namespace boost_concepts
  24. {
  25. // Used a different namespace here (instead of "boost") so that the
  26. // concept descriptions do not take for granted the names in
  27. // namespace boost.
  28. //===========================================================================
  29. // Iterator Access Concepts
  30. BOOST_concept(ReadableIterator,(Iterator))
  31. : boost::Assignable<Iterator>
  32. , boost::CopyConstructible<Iterator>
  33. {
  34. typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type value_type;
  35. typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference reference;
  36. BOOST_CONCEPT_USAGE(ReadableIterator)
  37. {
  38. value_type v = *i;
  39. boost::ignore_unused_variable_warning(v);
  40. }
  41. private:
  42. Iterator i;
  43. };
  44. template <
  45. typename Iterator
  46. , typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
  47. >
  48. struct WritableIterator
  49. : boost::CopyConstructible<Iterator>
  50. {
  51. BOOST_CONCEPT_USAGE(WritableIterator)
  52. {
  53. *i = v;
  54. }
  55. private:
  56. ValueType v;
  57. Iterator i;
  58. };
  59. template <
  60. typename Iterator
  61. , typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
  62. >
  63. struct WritableIteratorConcept : WritableIterator<Iterator,ValueType> {};
  64. BOOST_concept(SwappableIterator,(Iterator))
  65. {
  66. BOOST_CONCEPT_USAGE(SwappableIterator)
  67. {
  68. std::iter_swap(i1, i2);
  69. }
  70. private:
  71. Iterator i1;
  72. Iterator i2;
  73. };
  74. BOOST_concept(LvalueIterator,(Iterator))
  75. {
  76. typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
  77. BOOST_CONCEPT_USAGE(LvalueIterator)
  78. {
  79. value_type& r = const_cast<value_type&>(*i);
  80. boost::ignore_unused_variable_warning(r);
  81. }
  82. private:
  83. Iterator i;
  84. };
  85. //===========================================================================
  86. // Iterator Traversal Concepts
  87. BOOST_concept(IncrementableIterator,(Iterator))
  88. : boost::Assignable<Iterator>
  89. , boost::CopyConstructible<Iterator>
  90. {
  91. typedef typename boost::iterator_traversal<Iterator>::type traversal_category;
  92. BOOST_CONCEPT_ASSERT((
  93. boost::Convertible<
  94. traversal_category
  95. , boost::incrementable_traversal_tag
  96. >));
  97. BOOST_CONCEPT_USAGE(IncrementableIterator)
  98. {
  99. ++i;
  100. (void)i++;
  101. }
  102. private:
  103. Iterator i;
  104. };
  105. BOOST_concept(SinglePassIterator,(Iterator))
  106. : IncrementableIterator<Iterator>
  107. , boost::EqualityComparable<Iterator>
  108. {
  109. BOOST_CONCEPT_ASSERT((
  110. boost::Convertible<
  111. BOOST_DEDUCED_TYPENAME SinglePassIterator::traversal_category
  112. , boost::single_pass_traversal_tag
  113. > ));
  114. };
  115. BOOST_concept(ForwardTraversal,(Iterator))
  116. : SinglePassIterator<Iterator>
  117. , boost::DefaultConstructible<Iterator>
  118. {
  119. typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
  120. BOOST_MPL_ASSERT((boost::is_integral<difference_type>));
  121. BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
  122. BOOST_CONCEPT_ASSERT((
  123. boost::Convertible<
  124. BOOST_DEDUCED_TYPENAME ForwardTraversal::traversal_category
  125. , boost::forward_traversal_tag
  126. > ));
  127. };
  128. BOOST_concept(BidirectionalTraversal,(Iterator))
  129. : ForwardTraversal<Iterator>
  130. {
  131. BOOST_CONCEPT_ASSERT((
  132. boost::Convertible<
  133. BOOST_DEDUCED_TYPENAME BidirectionalTraversal::traversal_category
  134. , boost::bidirectional_traversal_tag
  135. > ));
  136. BOOST_CONCEPT_USAGE(BidirectionalTraversal)
  137. {
  138. --i;
  139. (void)i--;
  140. }
  141. private:
  142. Iterator i;
  143. };
  144. BOOST_concept(RandomAccessTraversal,(Iterator))
  145. : BidirectionalTraversal<Iterator>
  146. {
  147. BOOST_CONCEPT_ASSERT((
  148. boost::Convertible<
  149. BOOST_DEDUCED_TYPENAME RandomAccessTraversal::traversal_category
  150. , boost::random_access_traversal_tag
  151. > ));
  152. BOOST_CONCEPT_USAGE(RandomAccessTraversal)
  153. {
  154. i += n;
  155. i = i + n;
  156. i = n + i;
  157. i -= n;
  158. i = i - n;
  159. n = i - j;
  160. }
  161. private:
  162. typename BidirectionalTraversal<Iterator>::difference_type n;
  163. Iterator i, j;
  164. };
  165. //===========================================================================
  166. // Iterator Interoperability
  167. namespace detail
  168. {
  169. template <typename Iterator1, typename Iterator2>
  170. void interop_single_pass_constraints(Iterator1 const& i1, Iterator2 const& i2)
  171. {
  172. bool b;
  173. b = i1 == i2;
  174. b = i1 != i2;
  175. b = i2 == i1;
  176. b = i2 != i1;
  177. boost::ignore_unused_variable_warning(b);
  178. }
  179. template <typename Iterator1, typename Iterator2>
  180. void interop_rand_access_constraints(
  181. Iterator1 const& i1, Iterator2 const& i2,
  182. boost::random_access_traversal_tag, boost::random_access_traversal_tag)
  183. {
  184. bool b;
  185. typename boost::detail::iterator_traits<Iterator2>::difference_type n;
  186. b = i1 < i2;
  187. b = i1 <= i2;
  188. b = i1 > i2;
  189. b = i1 >= i2;
  190. n = i1 - i2;
  191. b = i2 < i1;
  192. b = i2 <= i1;
  193. b = i2 > i1;
  194. b = i2 >= i1;
  195. n = i2 - i1;
  196. boost::ignore_unused_variable_warning(b);
  197. boost::ignore_unused_variable_warning(n);
  198. }
  199. template <typename Iterator1, typename Iterator2>
  200. void interop_rand_access_constraints(
  201. Iterator1 const&, Iterator2 const&,
  202. boost::single_pass_traversal_tag, boost::single_pass_traversal_tag)
  203. { }
  204. } // namespace detail
  205. BOOST_concept(InteroperableIterator,(Iterator)(ConstIterator))
  206. {
  207. private:
  208. typedef typename boost::detail::pure_traversal_tag<
  209. typename boost::iterator_traversal<
  210. Iterator
  211. >::type
  212. >::type traversal_category;
  213. typedef typename boost::detail::pure_traversal_tag<
  214. typename boost::iterator_traversal<
  215. ConstIterator
  216. >::type
  217. >::type const_traversal_category;
  218. public:
  219. BOOST_CONCEPT_ASSERT((SinglePassIterator<Iterator>));
  220. BOOST_CONCEPT_ASSERT((SinglePassIterator<ConstIterator>));
  221. BOOST_CONCEPT_USAGE(InteroperableIterator)
  222. {
  223. detail::interop_single_pass_constraints(i, ci);
  224. detail::interop_rand_access_constraints(i, ci, traversal_category(), const_traversal_category());
  225. ci = i;
  226. }
  227. private:
  228. Iterator i;
  229. ConstIterator ci;
  230. };
  231. } // namespace boost_concepts
  232. #include <boost/concept/detail/concept_undef.hpp>
  233. #endif // BOOST_ITERATOR_CONCEPTS_HPP