advance.hpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(FUSION_ADVANCE_09172005_1146)
  7. #define FUSION_ADVANCE_09172005_1146
  8. #include <boost/fusion/iterator/detail/advance.hpp>
  9. #include <boost/fusion/support/category_of.hpp>
  10. #include <boost/mpl/int.hpp>
  11. #include <boost/mpl/assert.hpp>
  12. #include <boost/type_traits/is_same.hpp>
  13. #include <boost/fusion/support/tag_of.hpp>
  14. namespace boost { namespace fusion
  15. {
  16. struct random_access_traversal_tag;
  17. // Special tags:
  18. struct iterator_facade_tag; // iterator facade tag
  19. struct boost_array_iterator_tag; // boost::array iterator tag
  20. struct mpl_iterator_tag; // mpl sequence iterator tag
  21. struct std_pair_iterator_tag; // std::pair iterator tag
  22. namespace extension
  23. {
  24. template <typename Tag>
  25. struct advance_impl
  26. {
  27. // default implementation
  28. template <typename Iterator, typename N>
  29. struct apply :
  30. mpl::if_c<
  31. (N::value > 0)
  32. , advance_detail::forward<Iterator, N::value>
  33. , advance_detail::backward<Iterator, N::value>
  34. >::type
  35. {
  36. BOOST_MPL_ASSERT_NOT((traits::is_random_access<Iterator>));
  37. };
  38. };
  39. template <>
  40. struct advance_impl<iterator_facade_tag>
  41. {
  42. template <typename Iterator, typename N>
  43. struct apply : Iterator::template advance<Iterator, N> {};
  44. };
  45. template <>
  46. struct advance_impl<boost_array_iterator_tag>;
  47. template <>
  48. struct advance_impl<mpl_iterator_tag>;
  49. template <>
  50. struct advance_impl<std_pair_iterator_tag>;
  51. }
  52. namespace result_of
  53. {
  54. template <typename Iterator, int N>
  55. struct advance_c
  56. : extension::advance_impl<typename detail::tag_of<Iterator>::type>::template apply<Iterator, mpl::int_<N> >
  57. {};
  58. template <typename Iterator, typename N>
  59. struct advance
  60. : extension::advance_impl<typename detail::tag_of<Iterator>::type>::template apply<Iterator, N>
  61. {};
  62. }
  63. template <int N, typename Iterator>
  64. inline typename result_of::advance_c<Iterator, N>::type const
  65. advance_c(Iterator const& i)
  66. {
  67. return result_of::advance_c<Iterator, N>::call(i);
  68. }
  69. template<typename N, typename Iterator>
  70. inline typename result_of::advance<Iterator, N>::type const
  71. advance(Iterator const& i)
  72. {
  73. return result_of::advance<Iterator, N>::call(i);
  74. }
  75. }} // namespace boost::fusion
  76. #endif