iterator_concepts.hpp 7.1 KB

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