Boost logo

Boost Users :

Subject: [Boost-users] Help with split_iterator, iterator_range and strings
From: Jeffrey C. Jacobs (darklord_at_[hidden])
Date: 2008-10-22 12:50:03


I am trying to write an adaptor function that takes a string and a
list of character delimiters and populates an output iterator with the
result. Specifically, this is what I have:

using boost::algorithm::make_split_iterator;
using boost::algorithm::split_iterator;
using boost::iterator_range;
using boost::copy_range;
using boost::algorithm::is_any_of;
using boost::algorithm::token_finder;

template <typename E, typename T, typename A, typename D, typename OutIt>
inline OutIt split_and_copy(const std::basic_string<E, T, A> &source,
                            const D &delimeters,
                            OutIt out)
{
    typedef std::basic_string<E, T, A> mystring;
    typedef split_iterator<mystring::const_iterator> SplitIt;
    typedef iterator_range<mystring::const_iterator> RangeIt;
    const SplitIt b = make_split_iterator(source,
                                          token_finder(is_any_of(delimeters)));
    const SplitIt e;

    return std::transform(b, e, out, copy_range<mystring, RangeIt>);
}

This compiles but strikes me as a bit verbose. I mean, am I missing
something visa-vi the proper interaction of split_iterator,
iterator_range and the container they are splitting and making a range
of?

I believe since b is a split_iterator type, that *b is of type
iterator_range, is this not correct? The templates would be as I
listed for SplitIt and RangeIt, as I understand it. Now, originally I
was hoping there would be an automatic conversion back from
iterator_range to the ranged container, which would make a copy of the
elements in the range and stick them into a container of the original
type (in this case, string). Is there no conversion from
iterator_range<mystring::const_iterator> back to mystring? You see,
originally, I wanted to write:

std::copy(b, e, out);

But it seems there is no way around using std::transform with an
explicit conversion from RangeIt to mystring with copy_range. Or am I
wrong in that assumption? No, I don't want to use the split function
since I don't want to populate the whole container, just write my
entries to an output iterator; it's generic in that sense to allow for
ostream_iterator or back_inserters or whatever. Also, is there some
way to not have to explicitly provide the copy_range input type since
that type is already known to be the same type as *b and *e?

Thanks for any insight you might be able to offer!

Jeffrey

-- 
"Scan not a friend with a microscopic glass; you know his faults so
let his foibles pass." -- Victorian Proverb, likely Sir Frank Crisp,
1st Baronet of Bungay
~,-;`    The TimeHorse

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net