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_1149)
8 #define FUSION_ADVANCE_09172005_1149
9 
10 #include <boost/fusion/support/config.hpp>
11 #include <boost/mpl/int.hpp>
12 #include <boost/mpl/if.hpp>
13 #include <boost/mpl/eval_if.hpp>
14 #include <boost/mpl/identity.hpp>
15 #include <boost/fusion/iterator/next.hpp>
16 #include <boost/fusion/iterator/prior.hpp>
17 
18 namespace boost { namespace fusion { namespace advance_detail
19 {
20     // Default advance implementation, perform next(i)
21     // or prior(i) N times.
22 
23     template <typename Iterator, int N>
24     struct forward;
25 
26     template <typename Iterator, int N>
27     struct next_forward
28     {
29         typedef typename
30             forward<
31                 typename result_of::next<Iterator>::type
32               , N-1
33             >::type
34         type;
35     };
36 
37     template <typename Iterator, int N>
38     struct forward
39     {
40         typedef typename
41             mpl::eval_if_c<
42                 (N == 0)
43               , mpl::identity<Iterator>
44               , next_forward<Iterator, N>
45             >::type
46         type;
47 
48         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
49         static type const&
callboost::fusion::advance_detail::forward50         call(type const& i)
51         {
52             return i;
53         }
54 
55         template <typename I>
56         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
57         static type
callboost::fusion::advance_detail::forward58         call(I const& i)
59         {
60             return call(fusion::next(i));
61         }
62     };
63 
64     template <typename Iterator, int N>
65     struct backward;
66 
67     template <typename Iterator, int N>
68     struct next_backward
69     {
70         typedef typename
71             backward<
72                 typename result_of::prior<Iterator>::type
73               , N+1
74             >::type
75         type;
76     };
77 
78     template <typename Iterator, int N>
79     struct backward
80     {
81         typedef typename
82             mpl::eval_if_c<
83                 (N == 0)
84               , mpl::identity<Iterator>
85               , next_backward<Iterator, N>
86             >::type
87         type;
88 
89         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
90         static type const&
callboost::fusion::advance_detail::backward91         call(type const& i)
92         {
93             return i;
94         }
95 
96         template <typename I>
97         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
98         static type
callboost::fusion::advance_detail::backward99         call(I const& i)
100         {
101             return call(fusion::prior(i));
102         }
103     };
104 
105 }}}
106 
107 #endif
108