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