Boost logo

Boost :

From: Neal D. Becker (nbecker_at_[hidden])
Date: 2002-03-19 15:53:36


>>>>> "Gennadiy" == Gennadiy Rozental <rogeeff_at_[hidden]> writes:

    Gennadiy> See Joining Iterator in vault area. (By the way where is it now?)
    Gennadiy> Gennadiy.

    Gennadiy> --- nbecker_at_[hidden] (Neal D. Becker) wrote:
>> Has anyone tried to make an iterator adaptor to concatenate two
>> iterators?
>>
>> I'm thinking about something that takes as args b1, e1, b2, where b1
>> is the beginning or range1, e1 is the end, and b2 is the beginning of
>> range2. Dereferencing would first iterate through [b1...e1) and then
>> [b2...)

Thanks for the pointer. Interesting. I think what the joining
iterator is doing is depending on a state variable to switch between 2
iterator ranges?

Not quite what I was looking for. I'm thinking something like this:
This will switch automatically. Probably only works for random_access.

#ifndef CAT_ITERATOR_HPP
#define CAT_ITERATOR_HPP

#include<boost/iterator_adaptors.hpp>

#include<utility>
#include<algorithm>

namespace boost {

  namespace detail{

    template<typename BaseIterator>
    class cat_iterator_policy : public default_iterator_policies {
      typedef boost::detail::iterator_traits<BaseIterator>::difference_type difference_type;
    public:
      // Constructors
      cat_iterator_policy (BaseIterator const& _b1, BaseIterator const& _e1, BaseIterator const& _b2) :
        b1 (_b1),
        e1 (_e1),
        b2 (_b2) {}

      template <class IteratorAdaptor>
      typename IteratorAdaptor::reference dereference(const IteratorAdaptor& x) const {
        // std::cerr << "d: " << x.base() - b1 << std::endl;
        if (x.base() - b1 >= e1 - b1)
          return *(b2 + (x.base() - e1));
        else
          return *(x.base());
      }

    private:
      const BaseIterator& b1;
      const BaseIterator& e1;
      const BaseIterator& b2;
    };
  } // namespace detail

  template<typename BaseIterator>
  struct cat_iterator_generator {
    typedef boost::iterator_adaptor<BaseIterator,detail::cat_iterator_policy<BaseIterator> > type;
  };

  template<typename BaseIterator>
  typename cat_iterator_generator<BaseIterator>::type
  make_cat_iterator(BaseIterator const& b1, BaseIterator const& e1, BaseIterator const& b2) {
    typedef typename cat_iterator_generator<BaseIterator>::type ret_type;

    return ret_type (b1, detail::cat_iterator_policy<BaseIterator> (b1, e1, b2));
  }

    

} // namespace boost

#endif


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk