File indexing completed on 2025-09-15 08:38:53
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
0009 #define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
0010
0011 #include <utility> // for std::pair
0012
0013 #include <boost/iterator/iterator_traits.hpp>
0014 #include <boost/iterator/iterator_facade.hpp>
0015 #include <boost/iterator/enable_if_convertible.hpp>
0016 #include <boost/iterator/iterator_categories.hpp>
0017 #include <boost/iterator/min_category.hpp>
0018
0019 #include <boost/mp11/list.hpp>
0020 #include <boost/mp11/utility.hpp>
0021 #include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
0022 #include <boost/fusion/algorithm/iteration/for_each.hpp>
0023 #include <boost/fusion/algorithm/transformation/transform.hpp>
0024 #include <boost/fusion/sequence/convert.hpp>
0025 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
0026 #include <boost/fusion/sequence/comparison/equal_to.hpp>
0027 #include <boost/fusion/support/tag_of_fwd.hpp>
0028
0029 namespace boost {
0030
0031
0032 namespace tuples {
0033 struct null_type;
0034 template< class, class >
0035 struct cons;
0036 }
0037
0038
0039 namespace fusion {
0040 struct void_;
0041 }
0042
0043 namespace iterators {
0044
0045
0046 template< typename IteratorTuple >
0047 class zip_iterator;
0048
0049 namespace detail {
0050
0051
0052
0053 template< typename DiffType >
0054 class advance_iterator
0055 {
0056 public:
0057 advance_iterator(DiffType step) :
0058 m_step(step)
0059 {}
0060
0061 template< typename Iterator >
0062 void operator()(Iterator& it) const { it += m_step; }
0063
0064 private:
0065 DiffType m_step;
0066 };
0067
0068 struct increment_iterator
0069 {
0070 template< typename Iterator >
0071 void operator()(Iterator& it) const { ++it; }
0072 };
0073
0074 struct decrement_iterator
0075 {
0076 template< typename Iterator >
0077 void operator()(Iterator& it) const { --it; }
0078 };
0079
0080 struct dereference_iterator
0081 {
0082 template< typename >
0083 struct result;
0084
0085 template< typename This, typename Iterator >
0086 struct result< This(Iterator) >
0087 {
0088 using type = iterator_reference_t<
0089 typename std::remove_cv< typename std::remove_reference< Iterator >::type >::type
0090 >;
0091 };
0092
0093 template< typename Iterator >
0094 typename result< dereference_iterator(Iterator) >::type operator()(Iterator const& it) const
0095 {
0096 return *it;
0097 }
0098 };
0099
0100
0101 template< typename T >
0102 struct is_trailing_null_type : std::false_type {};
0103 template< typename T >
0104 struct is_trailing_null_type< const T > : is_trailing_null_type< T > {};
0105 template< >
0106 struct is_trailing_null_type< tuples::null_type > : std::true_type {};
0107 template< >
0108 struct is_trailing_null_type< fusion::void_ > : std::true_type {};
0109
0110
0111
0112 template< typename IteratorTuple >
0113 struct tuple_of_references;
0114
0115 template< typename IteratorTuple >
0116 using tuple_of_references_t = typename tuple_of_references< IteratorTuple >::type;
0117
0118 template< template< typename... > class Tuple, typename... Iterators >
0119 struct tuple_of_references< Tuple< Iterators... > >
0120 {
0121
0122
0123
0124
0125 using type = Tuple<
0126 mp11::mp_eval_if<
0127 detail::is_trailing_null_type< Iterators >,
0128 Iterators,
0129 iterator_reference_t, Iterators
0130 >...
0131 >;
0132 };
0133
0134 template< typename Front, typename Tail >
0135 struct tuple_of_references< tuples::cons< Front, Tail > >
0136 {
0137 using type = tuples::cons<
0138 iterator_reference_t< Front >,
0139 mp11::mp_eval_if<
0140 detail::is_trailing_null_type< Tail >,
0141 Tail,
0142 detail::tuple_of_references_t, Tail
0143 >
0144 >;
0145 };
0146
0147
0148
0149 template< typename IteratorList >
0150 struct minimum_traversal_category_in_iterator_list;
0151
0152 template< typename IteratorList >
0153 using minimum_traversal_category_in_iterator_list_t = typename minimum_traversal_category_in_iterator_list< IteratorList >::type;
0154
0155 template< template< typename... > class List, typename... Iterators >
0156 struct minimum_traversal_category_in_iterator_list< List< Iterators... > >
0157 {
0158
0159
0160
0161
0162 using type = min_category_t<
0163 mp11::mp_eval_if<
0164 detail::is_trailing_null_type< Iterators >,
0165 random_access_traversal_tag,
0166 pure_iterator_traversal_t, Iterators
0167 >...
0168 >;
0169 };
0170
0171 template< typename FrontTraversal, typename Tail >
0172 using minimum_traversal_category_in_tail_t = min_category_t<
0173 FrontTraversal,
0174 minimum_traversal_category_in_iterator_list_t< Tail >
0175 >;
0176
0177 template< typename Front, typename Tail >
0178 struct minimum_traversal_category_in_iterator_list< tuples::cons< Front, Tail > >
0179 {
0180 using front_traversal = pure_iterator_traversal_t< Front >;
0181
0182 using type = mp11::mp_eval_if<
0183 detail::is_trailing_null_type< Tail >,
0184 front_traversal,
0185 minimum_traversal_category_in_tail_t,
0186 front_traversal,
0187 Tail
0188 >;
0189 };
0190
0191
0192
0193
0194
0195
0196
0197
0198 template< typename IteratorTuple >
0199 struct zip_iterator_base
0200 {
0201 private:
0202
0203
0204 using reference = detail::tuple_of_references_t< IteratorTuple >;
0205
0206
0207 using value_type = reference;
0208
0209
0210 using difference_type = iterator_difference_t< mp11::mp_front< IteratorTuple > >;
0211
0212
0213
0214 using traversal_category = detail::minimum_traversal_category_in_iterator_list_t< IteratorTuple >;
0215
0216 public:
0217
0218
0219 using type = iterator_facade<
0220 zip_iterator< IteratorTuple >,
0221 value_type,
0222 traversal_category,
0223 reference,
0224 difference_type
0225 >;
0226 };
0227
0228 template< typename Reference >
0229 struct converter
0230 {
0231 template< typename Seq >
0232 static Reference call(Seq seq)
0233 {
0234 using tag = typename fusion::traits::tag_of< Reference >::type;
0235 return fusion::convert< tag >(seq);
0236 }
0237 };
0238
0239 template< typename Reference1, typename Reference2 >
0240 struct converter< std::pair< Reference1, Reference2 > >
0241 {
0242 using reference = std::pair< Reference1, Reference2 >;
0243
0244 template< typename Seq >
0245 static reference call(Seq seq)
0246 {
0247 return reference(fusion::at_c< 0 >(seq), fusion::at_c< 1 >(seq));
0248 }
0249 };
0250
0251 }
0252
0253
0254
0255
0256
0257 template< typename IteratorTuple >
0258 class zip_iterator :
0259 public detail::zip_iterator_base< IteratorTuple >::type
0260 {
0261
0262 using super_t = typename detail::zip_iterator_base< IteratorTuple >::type;
0263
0264
0265 friend class iterator_core_access;
0266
0267 public:
0268
0269
0270
0271
0272 zip_iterator() = default;
0273
0274
0275 zip_iterator(IteratorTuple iterator_tuple) :
0276 m_iterator_tuple(iterator_tuple)
0277 {}
0278
0279
0280 template< typename OtherIteratorTuple, typename = enable_if_convertible_t< OtherIteratorTuple, IteratorTuple > >
0281 zip_iterator(zip_iterator< OtherIteratorTuple > const& other) :
0282 m_iterator_tuple(other.get_iterator_tuple())
0283 {}
0284
0285
0286 IteratorTuple const& get_iterator_tuple() const { return m_iterator_tuple; }
0287
0288 private:
0289
0290
0291
0292
0293
0294 typename super_t::reference dereference() const
0295 {
0296 using reference = typename super_t::reference;
0297 using gen = detail::converter< reference >;
0298 return gen::call(fusion::transform(get_iterator_tuple(), detail::dereference_iterator()));
0299 }
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311 template< typename OtherIteratorTuple >
0312 bool equal(zip_iterator< OtherIteratorTuple > const& other) const
0313 {
0314 return fusion::equal_to(get_iterator_tuple(), other.get_iterator_tuple());
0315 }
0316
0317
0318
0319 void advance(typename super_t::difference_type n)
0320 {
0321 fusion::for_each(m_iterator_tuple, detail::advance_iterator< typename super_t::difference_type >(n));
0322 }
0323
0324
0325
0326 void increment()
0327 {
0328 fusion::for_each(m_iterator_tuple, detail::increment_iterator());
0329 }
0330
0331
0332
0333 void decrement()
0334 {
0335 fusion::for_each(m_iterator_tuple, detail::decrement_iterator());
0336 }
0337
0338
0339 template< typename OtherIteratorTuple >
0340 typename super_t::difference_type distance_to(zip_iterator< OtherIteratorTuple > const& other) const
0341 {
0342 return fusion::at_c< 0 >(other.get_iterator_tuple()) - fusion::at_c< 0 >(this->get_iterator_tuple());
0343 }
0344
0345 private:
0346
0347
0348
0349
0350 IteratorTuple m_iterator_tuple;
0351 };
0352
0353
0354
0355 template< typename IteratorTuple >
0356 inline zip_iterator< IteratorTuple > make_zip_iterator(IteratorTuple t)
0357 {
0358 return zip_iterator< IteratorTuple >(t);
0359 }
0360
0361 }
0362
0363 using iterators::zip_iterator;
0364 using iterators::make_zip_iterator;
0365
0366 }
0367
0368 #endif