Boost logo

Boost :

Subject: Re: [boost] Variadic append for std::string
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2017-01-24 04:07:58


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.

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

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
>


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