Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / fusion / adapted / boost_tuple / boost_tuple_iterator.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_BOOST_TUPLE_ITERATOR_09262006_1851)
8 #define FUSION_BOOST_TUPLE_ITERATOR_09262006_1851
9
10 #include <boost/fusion/support/config.hpp>
11 #include <boost/fusion/iterator/iterator_facade.hpp>
12 #include <boost/type_traits/is_const.hpp>
13 #include <boost/type_traits/add_const.hpp>
14 #include <boost/mpl/identity.hpp>
15 #include <boost/mpl/if.hpp>
16 #include <boost/mpl/eval_if.hpp>
17 #include <boost/mpl/or.hpp>
18 #include <boost/mpl/plus.hpp>
19 #include <boost/mpl/int.hpp>
20 #include <boost/mpl/apply.hpp>
21 #include <boost/tuple/tuple.hpp>
22
23 namespace boost { namespace fusion
24 {
25     struct forward_traversal_tag;
26
27     namespace detail
28     {
29         template <typename T>
30         struct boost_tuple_is_empty : mpl::false_ {};
31
32         template <>
33         struct boost_tuple_is_empty<tuples::null_type> : mpl::true_ {};
34
35         template <>
36         struct boost_tuple_is_empty<tuples::null_type const> : mpl::true_ {};
37
38         template <>
39         struct boost_tuple_is_empty<tuples::tuple<> > : mpl::true_ {};
40
41         template <>
42         struct boost_tuple_is_empty<tuples::tuple<> const> : mpl::true_ {};
43     }
44
45     template <typename Cons = tuples::null_type>
46     struct boost_tuple_iterator
47         : iterator_facade<boost_tuple_iterator<Cons>, forward_traversal_tag>
48     {
49         typedef Cons cons_type;
50
51         BOOST_FUSION_GPU_ENABLED
52         explicit boost_tuple_iterator(Cons& in_cons)
53             : cons(in_cons) {}
54         Cons& cons;
55
56         template <typename Iterator>
57         struct value_of : mpl::identity<typename Iterator::cons_type::head_type> {};
58
59         template <typename Iterator>
60         struct deref
61         {
62             typedef typename value_of<Iterator>::type element;
63
64             typedef typename
65                 mpl::if_<
66                     is_const<typename Iterator::cons_type>
67                   , typename tuples::access_traits<element>::const_type
68                   , typename tuples::access_traits<element>::non_const_type
69                 >::type
70             type;
71
72             BOOST_FUSION_GPU_ENABLED
73             static type
74             call(Iterator const& iter)
75             {
76                 return iter.cons.get_head();
77             }
78         };
79
80         template <typename Iterator>
81         struct next
82         {
83             typedef typename Iterator::cons_type cons_type;
84             typedef typename cons_type::tail_type tail_type;
85
86             typedef boost_tuple_iterator<
87                 typename mpl::eval_if<
88                     is_const<cons_type>
89                   , add_const<tail_type>
90                   , mpl::identity<tail_type>
91                 >::type>
92             type;
93
94             BOOST_FUSION_GPU_ENABLED
95             static type
96             call(Iterator const& iter)
97             {
98                 return type(iter.cons.get_tail());
99             }
100         };
101         
102         template <typename I1, typename I2>
103         struct distance;
104
105         // detail
106         template <typename I1, typename I2>
107         struct lazy_next_distance
108         {
109             typedef
110                 typename mpl::plus<
111                     mpl::int_<1>,
112                     typename distance<
113                         typename next<I1>::type,
114                         I2
115                     >::type
116                 >::type type;
117         };
118         
119         template <typename I1, typename I2>
120         struct distance
121         {
122             typedef typename mpl::eval_if<
123                 boost::is_same<I1, I2>,
124                 mpl::int_<0>,
125                 lazy_next_distance<I1, I2>
126             >::type type;
127             
128             BOOST_FUSION_GPU_ENABLED
129             static type
130             call(I1 const&, I2 const&)
131             {
132                 return type();
133             }
134         };
135
136     private:
137         // silence MSVC warning C4512: assignment operator could not be generated
138         boost_tuple_iterator& operator= (boost_tuple_iterator const&);
139     };
140
141     template <typename Null>
142     struct boost_tuple_null_iterator
143         : iterator_facade<boost_tuple_iterator<Null>, forward_traversal_tag>
144     {
145         typedef Null cons_type;
146
147         template <typename I1, typename I2>
148         struct equal_to
149             : mpl::or_<
150                 is_same<I1, I2>
151               , mpl::and_<
152                     detail::boost_tuple_is_empty<typename I1::cons_type>
153                   , detail::boost_tuple_is_empty<typename I2::cons_type>
154                 >
155             >
156         {};
157     };
158
159     template <>
160     struct boost_tuple_iterator<tuples::null_type>
161         : boost_tuple_null_iterator<tuples::null_type>
162     {
163         template <typename Cons>
164         BOOST_FUSION_GPU_ENABLED
165         explicit boost_tuple_iterator(Cons const&) {}
166     };
167
168     template <>
169     struct boost_tuple_iterator<tuples::null_type const>
170         : boost_tuple_null_iterator<tuples::null_type const>
171     {
172         template <typename Cons>
173         BOOST_FUSION_GPU_ENABLED
174         explicit boost_tuple_iterator(Cons const&) {}
175     };
176
177     template <>
178     struct boost_tuple_iterator<tuples::tuple<> >
179         : boost_tuple_null_iterator<tuples::tuple<> >
180     {
181         template <typename Cons>
182         BOOST_FUSION_GPU_ENABLED
183         explicit boost_tuple_iterator(Cons const&) {}
184     };
185
186     template <>
187     struct boost_tuple_iterator<tuples::tuple<> const>
188         : boost_tuple_null_iterator<tuples::tuple<> const>
189     {
190         template <typename Cons>
191         BOOST_FUSION_GPU_ENABLED
192         explicit boost_tuple_iterator(Cons const&) {}
193     };
194 }}
195
196 #endif
197
198