|
Boost : |
Subject: Re: [boost] Variadic append for std::string
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2017-01-25 12:37:27
> The string factories, of course need more than only begin() and end().
They also have to provide a way to estimate the size of the output, because
we want to be able to allocate the complete buffer upfront. In the naive
implementation I called that size().
If you have size(), it means you know the size because the conversion work
has already been done. If you know the size, then the iterators returned by
begin() and end() can be of category std::random_access_tag, in which case
std::distance(begin(), end()) is both trivial and yields the size.
This is a long way of saying that if you have size(), you cant have the
simpler initial option of using forward_only iterators.
The practical fallout of this is that either the filter objects will have
to separate the concerns of size computation and formatting (they are very
much related), or the filter objects will have to carry some mutable state,
even when const (this is done, for example in google protocol buffers). The
latter options makes them a little less flexible.
Whether all this is worth it in terms of the performance gain of being able
to pre-compute size and therefore avoid un-necessary memory allocations...
I don't know. I think on balance it might.
On 25 January 2017 at 18:19, Christof Donat <cd_at_[hidden]> wrote:
> Hi,
>
> Am 24.01.2017 14:00, schrieb Richard Hodges:
>
>> It's almost looking like conversion to utf8, wide strings, strings or
>> string_views should be a filter rather than an option.
>>
>
> A filter always needs an input encoding and an output encoding. If we want
> to have filters to chose the output encoding between UTF-8, Latin 1, etc.
> what is going to be the input encoding?
>
> Note that I am still resisting the idea of .str() as a member function. If
>> the joiner or concatenation object exports begin() and end(), it's
>> un-necessary, because the object returned by create_string() (or similar)
>> can use the iterators.
>>
>
> I like that idea, though I still don't like the name to_string().
>
> How about this:
>
> auto s = generate<std::sting>(concat(...));
> auto ws = generate<std::wsting>(concat(...));
>
> generate<std::sting>(s, concat(...)); // returns reference to s for
> consistency
>
> auto v = generate<std::vector<int>>(any_other_range); // actually will
> just copy
>
> A very naive Implementation might look like this:
>
> template<typename ReturnT, typename Sequence>
> auto generate(ReturnT& r, Sequence& seq) -> ReturnT& {
> std::copy(std::begin(seq), std::end(seq), std::begin(r));
> return r;
> }
> template<typename ReturnT, typename Sequence>
> auto generate(Sequence& seq) -> ReturnT {
> ReturnT r{seq.size()};
> generate(r, seq);
> return r;
> }
>
> The word "generate" is very generic, therefore I'm still not really happy
> with it.
>
> The string factories, of course need more than only begin() and end().
> They also have to provide a way to estimate the size of the output, because
> we want to be able to allocate the complete buffer upfront. In the naive
> implementation I called that size().
>
> Having iterators also means that the attributed factory can be used as a
>> source in std::copy, std::transform, std::for_each etc.
>>
>
> .. and in range expressions :-)
>
>
> Christof
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman
> /listinfo.cgi/boost
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk