iterator_concepts.hpp 7.2 KB

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