From: João Abecasis (jpabecasis_at_[hidden])
Date: 2006-03-22 12:45:14
Eric Niebler wrote:
> João Abecasis wrote:
>>>> Also what is the rationale for singling out std::basic_string (and
>>>> Char const *) instead of going for the more general Range concept?
>>> Very off-topic here, but I'm just following the TR1 regex spec. Besides,
>>> in the future, Range won't cover Char const *. A Range-based interface
>>> might make for a nice extension to TR1, though.
>> For Spirit, the situation is the same. To circumvent this, I'm locally
>> extending the Range concept to include istreams, fstreams and, when
>> Range drops support for those, string literals.
>> To this end, there's an extensible as_range<T> class template that is
>> specialized to offer automatic conversion of T to a real range. Working
>> code is available through the link above.
>> What do you think of this?
> I think it sounds interesting, but Xpressive requires bidirectional
> iterators. I doubt your range adaptors for istream and fstream produce
> bidirectional ranges, do they?
No, they don't. istream and fstream become Readable, Single Pass Ranges
(Input Ranges?), through the use of istreambuf_iterator, an Input
Iterator itself. The idea of the as_range utility is to produce a Range
(any range) with minimal effort.
Input Iterators don't meet the requirements for Spirit either, which
requires Forward Iterators. Here another utility comes into play,
as_forward_iterator, which later on wraps Input Iterators with the
multi_pass adaptor. I suppose multi_pass could be extended to provide a
bidirectional adaptor. Caching the begin iterator would already get us
half the way.
My point was not the specific details of how we deal with istream and
fstream, anyway. What makes sense for Spirit, may or may not make as
much for Xpressive. For Spirit parsing a file or std::cin directly are
common enough, I guess.
So far, the one issue I've seen with this approach comes from Input
Iterators, because reading from them destroys the input sequence. So,
even though we can wrap the iterators for internal use, the user needs
to be aware of this and be given access to the wrapper so he doesn't
lose any unmatched input.