source: XIOS/dev/dev_olga/src/extern/boost/include/boost/range/combine.hpp @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 10.7 KB
Line 
1#ifndef BOOST_RANGE_COMBINE_HPP
2#define BOOST_RANGE_COMBINE_HPP
3
4#include <boost/iterator/zip_iterator.hpp>
5#include <boost/tuple/tuple.hpp>
6#include <boost/range/iterator.hpp>
7#include <boost/range/iterator_range.hpp>
8#include <boost/type_traits/is_void.hpp>
9#include <boost/type_traits/is_same.hpp>
10#include <boost/mpl/eval_if.hpp>
11#include <boost/mpl/int.hpp>
12#include <boost/mpl/plus.hpp>
13#include <boost/mpl/arithmetic.hpp>
14#include <boost/config.hpp>
15
16namespace boost
17{
18    namespace range_detail
19    {
20        struct void_ { typedef void_ type; };
21    }
22
23    template<> struct range_iterator< ::boost::range_detail::void_ >
24    {
25       typedef ::boost::tuples::null_type type;
26    };
27
28    namespace range_detail
29    {
30        inline ::boost::tuples::null_type range_begin( ::boost::range_detail::void_& )
31        { return ::boost::tuples::null_type(); }
32
33        inline ::boost::tuples::null_type range_begin( const ::boost::range_detail::void_& )
34        { return ::boost::tuples::null_type(); }
35
36        inline ::boost::tuples::null_type range_end( ::boost::range_detail::void_& )
37        { return ::boost::tuples::null_type(); }
38
39        inline ::boost::tuples::null_type range_end( const ::boost::range_detail::void_& )
40        { return ::boost::tuples::null_type(); }
41
42        template< class T >
43        struct tuple_iter
44        {
45            typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c<
46                ::boost::is_same<T, ::boost::range_detail::void_ >::value,
47                ::boost::mpl::identity< ::boost::tuples::null_type >,
48                ::boost::range_iterator<T>
49            >::type type;
50        };
51
52        template< class Rng1, class Rng2 >
53        struct tuple_range
54        {
55            typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::eval_if_c<
56                ::boost::is_same<Rng1, ::boost::range_detail::void_ >::value,
57                ::boost::range_detail::void_,
58                ::boost::mpl::identity<Rng1>
59            >::type type;
60        };
61
62        template
63        <
64            class R1,
65            class R2,
66            class R3,
67            class R4,
68            class R5,
69            class R6
70        >
71        struct generate_tuple
72        {
73            typedef ::boost::tuples::tuple<
74                        BOOST_DEDUCED_TYPENAME tuple_iter<R1>::type,
75                        BOOST_DEDUCED_TYPENAME tuple_iter<R2>::type,
76                        BOOST_DEDUCED_TYPENAME tuple_iter<R3>::type,
77                        BOOST_DEDUCED_TYPENAME tuple_iter<R4>::type,
78                        BOOST_DEDUCED_TYPENAME tuple_iter<R5>::type,
79                        BOOST_DEDUCED_TYPENAME tuple_iter<R6>::type
80                    > type;
81
82            static type begin( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
83            {
84                return ::boost::tuples::make_tuple( ::boost::begin(r1),
85                                                    ::boost::begin(r2),
86                                                    ::boost::begin(r3),
87                                                    ::boost::begin(r4),
88                                                    ::boost::begin(r5),
89                                                    ::boost::begin(r6) );
90            }
91
92            static type end( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
93            {
94                return ::boost::tuples::make_tuple( ::boost::end(r1),
95                                                    ::boost::end(r2),
96                                                    ::boost::end(r3),
97                                                    ::boost::end(r4),
98                                                    ::boost::end(r5),
99                                                    ::boost::end(r6) );
100            }
101        };
102
103        template
104        <
105            class R1,
106            class R2 = void_,
107            class R3 = void_,
108            class R4 = void_,
109            class R5 = void_,
110            class R6 = void_
111        >
112        struct zip_rng
113            : iterator_range<
114                zip_iterator<
115                    BOOST_DEDUCED_TYPENAME generate_tuple<R1,R2,R3,R4,R5,R6>::type
116                >
117            >
118        {
119        private:
120            typedef generate_tuple<R1,R2,R3,R4,R5,R6>        generator_t;
121            typedef BOOST_DEDUCED_TYPENAME generator_t::type tuple_t;
122            typedef zip_iterator<tuple_t>                    zip_iter_t;
123            typedef iterator_range<zip_iter_t>               base_t;
124
125        public:
126            zip_rng( R1& r1, R2& r2, R3& r3, R4& r4, R5& r5, R6& r6 )
127            : base_t( zip_iter_t( generator_t::begin(r1,r2,r3,r4,r5,r6) ),
128                      zip_iter_t( generator_t::end(r1,r2,r3,r4,r5,r6) ) )
129            {
130                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
131                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3));
132                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r4));
133                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r5));
134                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r6));
135            }
136
137            template< class Zip, class Rng >
138            zip_rng( Zip& z, Rng& r )
139            : base_t( zip_iter_t( generator_t::begin( z, r ) ),
140                      zip_iter_t( generator_t::end( z, r ) ) )
141            {
142
143                // @todo: tuple::begin( should be overloaded for this situation
144            }
145
146            struct tuple_length : ::boost::tuples::length<tuple_t>
147            { };
148
149            template< unsigned N >
150            struct get
151            {
152                template< class Z, class R >
153                static BOOST_DEDUCED_TYPENAME ::boost::tuples::element<N,tuple_t>::type begin( Z& z, R& )
154                {
155                    return get<N>( z.begin().get_iterator_tuple() );
156                }
157
158                template< class Z, class R >
159                static BOOST_DEDUCED_TYPENAME ::boost::tuples::element<N,tuple_t>::type end( Z& z, R& r )
160                {
161                    return get<N>( z.end().get_iterator_tuple() );
162                }
163            };
164
165        };
166
167        template< class Rng1, class Rng2 >
168        struct zip_range
169            : iterator_range<
170                zip_iterator<
171                    ::boost::tuples::tuple<
172                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
173                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type
174                    >
175                >
176            >
177        {
178        private:
179            typedef zip_iterator<
180                        ::boost::tuples::tuple<
181                            BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
182                            BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type
183                        >
184                    > zip_iter_t;
185            typedef iterator_range<zip_iter_t> base_t;
186
187        public:
188            zip_range( Rng1& r1, Rng2& r2 )
189            : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1),
190                                                              ::boost::begin(r2)) ),
191                      zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1),
192                                                              ::boost::end(r2)) ) )
193            {
194                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
195            }
196        };
197
198        template< class Rng1, class Rng2, class Rng3 >
199        struct zip_range3
200            : iterator_range<
201                zip_iterator<
202                    ::boost::tuples::tuple<
203                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
204                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type,
205                        BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng3>::type
206                    >
207                >
208            >
209        {
210        private:
211            typedef zip_iterator<
212                ::boost::tuples::tuple<
213                    BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng1>::type,
214                    BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng2>::type,
215                    BOOST_DEDUCED_TYPENAME ::boost::range_iterator<Rng3>::type
216                >
217            > zip_iter_t;
218            typedef iterator_range<zip_iter_t> base_t;
219
220        public:
221            zip_range3( Rng1& r1, Rng2& r2, Rng3& r3 )
222            : base_t( zip_iter_t( ::boost::tuples::make_tuple(::boost::begin(r1),
223                                                              ::boost::begin(r2),
224                                                              ::boost::begin(r3)) ),
225                      zip_iter_t( ::boost::tuples::make_tuple(::boost::end(r1),
226                                                              ::boost::end(r2),
227                                                              ::boost::end(r3)) )
228                    )
229            {
230                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r2));
231                BOOST_ASSERT(::boost::distance(r1) <= ::boost::distance(r3));
232            }
233        };
234
235
236        struct combine_tag {};
237
238        template< class Rng >
239        inline zip_rng<Rng>
240        operator&( combine_tag, Rng& r )
241        {
242            return zip_rng<Rng>(r);
243        }
244
245        template< class Rng >
246        inline iterator_range<const Rng>
247        operator&( combine_tag, const Rng& r )
248        {
249            return iterator_range<const Rng>(r);
250        }
251
252        template
253        <
254            class R1,
255            class R2,
256            class R3,
257            class R4,
258            class R5,
259            class Rng
260        >
261        inline BOOST_DEDUCED_TYPENAME zip_rng<R1,R2,R3,R4,R5>::next
262        operator&( const zip_rng<R1,R2,R3,R4,R5>& zip,
263                   Rng& r )
264        {
265            return zip_rng<R1,R2,R3,R4,R5>::next( zip, r );
266        }
267
268    } // namespace range_detail
269
270    template< class Rng1, class Rng2 >
271    inline ::boost::range_detail::zip_range<Rng1, Rng2> combine( Rng1& r1, Rng2& r2 )
272    {
273        return ::boost::range_detail::zip_range<Rng1, Rng2>(r1, r2);
274    }
275
276    template< class Rng1, class Rng2 >
277    inline ::boost::range_detail::zip_range<const Rng1, Rng2> combine( const Rng1& r1, Rng2& r2 )
278    {
279        return ::boost::range_detail::zip_range<const Rng1, Rng2>(r1, r2);
280    }
281
282    template< class Rng1, class Rng2 >
283    inline ::boost::range_detail::zip_range<Rng1, const Rng2> combine( Rng1& r1, const Rng2& r2 )
284    {
285        return ::boost::range_detail::zip_range<Rng1, const Rng2>(r1, r2);
286    }
287
288    template< class Rng1, class Rng2 >
289    inline ::boost::range_detail::zip_range<const Rng1, const Rng2> combine( const Rng1& r1, const Rng2& r2 )
290    {
291        return ::boost::range_detail::zip_range<const Rng1, const Rng2>(r1, r2);
292    }
293
294} // namespace boost
295
296#endif
Note: See TracBrowser for help on using the repository browser.