Boost logo

Boost :

Subject: Re: [boost] Stringify
From: Roberto Hinz (robhz786_at_[hidden])
Date: 2017-01-13 08:22:37


On Thu, Jan 12, 2017 at 4:52 PM, Olaf van der Spek <ml_at_[hidden]> wrote:

> On Wed, Jan 11, 2017 at 8:03 PM, Roberto Hinz <robhz786_at_[hidden]> wrote:
>
> > On Wed, Jan 11, 2017 at 3:40 PM, Roberto Hinz <robhz786_at_[hidden]>
> wrote:
> >
> > >
> > > Hi,
> > >
> > > I've been working in a format library that contains a function template
> > > called appendf that can do this:
> > >
> > > std::string str("blabla");
> > > boost::stringify::appendf(str) () (" AAA ", 25, " BBB ", {255, "x"});
> > > assert(str == "blabla AAA 25 BBB ff"); // ( 255 formated in
> > > hexadecimal )
> > >
> > > This library - I call it Boost.Stringify - is in very early stage of
> > > development and I though it would be to premature to mention it now.
> But
> > > given the repercussion in this thread so far, I changed my mind. So I
> > will
> > > soon publish it in github and I will start to write a brief
> documentation
> > > so that I can soon present here to gauge interest.
> >
>
> Hi,
>
> I think your library deserves it's own thread. ;)
> How does it compare to for example fmtlib?
>
> Gr,
>
> Olaf
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman
> /listinfo.cgi/boost
>

Hi Olaf,

this is a c++14, header-only, locale insensitive, format library.
I have for a long time redesigned it over and over again, until
I finally believe it conciliates well performance, extensibility,
customizability, and usability.

Source at: https://github.com/robhz786/stringify

Note: Many code snippets bellow don' t work yet.

== Basic usage ===

  boost::stringify::writef(output) (formatting_facets...) (intput_args...);
  boost::stringify::assignf(std_string_output) (formatting_facets...)
(intput_args...);
  boost::stringify::appendf(std_string_output) (formatting_facets...)
(intput_args...);
  auto str = boost::stringify::make_string (formatting_facets...)
(intput_args...);

Unfortunatelly, there is limit on the number input arguments in the above
form,
because it can´t be done with variadic templates.
But you can also use the initializer-list form, which has no such limit:

  boost::stringify::writef (output) (facets ...) [{ input_args ..}].

== supported outputs types ==

 - already: raw strings and std::basic_string
 - todo: FILE* and std::basic_streambuf

Note: when writing do std::string, the total amount of characters is
calculated in
advance in order to update the string capacity before writing. So that at
most only
one memory allocation is necessary.

== supported input types ==

 - currently : int, string and char. And with format option
 - todo: bool, void*, floating-point, and perhaps others

== formatting ==

Boost.Stringify does not a use a formatting string like printf,
Boost.Format or fmtlib.
An argument can be formatted in form {argument, {formating-arguments...}}

sample 1:
  auto s = boost::stringify::make_string() ("aaa", {"bbb", 5}, {"ccc",
{"<", 5"}});
  assert(s == "aaa bbbccc ");

sample 2:
  auto s = boost::stringify::make_string() (255, "zzz", {255, {"#xC<", 6}},
"zzz");
  assert(s == "255zzz0XFF zzz");

What type of formatting parameters to pass depends on the input argument.

== facets and ftuples ==

However, some formatting, like numeric punctuation and numeric digits
can only be customized instead with formatting facets.

facets can also be used to specify, for instance, that strings
shall be justified by default to the left, and integer to the right.
Or that long long should by default have width equal to 20, while
long should have width of 15.

Hence, facets are mostly used to formatting options that the user
would usually want reuse, while argument formatting is for the
things that he would often change most.

You can group facets into a ftuple. This resembles std::locale, with the
difference that ftuples solves everything at compilation time.
And two ftuples can be merged.

Some usage examples:
https://github.com/robhz786/stringify/blob/master/test/ftuple_test.cpp

== utf8 friendly ==

In others format libraries the width is simply the length.
In Boost.Stringify the user can define his own algorithm.
So width could be the number of unicode codepoints, or
could be something more sophisticated.

Also, fill, punctuation and others are specified as char32_t,
instead of a single char, so that it will be converted to utf8
( or to whatever encoding the user prefers ).

I also plan to support convertion from one encoding to other.
Windows development rules you to use wide strings,
and other environmets want narrow strings.
Boost.Stringify could aliviate such non-uniformity:

    #ifdef _WIN32
      typedef std::wstring mystring;
      typedef wchar_t mychar;
    #else
      typedef std::string mystring;
      typedef char mychar;
    #endif

    namespace strf = boost::stringify;
    auto fmt = strf::make_ftuple(strf::fill(U'~'), strf::width(6));

    mychar buff[80];
    strf::writef(buff) (fmt) ("aaa", u"bbb", U"ccc", L"ddd");

    mystring str;
    strf::assignf(str) (fmt) ("aaa", u"bbb", U"ccc", L"ddd");

The above code works in both Windows and Unix.

== fully extensible ==

The user can extend both input and output types

When extending input types, the user decides formatting options
specific to this new type, and he can create new formatting facets.

Actually, from the implementation point of view, there is no difference
between user-defined types and already supported types. There is
no "build-in" supported types. If, for instance, integers weren't
supported, the user could fully implement it by himself.

== performance ==

Good execution performance but bad compilation performance.
I want to provide more details about that later.

Well, any interest ?

Best regards
Roberto


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