iterator.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2014-2014
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/intrusive for documentation.
  10. //
  11. /////////////////////////////////////////////////////////////////////////////
  12. #ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
  13. #define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
  14. #ifndef BOOST_CONFIG_HPP
  15. # include <boost/config.hpp>
  16. #endif
  17. #if defined(BOOST_HAS_PRAGMA_ONCE)
  18. # pragma once
  19. #endif
  20. #include <cstddef>
  21. #include <boost/intrusive/detail/std_fwd.hpp>
  22. #include <boost/intrusive/detail/workaround.hpp>
  23. #include <boost/move/detail/iterator_traits.hpp>
  24. #include <boost/move/detail/meta_utils_core.hpp>
  25. namespace boost{
  26. namespace iterators{
  27. struct incrementable_traversal_tag;
  28. struct single_pass_traversal_tag;
  29. struct forward_traversal_tag;
  30. struct bidirectional_traversal_tag;
  31. struct random_access_traversal_tag;
  32. namespace detail{
  33. template <class Category, class Traversal>
  34. struct iterator_category_with_traversal;
  35. } //namespace boost{
  36. } //namespace iterators{
  37. } //namespace detail{
  38. namespace boost {
  39. namespace intrusive {
  40. using boost::movelib::iterator_traits;
  41. ////////////////////
  42. // iterator
  43. ////////////////////
  44. template<class Category, class T, class Difference, class Pointer, class Reference>
  45. struct iterator
  46. {
  47. typedef Category iterator_category;
  48. typedef T value_type;
  49. typedef Difference difference_type;
  50. typedef Pointer pointer;
  51. typedef Reference reference;
  52. };
  53. ////////////////////////////////////////
  54. // iterator_[dis|en]able_if_boost_iterator
  55. ////////////////////////////////////////
  56. template<class I>
  57. struct is_boost_iterator
  58. {
  59. static const bool value = false;
  60. };
  61. template<class Category, class Traversal>
  62. struct is_boost_iterator< boost::iterators::detail::iterator_category_with_traversal<Category, Traversal> >
  63. {
  64. static const bool value = true;
  65. };
  66. template<class I, class R = void>
  67. struct iterator_enable_if_boost_iterator
  68. : ::boost::move_detail::enable_if_c
  69. < is_boost_iterator<typename boost::intrusive::iterator_traits<I>::iterator_category >::value
  70. , R>
  71. {};
  72. ////////////////////////////////////////
  73. // iterator_[dis|en]able_if_tag
  74. ////////////////////////////////////////
  75. template<class I, class Tag, class R = void>
  76. struct iterator_enable_if_tag
  77. : ::boost::move_detail::enable_if_c
  78. < ::boost::move_detail::is_same
  79. < typename boost::intrusive::iterator_traits<I>::iterator_category
  80. , Tag
  81. >::value
  82. , R>
  83. {};
  84. template<class I, class Tag, class R = void>
  85. struct iterator_disable_if_tag
  86. : ::boost::move_detail::enable_if_c
  87. < !::boost::move_detail::is_same
  88. < typename boost::intrusive::iterator_traits<I>::iterator_category
  89. , Tag
  90. >::value
  91. , R>
  92. {};
  93. ////////////////////////////////////////
  94. // iterator_[dis|en]able_if_tag
  95. ////////////////////////////////////////
  96. template<class I, class Tag, class Tag2, class R = void>
  97. struct iterator_enable_if_convertible_tag
  98. : ::boost::move_detail::enable_if_c
  99. < ::boost::move_detail::is_same_or_convertible
  100. < typename boost::intrusive::iterator_traits<I>::iterator_category
  101. , Tag
  102. >::value &&
  103. !::boost::move_detail::is_same_or_convertible
  104. < typename boost::intrusive::iterator_traits<I>::iterator_category
  105. , Tag2
  106. >::value
  107. , R>
  108. {};
  109. ////////////////////////////////////////
  110. // iterator_[dis|en]able_if_tag_difference_type
  111. ////////////////////////////////////////
  112. template<class I, class Tag>
  113. struct iterator_enable_if_tag_difference_type
  114. : iterator_enable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type>
  115. {};
  116. template<class I, class Tag>
  117. struct iterator_disable_if_tag_difference_type
  118. : iterator_disable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type>
  119. {};
  120. ////////////////////
  121. // advance
  122. ////////////////////
  123. template<class InputIt, class Distance>
  124. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type
  125. iterator_advance(InputIt& it, Distance n)
  126. {
  127. while(n--)
  128. ++it;
  129. }
  130. template<class InputIt, class Distance>
  131. typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type
  132. iterator_advance(InputIt& it, Distance n)
  133. {
  134. while(n--)
  135. ++it;
  136. }
  137. template<class InputIt, class Distance>
  138. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type
  139. iterator_advance(InputIt& it, Distance n)
  140. {
  141. for (; 0 < n; --n)
  142. ++it;
  143. for (; n < 0; ++n)
  144. --it;
  145. }
  146. template<class InputIt, class Distance>
  147. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type
  148. iterator_advance(InputIt& it, Distance n)
  149. {
  150. it += n;
  151. }
  152. template<class InputIt, class Distance>
  153. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag
  154. <InputIt, const boost::iterators::incrementable_traversal_tag&, const boost::iterators::single_pass_traversal_tag&>::type
  155. iterator_advance(InputIt& it, Distance n)
  156. {
  157. while(n--)
  158. ++it;
  159. }
  160. template<class InputIt, class Distance>
  161. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag
  162. <InputIt, const boost::iterators::single_pass_traversal_tag &, const boost::iterators::forward_traversal_tag&>::type
  163. iterator_advance(InputIt& it, Distance n)
  164. {
  165. while(n--)
  166. ++it;
  167. }
  168. template<class InputIt, class Distance>
  169. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag
  170. <InputIt, const boost::iterators::forward_traversal_tag&, const boost::iterators::bidirectional_traversal_tag&>::type
  171. iterator_advance(InputIt& it, Distance n)
  172. {
  173. while(n--)
  174. ++it;
  175. }
  176. template<class InputIt, class Distance>
  177. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag
  178. <InputIt, const boost::iterators::bidirectional_traversal_tag&, const boost::iterators::random_access_traversal_tag&>::type
  179. iterator_advance(InputIt& it, Distance n)
  180. {
  181. for (; 0 < n; --n)
  182. ++it;
  183. for (; n < 0; ++n)
  184. --it;
  185. }
  186. class fake{};
  187. template<class InputIt, class Distance>
  188. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag
  189. <InputIt, const boost::iterators::random_access_traversal_tag&, const fake&>::type
  190. iterator_advance(InputIt& it, Distance n)
  191. {
  192. it += n;
  193. }
  194. ////////////////////
  195. // distance
  196. ////////////////////
  197. template<class InputIt> inline
  198. typename iterator_disable_if_tag_difference_type
  199. <InputIt, std::random_access_iterator_tag>::type
  200. iterator_distance(InputIt first, InputIt last)
  201. {
  202. typename iterator_traits<InputIt>::difference_type off = 0;
  203. while(first != last){
  204. ++off;
  205. ++first;
  206. }
  207. return off;
  208. }
  209. template<class InputIt>
  210. BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag_difference_type
  211. <InputIt, std::random_access_iterator_tag>::type
  212. iterator_distance(InputIt first, InputIt last)
  213. {
  214. typename iterator_traits<InputIt>::difference_type off = last - first;
  215. return off;
  216. }
  217. template<class I>
  218. BOOST_INTRUSIVE_FORCEINLINE typename iterator_traits<I>::pointer iterator_arrow_result(const I &i)
  219. { return i.operator->(); }
  220. template<class T>
  221. BOOST_INTRUSIVE_FORCEINLINE T * iterator_arrow_result(T *p)
  222. { return p; }
  223. } //namespace intrusive
  224. } //namespace boost
  225. #endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP