summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libadhocutil/compileTimeFormatter.h198
1 files changed, 104 insertions, 94 deletions
diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h
index 7734f9c..4f980d2 100644
--- a/libadhocutil/compileTimeFormatter.h
+++ b/libadhocutil/compileTimeFormatter.h
@@ -7,51 +7,16 @@ namespace AdHoc {
/// @cond
constexpr int WRAP_AT = 120;
- template <int, char...> struct Buffer { };
-
- template <const char * const & S, int start, int offset, char ...>
- struct Upto {
- template<typename stream>
- static auto scan(stream &, const Buffer<start> & f)
- {
- return f;
- }
- };
- template <const char * const & S, int start, int offset, char s0, char... sn>
- struct Upto<S, start, offset, s0, sn...> {
- template<typename stream, int len, char... sm>
- static auto scan(stream & s, const Buffer<len, sm...> &)
- {
- return Upto<S, start, offset + 1, sn...>::scan(s, Buffer<len, sm..., s0>());
- }
- };
- template <const char * const & S, int start, char... sn>
- struct UptoWrite {
- template<typename stream, int len, char... sm>
- static auto scan(stream & s, const Buffer<len, sm...> &)
- {
- s.write(S + start, sizeof...(sm));
- return Buffer<sizeof...(sm), sn...>();
- }
- };
- template <const char * const & S, int start, int offset, char... sn>
- struct Upto<S, start, offset, '%', sn...> : public UptoWrite<S, start, '%', sn...> { };
- template <const char * const & S, int start, int offset, char... sn>
- struct Upto<S, start, offset, 0, sn...> : public UptoWrite<S, start, 0, sn...> { };
- template <const char * const & S, int start, char s0, char... sn>
- struct Upto<S, start, WRAP_AT, s0, sn...> : public UptoWrite<S, start, s0, sn...> { };
- template <const char * const & S, int start, char... sn>
- struct Upto<S, start, WRAP_AT, '%', sn...> : public UptoWrite<S, start, '%', sn...> { };
- template <const char * const & S, int start, char... sn>
- struct Upto<S, start, WRAP_AT, 0, sn...> : public UptoWrite<S, start, 0, sn...> { };
+ namespace FormatterImpl {
+ template <bool, char...> struct ParserBuffer { };
+ template <int, char...> struct Buffer { };
+ }
template <const char * const & S, int start, typename stream, char ... sn>
struct StreamWriter {
template<typename ... Pn>
- static void write(stream & s, const Pn & ... pn)
- {
- next(s, Upto<S, start, 0, sn...>::scan(s, Buffer<0>()), pn...);
- }
+ static void write(stream & s, const Pn & ... pn);
+
template<typename ... Pn, int len, char... ssn, template <int, char...> class Buffer>
static void next(stream & s, const Buffer<len, ssn...>&, const Pn & ... pn)
{
@@ -121,63 +86,99 @@ namespace AdHoc {
static int err;
};
- template <bool, char...> struct ParserBuffer { };
-
- template <const char * const & S, int offset, int roffset, char s0, char ... sn>
- struct Parser {
- static auto parse()
- {
- return append(innerparse());
- }
- static auto innerparse()
- {
- return Parser<S, offset + 1, roffset + 1, S[offset + 1], sn..., s0>::innerparse();
- }
- template<char...ssn>
- static auto append(const ParserBuffer<true, ssn...> & b)
- {
- return join(b, Parser<S, offset + 1 + WRAP_AT, 0, S[offset + 1 + WRAP_AT]>::parse());
- }
- template<char...ssn>
- static auto append(const ParserBuffer<false, ssn...> & b)
- {
- return b;
- }
- template<bool more, char...ssn, char...ssm>
- static auto join(const ParserBuffer<true, ssn...> &, const ParserBuffer<more, ssm...> &)
- {
- return ParserBuffer<more, ssn..., ssm...>();
- }
- };
-
- template <const char * const & S, bool more, char ... sn>
- struct ParserBase {
- static auto parse()
- {
- return innerparse();
- }
- static auto innerparse()
- {
- return ParserBuffer<more, sn...>();
- }
- };
-
- template <const char * const & S, int offset, char s0, char ... sn>
- struct Parser<S, offset, WRAP_AT, s0, sn...> : public ParserBase<S, true, sn..., s0> { };
-
- template <const char * const & S, int offset, char ... sn>
- struct Parser<S, offset, WRAP_AT, 0, sn...> : public ParserBase<S, true, sn..., 0> { };
-
- template <const char * const & S, int offset, int roffset, char ... sn>
- struct Parser<S, offset, roffset, 0, sn...> : public ParserBase<S, false, sn..., 0>{ };
- /// @endcond
-
/**
* Compile time string formatter.
* @param S the format string.
*/
template <const char * const & S>
class Formatter {
+ private:
+ template<const char * const &, int, typename, char ...> friend struct StreamWriter;
+
+ template <int start, int offset, char ...>
+ struct Upto {
+ template<typename stream>
+ static auto scan(stream &, const FormatterImpl::Buffer<start> & f)
+ {
+ return f;
+ }
+ };
+ template <int start, int offset, char s0, char... sn>
+ struct Upto<start, offset, s0, sn...> {
+ template<typename stream, int len, char... sm>
+ static auto scan(stream & s, const FormatterImpl::Buffer<len, sm...> &)
+ {
+ return Upto<start, offset + 1, sn...>::scan(s, FormatterImpl::Buffer<len, sm..., s0>());
+ }
+ };
+ template <int start, char... sn>
+ struct UptoWrite {
+ template<typename stream, int len, char... sm>
+ static auto scan(stream & s, const FormatterImpl::Buffer<len, sm...> &)
+ {
+ s.write(S + start, sizeof...(sm));
+ return FormatterImpl::Buffer<sizeof...(sm), sn...>();
+ }
+ };
+ template <int start, int offset, char... sn>
+ struct Upto<start, offset, '%', sn...> : public UptoWrite<start, '%', sn...> { };
+ template <int start, int offset, char... sn>
+ struct Upto<start, offset, 0, sn...> : public UptoWrite<start, 0, sn...> { };
+ template <int start, char s0, char... sn>
+ struct Upto<start, WRAP_AT, s0, sn...> : public UptoWrite<start, s0, sn...> { };
+ template <int start, char... sn>
+ struct Upto<start, WRAP_AT, '%', sn...> : public UptoWrite<start, '%', sn...> { };
+ template <int start, char... sn>
+ struct Upto<start, WRAP_AT, 0, sn...> : public UptoWrite<start, 0, sn...> { };
+
+ template <int offset, int roffset, char s0, char ... sn>
+ struct Parser {
+ static auto parse()
+ {
+ return append(innerparse());
+ }
+ static auto innerparse()
+ {
+ return Parser<offset + 1, roffset + 1, S[offset + 1], sn..., s0>::innerparse();
+ }
+ template<char...ssn>
+ static auto append(const FormatterImpl::ParserBuffer<true, ssn...> & b)
+ {
+ return join(b, Parser<offset + 1 + WRAP_AT, 0, S[offset + 1 + WRAP_AT]>::parse());
+ }
+ template<char...ssn>
+ static auto append(const FormatterImpl::ParserBuffer<false, ssn...> & b)
+ {
+ return b;
+ }
+ template<bool more, char...ssn, char...ssm>
+ static auto join(const FormatterImpl::ParserBuffer<true, ssn...> &, const FormatterImpl::ParserBuffer<more, ssm...> &)
+ {
+ return FormatterImpl::ParserBuffer<more, ssn..., ssm...>();
+ }
+ };
+
+ template <bool more, char ... sn>
+ struct ParserBase {
+ static auto parse()
+ {
+ return innerparse();
+ }
+ static auto innerparse()
+ {
+ return FormatterImpl::ParserBuffer<more, sn...>();
+ }
+ };
+
+ template <int offset, char s0, char ... sn>
+ struct Parser<offset, WRAP_AT, s0, sn...> : public ParserBase<true, sn..., s0> { };
+
+ template <int offset, char ... sn>
+ struct Parser<offset, WRAP_AT, 0, sn...> : public ParserBase<true, sn..., 0> { };
+
+ template <int offset, int roffset, char ... sn>
+ struct Parser<offset, roffset, 0, sn...> : public ParserBase<false, sn..., 0>{ };
+
public:
/**
* Get a string containing the result of formatting.
@@ -188,7 +189,7 @@ namespace AdHoc {
static std::string get(const Pn & ... pn)
{
std::stringstream s;
- return run(Parser<S, 0, 0, *S>::parse(), s, pn...).str();
+ return run(Parser<0, 0, *S>::parse(), s, pn...).str();
}
/**
@@ -200,7 +201,7 @@ namespace AdHoc {
template<typename stream, typename ... Pn>
static stream & write(stream & s, const Pn & ... pn)
{
- return run(Parser<S, 0, 0, *S>::parse(), s, pn...);
+ return run(Parser<0, 0, *S>::parse(), s, pn...);
}
private:
@@ -211,6 +212,15 @@ namespace AdHoc {
return s;
}
};
+
+ /// @cond
+ template <const char * const & S, int start, typename stream, char ... sn>
+ template<typename ... Pn>
+ void StreamWriter<S, start, stream, sn...>::write(stream & s, const Pn & ... pn)
+ {
+ next(s, Formatter<S>::template Upto<start, 0, sn...>::scan(s, FormatterImpl::Buffer<0>()), pn...);
+ }
+ /// @endcond
}
#define AdHocFormatterTypedef(name, str, id) \