annotate DEPENDENCIES/generic/include/boost/range/combine.hpp @ 16:2665513ce2d3

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