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