Boost logo

Boost :

Subject: Re: [boost] [Iterator] Zip iterator for back_insert_iterators?
From: Kris Rousey (krousey_at_[hidden])
Date: 2008-09-11 17:26:22


>
> Well, that's a very clever idea. It subverts the purpose of
> boost/detail/iterator.hpp which was intended to be not much more than a
> wrapper for std::iterator_traits to work around compiler/library
> implementation deficiencies, but something like that just might work.
> That said, the reference type is definitely wrong in your
> specialization; it should be the same as the type returned by
> dereferencing the back_insert_iterator (I think that might be the
> back_insert_iterator type itself, IIRC).
>
-- snip --
>
> Well, the *really* right way to go about it is to write a fix that's not
> specific to back_insert_iterator, but that works for all kinds of output
> iterators that are not also forward iterators. That would take a little
> thought to get right, but it would be a good project for you to take on.
>

Thanks for the catching the reference error. I did manage to get this
working, but only for back_insert_iterators. I did run into a few
troubles in the iterator_facade.hpp file. It seems that
back_insert_iterator doesn't offer a const dereference operator
member, and this caused issues in the dereference_iterator functor.
Changing it to cast away the const of the iterator made everything
work as expected. I don't like this solution, as it potentially
breaks a const contract for so many other use-cases. I went back and
changed it to only cast away the const if it had the
output_iterator_tag. This is slightly better in my opinion as I don't
see much use in a const output iterator. It still doesn't sit well
with me. Maybe after I'm less distracted by my day job, I can figure
out a better approach. I'm open to suggestions :) . I'll also look
into doing this generically, though I believe I'll just get into
enumerating the major output iterators (e.g. container inserter,
stream inserter, ...).

Here's the modified dereference_iterator functor. Feel free to rip into it:

    struct dereference_iterator
    {
      template<typename Iterator>
      struct apply
      {
        typedef typename
          iterator_traits<Iterator>::reference
        type;
      };

      template<typename Iterator>
      typename apply<Iterator>::type operator()(Iterator const& it)
      {
        typename iterator_traits<Iterator>::iterator_category category;
        return dereference_dispatch(it, category);
      }

      template<typename Iterator, typename IteratorCategory>
      typename apply<Iterator>::type dereference_dispatch(Iterator
const& it, IteratorCategory)
      { return *it; }

      template<typename Iterator>
      typename apply<Iterator>::type dereference_dispatch(Iterator
const& it, std::output_iterator_tag)
      { return *const_cast<Iterator&>(it); }
    };

Cheers,
Kris


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