iterator.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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. using boost::movelib::iter_difference;
  42. using boost::movelib::iter_value;
  43. using boost::movelib::iter_category;
  44. using boost::movelib::iter_size;
  45. ////////////////////
  46. // iterator
  47. ////////////////////
  48. template<class Category, class T, class Difference, class Pointer, class Reference>
  49. struct iterator
  50. {
  51. typedef Category iterator_category;
  52. typedef T value_type;
  53. typedef Difference difference_type;
  54. typedef Pointer pointer;
  55. typedef Reference reference;
  56. };
  57. ////////////////////////////////////////////////////////////////////////////////
  58. // Conversion from boost::iterator traversals to std tags
  59. ////////////////////////////////////////////////////////////////////////////////
  60. template<class Tag>
  61. struct get_std_category_from_tag
  62. {
  63. typedef Tag type;
  64. };
  65. template <class Category>
  66. struct get_std_category_from_tag
  67. <boost::iterators::detail::iterator_category_with_traversal
  68. <Category, boost::iterators::incrementable_traversal_tag> >
  69. {
  70. typedef std::input_iterator_tag type;
  71. };
  72. template <class Category>
  73. struct get_std_category_from_tag
  74. <boost::iterators::detail::iterator_category_with_traversal
  75. <Category, boost::iterators::single_pass_traversal_tag> >
  76. {
  77. typedef std::input_iterator_tag type;
  78. };
  79. template <class Category>
  80. struct get_std_category_from_tag
  81. <boost::iterators::detail::iterator_category_with_traversal
  82. <Category, boost::iterators::forward_traversal_tag> >
  83. {
  84. typedef std::input_iterator_tag type;
  85. };
  86. template <class Category>
  87. struct get_std_category_from_tag
  88. <boost::iterators::detail::iterator_category_with_traversal
  89. <Category, boost::iterators::bidirectional_traversal_tag> >
  90. {
  91. typedef std::bidirectional_iterator_tag type;
  92. };
  93. template <class Category>
  94. struct get_std_category_from_tag
  95. <boost::iterators::detail::iterator_category_with_traversal
  96. <Category, boost::iterators::random_access_traversal_tag> >
  97. {
  98. typedef std::random_access_iterator_tag type;
  99. };
  100. template<class It>
  101. struct get_std_category_from_it
  102. : get_std_category_from_tag< typename boost::intrusive::iter_category<It>::type >
  103. {};
  104. ////////////////////////////////////////
  105. // iterator_[dis|en]able_if_tag
  106. ////////////////////////////////////////
  107. template<class I, class Tag, class R = void>
  108. struct iterator_enable_if_tag
  109. : ::boost::move_detail::enable_if_c
  110. < ::boost::move_detail::is_same
  111. < typename get_std_category_from_it<I>::type
  112. , Tag
  113. >::value
  114. , R>
  115. {};
  116. template<class I, class Tag, class R = void>
  117. struct iterator_disable_if_tag
  118. : ::boost::move_detail::enable_if_c
  119. < !::boost::move_detail::is_same
  120. < typename get_std_category_from_it<I>::type
  121. , Tag
  122. >::value
  123. , R>
  124. {};
  125. ////////////////////////////////////////
  126. // iterator_[dis|en]able_if_tag
  127. ////////////////////////////////////////
  128. template<class I, class Tag, class Tag2, class R = void>
  129. struct iterator_enable_if_convertible_tag
  130. : ::boost::move_detail::enable_if_c
  131. < ::boost::move_detail::is_same_or_convertible
  132. < typename get_std_category_from_it<I>::type
  133. , Tag
  134. >::value &&
  135. !::boost::move_detail::is_same_or_convertible
  136. < typename get_std_category_from_it<I>::type
  137. , Tag2
  138. >::value
  139. , R>
  140. {};
  141. ////////////////////////////////////////
  142. // iterator_[dis|en]able_if_tag_difference_type
  143. ////////////////////////////////////////
  144. template<class I, class Tag>
  145. struct iterator_enable_if_tag_difference_type
  146. : iterator_enable_if_tag<I, Tag, typename boost::intrusive::iter_difference<I>::type>
  147. {};
  148. template<class I, class Tag>
  149. struct iterator_disable_if_tag_difference_type
  150. : iterator_disable_if_tag<I, Tag, typename boost::intrusive::iter_difference<I>::type>
  151. {};
  152. ////////////////////
  153. // advance
  154. ////////////////////
  155. template<class InputIt>
  156. inline typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type
  157. iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
  158. {
  159. while(n--)
  160. ++it;
  161. }
  162. template<class InputIt>
  163. typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type
  164. iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
  165. {
  166. while(n--)
  167. ++it;
  168. }
  169. template<class InputIt>
  170. inline typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type
  171. iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
  172. {
  173. for (; 0 < n; --n)
  174. ++it;
  175. for (; n < 0; ++n)
  176. --it;
  177. }
  178. template<class InputIt, class Distance>
  179. inline typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type
  180. iterator_advance(InputIt& it, Distance n)
  181. {
  182. it += n;
  183. }
  184. template<class InputIt, class Distance>
  185. inline typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag, InputIt>::type
  186. make_iterator_advance(InputIt it, Distance n)
  187. {
  188. (iterator_advance)(it, n);
  189. return it;
  190. }
  191. template<class It>
  192. inline
  193. void iterator_uadvance(It& it, typename iter_size<It>::type n)
  194. {
  195. (iterator_advance)(it, (typename iterator_traits<It>::difference_type)n);
  196. }
  197. template<class It>
  198. inline
  199. It make_iterator_uadvance(It it, typename iter_size<It>::type n)
  200. {
  201. (iterator_uadvance)(it, n);
  202. return it;
  203. }
  204. ////////////////////////////////////////
  205. // iterator_distance
  206. ////////////////////////////////////////
  207. template<class InputIt> inline
  208. typename iterator_disable_if_tag_difference_type
  209. <InputIt, std::random_access_iterator_tag>::type
  210. iterator_distance(InputIt first, InputIt last)
  211. {
  212. typename iter_difference<InputIt>::type off = 0;
  213. while(first != last){
  214. ++off;
  215. ++first;
  216. }
  217. return off;
  218. }
  219. template<class InputIt>
  220. inline typename iterator_enable_if_tag_difference_type
  221. <InputIt, std::random_access_iterator_tag>::type
  222. iterator_distance(InputIt first, InputIt last)
  223. {
  224. typename iter_difference<InputIt>::type off = last - first;
  225. return off;
  226. }
  227. ////////////////////////////////////////
  228. // iterator_udistance
  229. ////////////////////////////////////////
  230. template<class It>
  231. inline typename iter_size<It>::type
  232. iterator_udistance(It first, It last)
  233. {
  234. return (typename iter_size<It>::type)(iterator_distance)(first, last);
  235. }
  236. ////////////////////////////////////////
  237. // iterator_next
  238. ////////////////////////////////////////
  239. template<class InputIt>
  240. inline InputIt iterator_next(InputIt it, typename iter_difference<InputIt>::type n)
  241. {
  242. (iterator_advance)(it, n);
  243. return it;
  244. }
  245. template<class InputIt>
  246. inline InputIt iterator_unext(InputIt it, typename iterator_traits<InputIt>::size_type n)
  247. {
  248. (iterator_uadvance)(it, n);
  249. return it;
  250. }
  251. ////////////////////////////////////////
  252. // iterator_arrow_result
  253. ////////////////////////////////////////
  254. template<class I>
  255. inline typename iterator_traits<I>::pointer iterator_arrow_result(const I &i)
  256. { return i.operator->(); }
  257. template<class T>
  258. inline T * iterator_arrow_result(T *p)
  259. { return p; }
  260. } //namespace intrusive
  261. } //namespace boost
  262. #endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP