On Thu, Jan 12, 2017 at 4:52 PM, Olaf van der Spek
On Wed, Jan 11, 2017 at 8:03 PM, Roberto Hinz
wrote: On Wed, Jan 11, 2017 at 3:40 PM, Roberto Hinz
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