iterator.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file iterator.hpp
  3. /// Proto callables for std functions found in \<iterator\>
  4. //
  5. // Copyright 2012 Eric Niebler. Distributed under the Boost
  6. // Software License, Version 1.0. (See accompanying file
  7. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. #ifndef BOOST_PROTO_FUNCTIONAL_STD_ITERATOR_HPP_EAN_27_08_2012
  9. #define BOOST_PROTO_FUNCTIONAL_STD_ITERATOR_HPP_EAN_27_08_2012
  10. #include <iterator>
  11. #include <boost/type_traits/remove_const.hpp>
  12. #include <boost/type_traits/remove_reference.hpp>
  13. #include <boost/proto/proto_fwd.hpp>
  14. namespace boost { namespace proto { namespace functional
  15. {
  16. // A PolymorphicFunctionObject wrapping std::advance
  17. struct advance
  18. {
  19. BOOST_PROTO_CALLABLE()
  20. typedef void result_type;
  21. template<typename InputIterator, typename Distance>
  22. void operator()(InputIterator &x, Distance n) const
  23. {
  24. std::advance(x, n);
  25. }
  26. };
  27. // A PolymorphicFunctionObject wrapping std::distance
  28. struct distance
  29. {
  30. BOOST_PROTO_CALLABLE()
  31. template<typename Sig>
  32. struct result;
  33. template<typename This, typename InputIter1, typename InputIter2>
  34. struct result<This(InputIter1, InputIter2)>
  35. {
  36. typedef
  37. typename std::iterator_traits<
  38. typename boost::remove_const<
  39. typename boost::remove_reference<InputIter1>::type
  40. >::type
  41. >::difference_type
  42. type;
  43. };
  44. template<typename InputIterator>
  45. typename std::iterator_traits<InputIterator>::difference_type
  46. operator()(InputIterator first, InputIterator last) const
  47. {
  48. return std::distance(first, last);
  49. }
  50. };
  51. // A PolymorphicFunctionObject wrapping std::next
  52. struct next
  53. {
  54. BOOST_PROTO_CALLABLE()
  55. template<typename Sig>
  56. struct result;
  57. template<typename This, typename ForwardIterator>
  58. struct result<This(ForwardIterator)>
  59. {
  60. typedef
  61. typename boost::remove_const<
  62. typename boost::remove_reference<ForwardIterator>::type
  63. >::type
  64. type;
  65. };
  66. template<typename This, typename ForwardIterator, typename Distance>
  67. struct result<This(ForwardIterator, Distance)>
  68. {
  69. typedef
  70. typename boost::remove_const<
  71. typename boost::remove_reference<ForwardIterator>::type
  72. >::type
  73. type;
  74. };
  75. template<typename ForwardIterator>
  76. ForwardIterator operator()(ForwardIterator x) const
  77. {
  78. return std::advance(
  79. x
  80. , static_cast<typename std::iterator_traits<ForwardIterator>::difference_type>(1)
  81. );
  82. }
  83. template<typename ForwardIterator>
  84. ForwardIterator operator()(
  85. ForwardIterator x
  86. , typename std::iterator_traits<ForwardIterator>::difference_type n
  87. ) const
  88. {
  89. return std::advance(x, n);
  90. }
  91. };
  92. // A PolymorphicFunctionObject wrapping std::prior
  93. struct prior
  94. {
  95. BOOST_PROTO_CALLABLE()
  96. template<typename Sig>
  97. struct result;
  98. template<typename This, typename BidirectionalIterator>
  99. struct result<This(BidirectionalIterator)>
  100. {
  101. typedef
  102. typename boost::remove_const<
  103. typename boost::remove_reference<BidirectionalIterator>::type
  104. >::type
  105. type;
  106. };
  107. template<typename This, typename BidirectionalIterator, typename Distance>
  108. struct result<This(BidirectionalIterator, Distance)>
  109. {
  110. typedef
  111. typename boost::remove_const<
  112. typename boost::remove_reference<BidirectionalIterator>::type
  113. >::type
  114. type;
  115. };
  116. template<typename BidirectionalIterator>
  117. BidirectionalIterator operator()(BidirectionalIterator x) const
  118. {
  119. return std::advance(
  120. x
  121. , -static_cast<typename std::iterator_traits<BidirectionalIterator>::difference_type>(1)
  122. );
  123. }
  124. template<typename BidirectionalIterator>
  125. BidirectionalIterator operator()(
  126. BidirectionalIterator x
  127. , typename std::iterator_traits<BidirectionalIterator>::difference_type n
  128. ) const
  129. {
  130. return std::advance(x, -n);
  131. }
  132. };
  133. }}}
  134. #endif