Boost logo

Boost :

Subject: Re: [boost] Variadic append for std::string
From: Christof Donat (cd_at_[hidden])
Date: 2017-01-24 04:36:08


Hi,

Am 24.01.2017 10:07, schrieb Richard Hodges:
> For what it's worth, in my view join and/or concat should return a
> generator.
>
> To me the idiomatic way to convert it to a string would be and ADL
> function to_string(generator)
> -> std::string.

Then why not use the std::string constructor instead? That would be the
case with the implicit conversion:

auto generator = concat(...);
auto my_str = std::string{generator};

> The generator itself should be streamable to at least a basic_ostream
> via
> ADL operator<<

Yes, that looks like a good idea to me as well. The simple and straight
forward implementation (using the std::string constructor) might be:

auto operator << (std::basic_ostream<...>& stream, generator g)
-> std::basic_ostream<...>& {

}

> It seems to me that since c++17 is going to have string_view, and boost
> already does, then there should be a to_string_view free function to
> return
> the view of a temporary. The result will be that string construction is
> then only necessary when the user wants it.
>
>
> basic ADL interface something like this:
>
> #include <memory>
> #include <iostream>
> #include <string>
> #include <experimental/string_view>
>
> namespace boost {
> template<class Char, class Traits = std::char_traits<Char>, class
> Allocator = std::allocator<Char>>
> struct join_engine_type {
> // implementation of joiner here
> };
>
> template<class Char, class Traits, class Allocator>
> auto operator<<(std::basic_ostream<Char, Traits>& os,
> const join_engine_type<Char, Traits, Allocator>&
> eng)
> -> std::basic_ostream<Char, Traits>&
> {
> // impementation here
> return os;
> };
>
> template<class Char, class Traits, class Allocator>
> auto allocate_string(const join_engine_type<Char, Traits,
> Allocator>& eng)
> -> std::basic_string<Char, Traits, Allocator>&
> {
> // note that the allocator is copied, so if the joiner has a
> memory pool
> // allocator, the strings will share the memory pool
> // impementation here
> };
>
> template<class Char, class Traits, class Allocator>
> auto to_string(const join_engine_type<Char, Traits, Allocator>&
> eng)
> -> std::basic_string<Char, Traits>&
> {
> // note that the standard allocator is used. Strings are now
> independent.
> // impementation here
> };
>
> template<class Char, class Traits, class Allocator>
> auto to_string_view(const join_engine_type<Char, Traits,
> Allocator>& eng)
> -> std::experimental::basic_string_view<Char, Traits>&
> {
> // note that the standard allocator is used. Strings are now
> independent.
> // impementation here
> };
> }
>
> Furthermore, since the entire web is now (thankfully) UTF8, I strongly
> feel
> that there should be a utf8 version, which accepts wide and narrow
> strings
> and emits them correctly.
>
>
> On 24 January 2017 at 02:59, Jeff Garland <azswdude_at_[hidden]> wrote:
>
>> So let me just say that this is a bike shed topic -- I've been in the
>> shed
>> a decade ago on the subject -- but hey why not :) I dropped the
>> proposal
>> below bc it was clear to me that no agreement was possible on the
>> topic.
>> The proposal in isn't variadic because that feature didn't exist at
>> the
>> time, but you can see how it would be trivially changed to be -- why
>> it is
>> begging to be variadic. It brings together many of the discussed
>> libraries
>> format, string_algo, regex into an interface that is simple and clear.
>> It
>> allows for both formatting and appending. Extremely small sample
>>
>> super_string <http://www.crystalclearsoftware.com/
>> libraries/super_string/classbasic__super__string.html>
>> s(" (456789) [123] 2006-10-01 abcdef ");
>> s.to_upper();
>> cout << s << endl;
>>
>> s.trim(); //lop off the whitespace on both sides
>> cout << s << endl;
>>
>> double dbl = 1.23456;
>> s.append(dbl); //append any streamable type
>> s+= " ";
>> cout << s << endl;
>>
>> date d(2006, Jul, 1);
>> s.insert_at(28, d); //insert any streamable type
>> cout << s << endl;
>>
>>
>> super_string s;
>> double dbl = 1.123456789;
>> int i = 1000;
>> s.append_formatted
>> <http://www.crystalclearsoftware.com/libraries/super_string/
>> classbasic__super__string.html#67740abfd6224fab0402b3dd7076f216>(dbl,
>> i , dbl, i, "a string", "%-7.2f %-7d %-7.2f %-7d %s");
>> //s == "1.12 1000 1.12 1000 a string"
>>
>> //other overloadings available with less parameters
>> super_string s1;
>> s1.append_formatted
>> <http://www.crystalclearsoftware.com/libraries/super_string/
>> classbasic__super__string.html#67740abfd6224fab0402b3dd7076f216>(dbl,
>> "This is the value: %-7.2f");
>> //s1 == "This is the value: 1.12"
>>
>>
>> main page
>> http://www.crystalclearsoftware.com/libraries/super_string/index.html
>>
>> My justification for *why* I did this as a type against all the
>> *standard
>> judgement* of the c++ experts
>> http://www.crystalclearsoftware.com/libraries/super_string/index.
>> html#why_type
>>
>> My original post in 2006
>> http://lists.boost.org/Archives/boost/2006/07/107087.php
>>
>> Jeff
>>
>>
>>
>> On Mon, Jan 23, 2017 at 4:14 PM, Gavin Lambert <gavinl_at_[hidden]>
>> wrote:
>>
>> > On 24/01/2017 07:26, Olaf van der Spek wrote:
>> >
>> >> 1. scope for formatting tags:
>> >>>
>> >>> concat(format::hex<int>, 42, " is hex for ", concat(42)).str();
>> >>>
>> >>> Here the inner concat will convert the 42 to its decimal
>> representation,
>> >>> while the outer one converts the first 42 to its hex representation.
>> >>>
>> >>
>> >> Wouldn't concat(hex(42), " is hex for", 42) make more sense?
>> >>
>> >
>> > +1. If you like persistent formatting states (and all the unexpected fun
>> > they cause when you forget to cancel them), use iostreams instead.
>> >
>> > 3. results from concat() in a boost::range that is passed to join():
>> >>>
>> >>> join(separator("\n"),
>> >>> my_files | transformed([](const std::filesystem::path& f) -> auto
>> {
>> >>> return concat(f.filename, ": ",
>> >>> std::filesystem::file_size(f));
>> >>> })).str();
>> >>>
>> >>
>> > Maybe I missed something, but what was the intended distinction between
>> > concat() and join()?
>> >
>> > To me, as vocabulary words, concat() implies "concatenate without
>> > separator" and join() implies "concatenate with separator"; as such it
>> > seems unnecessary to explicitly decorate the separator here since it's a
>> > required parameter.
>> >
>> > (Both should accept either variadics or ranges, if that's not too
>> > complicated to arrange, though it's likely for join() to be used more
>> often
>> > on ranges; concat() might be more evenly split, though probably leaning
>> > toward variadics.)
>> >
>> > Although I suppose http://www.boost.org/doc/libs/
>> > 1_63_0/doc/html/string_algo/reference.html#header.boost.algo
>> > rithm.string.join_hpp and http://www.boost.org/doc/libs/
>> > 1_63_0/libs/range/doc/html/range/reference/utilities/join.html might not
>> > entirely agree on this vocabulary...
>> >
>> > (Loads the bikeshed on the back of a bike and rides away.)
>> >
>> > If "concat" is the outer layer anyway, I would return a std::string
>> >>>> directly for convenience. It is easy to forget the trailing .str() and
>> >>>> it does not look elegant.
>> >>>>
>> >>>
>> >>> Of course better proposals are welcome :-) Would you prefer the
>> implicit
>> >>> conversion? If so, why?
>> >>>
>> >>
>> >> Implicit is problematic with auto..
>> >>
>> >
>> > While that's true, I think the flexibility of returning a factory from
>> > concat() is more useful than the discomfort of either remembering the
>> str()
>> > or using std::string explicitly as the type instead of auto (or using
>> auto
>> > combined with explicit std::string construction).
>> >
>> >
>> >
>> >
>> > _______________________________________________
>> > Unsubscribe & other changes: http://lists.boost.org/mailman
>> > /listinfo.cgi/boost
>> >
>>
>> _______________________________________________
>> Unsubscribe & other changes: http://lists.boost.org/
>> mailman/listinfo.cgi/boost
>>
>
> _______________________________________________
> 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