EVOLUTION-MANAGER
Edit File: zip_iterator.hpp
// Copyright David Abrahams and Thomas Becker 2000-2006. // Copyright Kohei Takahashi 2012-2014. // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_ # define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_ #include <stddef.h> #include <boost/iterator/iterator_traits.hpp> #include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible #include <boost/iterator/iterator_categories.hpp> #include <boost/iterator/minimum_category.hpp> #include <utility> // for std::pair #include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility #include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_cv.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/fold.hpp> #include <boost/mpl/transform.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/algorithm/transformation/transform.hpp> #include <boost/fusion/sequence/convert.hpp> #include <boost/fusion/sequence/intrinsic/at_c.hpp> #include <boost/fusion/sequence/comparison/equal_to.hpp> #include <boost/fusion/support/tag_of_fwd.hpp> namespace boost { namespace iterators { // Zip iterator forward declaration for zip_iterator_base template<typename IteratorTuple> class zip_iterator; namespace detail { // Functors to be used with tuple algorithms // template<typename DiffType> class advance_iterator { public: advance_iterator(DiffType step) : m_step(step) {} template<typename Iterator> void operator()(Iterator& it) const { it += m_step; } private: DiffType m_step; }; // struct increment_iterator { template<typename Iterator> void operator()(Iterator& it) const { ++it; } }; // struct decrement_iterator { template<typename Iterator> void operator()(Iterator& it) const { --it; } }; // struct dereference_iterator { template<typename> struct result; template<typename This, typename Iterator> struct result<This(Iterator)> { typedef typename remove_cv<typename remove_reference<Iterator>::type>::type iterator; typedef typename iterator_reference<iterator>::type type; }; template<typename Iterator> typename result<dereference_iterator(Iterator)>::type operator()(Iterator const& it) const { return *it; } }; // Metafunction to obtain the type of the tuple whose element types // are the reference types of an iterator tuple. // template<typename IteratorTuple> struct tuple_of_references : mpl::transform< IteratorTuple, iterator_reference<mpl::_1> > { }; // Specialization for std::pair template<typename Iterator1, typename Iterator2> struct tuple_of_references<std::pair<Iterator1, Iterator2> > { typedef std::pair< typename iterator_reference<Iterator1>::type , typename iterator_reference<Iterator2>::type > type; }; // Metafunction to obtain the minimal traversal tag in a tuple // of iterators. // template<typename IteratorTuple> struct minimum_traversal_category_in_iterator_tuple { typedef typename mpl::transform< IteratorTuple , pure_traversal_tag<iterator_traversal<> > >::type tuple_of_traversal_tags; typedef typename mpl::fold< tuple_of_traversal_tags , random_access_traversal_tag , minimum_category<> >::type type; }; template<typename Iterator1, typename Iterator2> struct minimum_traversal_category_in_iterator_tuple<std::pair<Iterator1, Iterator2> > { typedef typename pure_traversal_tag< typename iterator_traversal<Iterator1>::type >::type iterator1_traversal; typedef typename pure_traversal_tag< typename iterator_traversal<Iterator2>::type >::type iterator2_traversal; typedef typename minimum_category< iterator1_traversal , typename minimum_category< iterator2_traversal , random_access_traversal_tag >::type >::type type; }; /////////////////////////////////////////////////////////////////// // // Class zip_iterator_base // // Builds and exposes the iterator facade type from which the zip // iterator will be derived. // template<typename IteratorTuple> struct zip_iterator_base { private: // Reference type is the type of the tuple obtained from the // iterators' reference types. typedef typename detail::tuple_of_references<IteratorTuple>::type reference; // Value type is the same as reference type. typedef reference value_type; // Difference type is the first iterator's difference type typedef typename iterator_difference< typename mpl::at_c<IteratorTuple, 0>::type >::type difference_type; // Traversal catetgory is the minimum traversal category in the // iterator tuple. typedef typename detail::minimum_traversal_category_in_iterator_tuple< IteratorTuple >::type traversal_category; public: // The iterator facade type from which the zip iterator will // be derived. typedef iterator_facade< zip_iterator<IteratorTuple>, value_type, traversal_category, reference, difference_type > type; }; template <> struct zip_iterator_base<int> { typedef int type; }; template <typename reference> struct converter { template <typename Seq> static reference call(Seq seq) { typedef typename fusion::traits::tag_of<reference>::type tag; return fusion::convert<tag>(seq); } }; template <typename Reference1, typename Reference2> struct converter<std::pair<Reference1, Reference2> > { typedef std::pair<Reference1, Reference2> reference; template <typename Seq> static reference call(Seq seq) { return reference( fusion::at_c<0>(seq) , fusion::at_c<1>(seq)); } }; } ///////////////////////////////////////////////////////////////////// // // zip_iterator class definition // template<typename IteratorTuple> class zip_iterator : public detail::zip_iterator_base<IteratorTuple>::type { // Typedef super_t as our base class. typedef typename detail::zip_iterator_base<IteratorTuple>::type super_t; // iterator_core_access is the iterator's best friend. friend class iterator_core_access; public: // Construction // ============ // Default constructor zip_iterator() { } // Constructor from iterator tuple zip_iterator(IteratorTuple iterator_tuple) : m_iterator_tuple(iterator_tuple) { } // Copy constructor template<typename OtherIteratorTuple> zip_iterator( const zip_iterator<OtherIteratorTuple>& other, typename enable_if_convertible< OtherIteratorTuple, IteratorTuple >::type* = 0 ) : m_iterator_tuple(other.get_iterator_tuple()) {} // Get method for the iterator tuple. const IteratorTuple& get_iterator_tuple() const { return m_iterator_tuple; } private: // Implementation of Iterator Operations // ===================================== // Dereferencing returns a tuple built from the dereferenced // iterators in the iterator tuple. typename super_t::reference dereference() const { typedef typename super_t::reference reference; typedef detail::converter<reference> gen; return gen::call(fusion::transform( get_iterator_tuple(), detail::dereference_iterator())); } // Two zip iterators are equal if all iterators in the iterator // tuple are equal. NOTE: It should be possible to implement this // as // // return get_iterator_tuple() == other.get_iterator_tuple(); // // but equality of tuples currently (7/2003) does not compile // under several compilers. No point in bringing in a bunch // of #ifdefs here. // template<typename OtherIteratorTuple> bool equal(const zip_iterator<OtherIteratorTuple>& other) const { return fusion::equal_to( get_iterator_tuple(), other.get_iterator_tuple()); } // Advancing a zip iterator means to advance all iterators in the // iterator tuple. void advance(typename super_t::difference_type n) { fusion::for_each( m_iterator_tuple, detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)); } // Incrementing a zip iterator means to increment all iterators in // the iterator tuple. void increment() { fusion::for_each( m_iterator_tuple, detail::increment_iterator()); } // Decrementing a zip iterator means to decrement all iterators in // the iterator tuple. void decrement() { fusion::for_each( m_iterator_tuple, detail::decrement_iterator()); } // Distance is calculated using the first iterator in the tuple. template<typename OtherIteratorTuple> typename super_t::difference_type distance_to( const zip_iterator<OtherIteratorTuple>& other ) const { return fusion::at_c<0>(other.get_iterator_tuple()) - fusion::at_c<0>(this->get_iterator_tuple()); } // Data Members // ============ // The iterator tuple. IteratorTuple m_iterator_tuple; }; // Make function for zip iterator // template<typename IteratorTuple> inline zip_iterator<IteratorTuple> make_zip_iterator(IteratorTuple t) { return zip_iterator<IteratorTuple>(t); } } // namespace iterators using iterators::zip_iterator; using iterators::make_zip_iterator; } // namespace boost #endif