• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
46     struct boost_tuple_iterator_identity;
47 
48     template <typename Cons = tuples::null_type>
49     struct boost_tuple_iterator
50         : iterator_facade<boost_tuple_iterator<Cons>, forward_traversal_tag>
51     {
52         typedef Cons cons_type;
53 
54         typedef boost_tuple_iterator_identity<
55             typename add_const<Cons>::type> identity;
56 
57         BOOST_FUSION_GPU_ENABLED
boost_tuple_iteratorboost::fusion::boost_tuple_iterator58         explicit boost_tuple_iterator(Cons& in_cons)
59             : cons(in_cons) {}
60         Cons& cons;
61 
62         template <typename Iterator>
63         struct value_of : mpl::identity<typename Iterator::cons_type::head_type> {};
64 
65         template <typename Iterator>
66         struct deref
67         {
68             typedef typename value_of<Iterator>::type element;
69 
70             typedef typename
71                 mpl::if_<
72                     is_const<typename Iterator::cons_type>
73                   , typename tuples::access_traits<element>::const_type
74                   , typename tuples::access_traits<element>::non_const_type
75                 >::type
76             type;
77 
78             BOOST_FUSION_GPU_ENABLED
79             static type
callboost::fusion::boost_tuple_iterator::deref80             call(Iterator const& iter)
81             {
82                 return iter.cons.get_head();
83             }
84         };
85 
86         template <typename Iterator>
87         struct next
88         {
89             typedef typename Iterator::cons_type cons_type;
90             typedef typename cons_type::tail_type tail_type;
91 
92             typedef boost_tuple_iterator<
93                 typename mpl::eval_if<
94                     is_const<cons_type>
95                   , add_const<tail_type>
96                   , mpl::identity<tail_type>
97                 >::type>
98             type;
99 
100             BOOST_FUSION_GPU_ENABLED
101             static type
callboost::fusion::boost_tuple_iterator::next102             call(Iterator const& iter)
103             {
104                 return type(iter.cons.get_tail());
105             }
106         };
107 
108         template <typename I1, typename I2>
109         struct distance;
110 
111         // detail
112         template <typename I1, typename I2>
113         struct lazy_next_distance
114         {
115             typedef
116                 typename mpl::plus<
117                     mpl::int_<1>,
118                     typename distance<
119                         typename next<I1>::type,
120                         I2
121                     >::type
122                 >::type type;
123         };
124 
125         template <typename I1, typename I2>
126         struct distance
127         {
128             typedef typename mpl::eval_if<
129                 boost::is_same<I1, I2>,
130                 mpl::int_<0>,
131                 lazy_next_distance<I1, I2>
132             >::type type;
133 
134             BOOST_FUSION_GPU_ENABLED
135             static type
callboost::fusion::boost_tuple_iterator::distance136             call(I1 const&, I2 const&)
137             {
138                 return type();
139             }
140         };
141 
142         template <typename I1, typename I2>
143         struct equal_to
144             : is_same<typename I1::identity, typename I2::identity>
145         {};
146 
147         // silence MSVC warning C4512: assignment operator could not be generated
148         BOOST_DELETED_FUNCTION(boost_tuple_iterator& operator= (boost_tuple_iterator const&))
149     };
150 
151     template <typename Null>
152     struct boost_tuple_null_iterator
153         : iterator_facade<boost_tuple_iterator<Null>, forward_traversal_tag>
154     {
155         typedef Null cons_type;
156 
157         typedef boost_tuple_iterator_identity<
158             typename add_const<Null>::type> identity;
159 
160         template <typename I1, typename I2>
161         struct equal_to
162             : mpl::or_<
163                 is_same<I1, I2>
164               , mpl::and_<
165                     detail::boost_tuple_is_empty<typename I1::cons_type>
166                   , detail::boost_tuple_is_empty<typename I2::cons_type>
167                 >
168             >
169         {};
170     };
171 
172     template <>
173     struct boost_tuple_iterator<tuples::null_type>
174         : boost_tuple_null_iterator<tuples::null_type>
175     {
176         template <typename Cons>
177         BOOST_FUSION_GPU_ENABLED
boost_tuple_iteratorboost::fusion::boost_tuple_iterator178         explicit boost_tuple_iterator(Cons const&) {}
179     };
180 
181     template <>
182     struct boost_tuple_iterator<tuples::null_type const>
183         : boost_tuple_null_iterator<tuples::null_type const>
184     {
185         template <typename Cons>
186         BOOST_FUSION_GPU_ENABLED
boost_tuple_iteratorboost::fusion::boost_tuple_iterator187         explicit boost_tuple_iterator(Cons const&) {}
188     };
189 
190     template <>
191     struct boost_tuple_iterator<tuples::tuple<> >
192         : boost_tuple_null_iterator<tuples::tuple<> >
193     {
194         template <typename Cons>
195         BOOST_FUSION_GPU_ENABLED
196         explicit boost_tuple_iterator(Cons const&) {}
197     };
198 
199     template <>
200     struct boost_tuple_iterator<tuples::tuple<> const>
201         : boost_tuple_null_iterator<tuples::tuple<> const>
202     {
203         template <typename Cons>
204         BOOST_FUSION_GPU_ENABLED
205         explicit boost_tuple_iterator(Cons const&) {}
206     };
207 }}
208 
209 #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408
210 namespace std
211 {
212     template <typename Cons>
213     struct iterator_traits< ::boost::fusion::boost_tuple_iterator<Cons> >
214     { };
215 }
216 #endif
217 
218 #endif
219 
220 
221