So let me ask a question: how useful is this library in practice, beyond "toy examples"?
Was this library developed with a real application, i.e. use in a product, as its motivation, or was it written to test the limits of what is possible using metaprogramming? This library was generalised from the original version of a type-safe
Hi Phil, On 2015-06-03 00:18, Phil Endecott wrote: printf (after realising that a "real" parser makes things much simpler).
My first reaction to the library was "cool!". My second reaction was "it's a toy to demonstrate metaprogramming". Then I saw the printf() example and my third (and for now final!) though is that, yes, this could be useful. I see it as a tool to build library interfaces. Here is a (yet unfinished) attempt to build an Xpressive frontend for example:
https://github.com/istvans/mpllibs/blob/master/libs/xlxpressive/example/comp... (the link points to an example comparing the new frontend to the original interface, the library lives in a fork of Mpllibs and has the same structure as the rest of the Mpllibs libraries). you can write MPLLIBS_REGEX("....") and that gets validated at compile-time. Another usage area (not published and to the best of my knowledge slightly explored) is writing SQL libraries that are checked at compile-time but don't change the SQL syntax. A third usage area (again, I'm not aware of it being explored) is generating runtime parsers from grammars (something like metaparse::grammar, but building a runtime parser instead of a compile-time one).
In another thread, Peter Dimov asked about getting char packs from string literals. It seems to me that if we had that then we could implement printf() without needing a "parser library" at all:
template
class formatter { public: template void operator()(ARGS... args...) { std::cout << c1; formatter ()(args...); } }; template
class formatter<'%','d',c...> { public: template void operator()(int i, ARGS... args...) { std::cout << i; formatter ()(args...); } }; template <char c1> class formatter<c1> { public: void operator()() { std::cout << c1; } };
int main() { formatter<'h','e','l','l','o','%','d','!'>()(42); }
So maybe all that I really want is the preprocessor magic to turn string literals into something that's more useful at compile time. Or a language feature to do that.
Or maybe somehow constexpr can do it all for me. Anyone have a constexpr implementation of printf()? This approach to write a type-safe printf displays the characters one-by-one on an output stream. The printf library in Mpllibs does the validation at compile-time and calls the "unsafe" printf at runtime (and has therefore no runtime overhead).
This does not necessarily mean that it is not possible to build validation using a recursive (pattern matching) approach for printf. However, note that the printf grammar is a bit more complicated than the most commonly used %d, %f, etc. (see http://www.cplusplus.com/reference/cstdio/printf/ for example). When you decide to support the full syntax, then it quickly gets complex (and that is where grammars and parser generators become helpful). Regards, Ábel