Imported Upstream version 1.51.0
[platform/upstream/boost.git] / boost / proto / detail / reverse.hpp
1 /*=============================================================================
2     Copyright (c) 2001-2006 Joel de Guzman
3     Copyright (c) 2008 Eric Niebler
4
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #ifndef BOOST_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008
9 #define BOOST_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008
10
11 #include <boost/spirit/fusion/detail/access.hpp>
12 #include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp>
13 #include <boost/spirit/fusion/iterator/detail/iterator_base.hpp>
14 #include <boost/spirit/fusion/sequence/detail/sequence_base.hpp>
15 #include <boost/spirit/fusion/iterator/next.hpp>
16 #include <boost/spirit/fusion/iterator/prior.hpp>
17 #include <boost/spirit/fusion/iterator/deref.hpp>
18 #include <boost/spirit/fusion/iterator/value_of.hpp>
19 #include <boost/spirit/fusion/sequence/begin.hpp>
20 #include <boost/spirit/fusion/sequence/end.hpp>
21
22 namespace boost { namespace fusion
23 {
24     struct reverse_view_tag;
25     struct reverse_view_iterator_tag;
26
27     template <typename First>
28     struct reverse_view_iterator
29         : iterator_base<reverse_view_iterator<First> >
30     {
31         typedef as_fusion_iterator<First> converter;
32         typedef typename converter::type first_type;
33         typedef reverse_view_iterator_tag tag;
34
35         reverse_view_iterator(First const& first)
36             : first(converter::convert(first)) {}
37
38         first_type first;
39     };
40
41     template <typename Sequence>
42     struct reverse_view : sequence_base<reverse_view<Sequence> >
43     {
44         typedef as_fusion_sequence<Sequence> seq_converter;
45         typedef typename seq_converter::type seq;
46
47         typedef reverse_view_tag tag;
48         typedef typename meta::begin<seq>::type first_type;
49         typedef typename meta::end<seq>::type last_type;
50
51         reverse_view(Sequence& seq)
52           : first(fusion::begin(seq))
53           , last(fusion::end(seq))
54         {}
55
56         first_type first;
57         last_type last;
58     };
59
60     namespace meta
61     {
62         template <>
63         struct deref_impl<reverse_view_iterator_tag>
64         {
65             template <typename Iterator>
66             struct apply
67             {
68                 typedef typename
69                     meta::deref<
70                         typename meta::prior<
71                             typename Iterator::first_type
72                         >::type
73                     >::type
74                 type;
75
76                 static type
77                 call(Iterator const& i)
78                 {
79                     return *fusion::prior(i.first);
80                 }
81             };
82         };
83
84         template <>
85         struct prior_impl<reverse_view_iterator_tag>
86         {
87             template <typename Iterator>
88             struct apply
89             {
90                 typedef typename Iterator::first_type first_type;
91                 typedef typename next_impl<typename first_type::tag>::
92                     template apply<first_type>
93                 wrapped;
94
95                 typedef reverse_view_iterator<typename wrapped::type> type;
96
97                 static type
98                 call(Iterator const& i)
99                 {
100                     return type(wrapped::call(i.first));
101                 }
102             };
103         };
104
105         template <>
106         struct next_impl<reverse_view_iterator_tag>
107         {
108             template <typename Iterator>
109             struct apply
110             {
111                 typedef typename Iterator::first_type first_type;
112                 typedef typename prior_impl<typename first_type::tag>::
113                     template apply<first_type>
114                 wrapped;
115
116                 typedef reverse_view_iterator<typename wrapped::type> type;
117
118                 static type
119                 call(Iterator const& i)
120                 {
121                     return type(wrapped::call(i.first));
122                 }
123             };
124         };
125
126         template <>
127         struct value_impl<reverse_view_iterator_tag>
128         {
129             template <typename Iterator>
130             struct apply
131             {
132                 typedef typename
133                     meta::value_of<
134                         typename meta::prior<
135                             typename Iterator::first_type
136                         >::type
137                     >::type
138                 type;
139             };
140         };
141
142         template <>
143         struct begin_impl<reverse_view_tag>
144         {
145             template <typename Sequence>
146             struct apply
147             {
148                 typedef reverse_view_iterator<typename Sequence::last_type> type;
149
150                 static type
151                 call(Sequence const& s)
152                 {
153                     return type(s.last);
154                 }
155             };
156         };
157
158         template <>
159         struct end_impl<reverse_view_tag>
160         {
161             template <typename Sequence>
162             struct apply
163             {
164                 typedef reverse_view_iterator<typename Sequence::first_type> type;
165
166                 static type
167                 call(Sequence const& s)
168                 {
169                     return type(s.first);
170                 }
171             };
172         };
173
174         template <typename Sequence>
175         struct reverse
176         {
177             typedef reverse_view<Sequence> type;
178         };
179     }
180
181     template <typename Sequence>
182     inline reverse_view<Sequence const>
183     reverse(Sequence const& view)
184     {
185         return reverse_view<Sequence const>(view);
186     }
187 }}
188
189 #endif