From 8d84ec6d1c40ed2769556c3642bd4fa785c1905c Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 17 Jun 2018 14:01:38 +0100 Subject: Massively simplified CTF with C++17 constexpr --- libadhocutil/compileTimeFormatter.h | 194 +++++++++--------------------------- 1 file changed, 48 insertions(+), 146 deletions(-) diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h index d55012e..4b268f7 100644 --- a/libadhocutil/compileTimeFormatter.h +++ b/libadhocutil/compileTimeFormatter.h @@ -34,61 +34,35 @@ namespace AdHoc { return off; } - /// @cond - inline constexpr int WRAP_AT = 120; + template class Formatter; - namespace FormatterImpl { - template struct ParserBuffer { }; - template struct Buffer { }; - } - - template + template struct StreamWriter { - template - static void write(stream & s, const Pn & ... pn); - - template class Buffer> - static void next(stream & s, const Buffer&, const Pn & ... pn) - { - StreamWriter::write(s, pn...); - } - }; - - template - struct StreamWriter { - template - static void write(stream &, const Pn & ...) { } }; - template - struct StreamWriter { - template - static void write(stream &, const Pn & ...) { } - }; - - template + template struct StreamWriterBase { template - static void next(stream & s, const Pn & ... pn) + static inline void next(stream & s, const Pn & ... pn) { - StreamWriter::write(s, pn...); + Formatter::template Parser::run(s, pn...); } }; #define StreamWriterT(C...) \ - template \ - struct StreamWriter : \ - public StreamWriterBase + template \ + struct StreamWriter : \ + public StreamWriterBase #define StreamWriterTP(P, C...) \ - template \ - struct StreamWriter : \ - public StreamWriterBase + template \ + struct StreamWriter : \ + public StreamWriterBase // Default stream writer formatter StreamWriterT('?') { template - static void write(stream & s, const P & p, const Pn & ... pn) + static inline void write(stream & s, const P & p, const Pn & ... pn) { s << p; StreamWriter::next(s, pn...); @@ -98,7 +72,7 @@ namespace AdHoc { // Escaped % stream writer formatter StreamWriterT('%') { template - static void write(stream & s, const Pn & ... pn) + static inline void write(stream & s, const Pn & ... pn) { s << '%'; StreamWriter::next(s, pn...); @@ -106,8 +80,8 @@ namespace AdHoc { }; // Unknown stream writer formatter - template - struct StreamWriter { + template + struct StreamWriter { template static void write(stream &, const Pn & ...) { @@ -120,94 +94,10 @@ namespace AdHoc { * Compile time string formatter. * @param S the format string. */ - template + template ()> class Formatter { private: - template friend struct StreamWriter; - - template - struct Upto { - template - static auto scan(stream &, const FormatterImpl::Buffer & f) - { - return f; - } - }; - template - struct Upto { - template - static auto scan(stream & s, const FormatterImpl::Buffer &) - { - return Upto::scan(s, FormatterImpl::Buffer()); - } - }; - template - struct UptoWrite { - template - static auto scan(stream & s, const FormatterImpl::Buffer &) - { - s.write(S + start, sizeof...(sm)); - return FormatterImpl::Buffer(); - } - }; - template - struct Upto : public UptoWrite { }; - template - struct Upto : public UptoWrite { }; - template - struct Upto : public UptoWrite { }; - template - struct Upto : public UptoWrite { }; - template - struct Upto : public UptoWrite { }; - - template - struct Parser { - static auto parse() - { - return append(innerparse()); - } - static auto innerparse() - { - return Parser::innerparse(); - } - template - static auto append(const FormatterImpl::ParserBuffer & b) - { - return join(b, Parser::parse()); - } - template - static auto append(const FormatterImpl::ParserBuffer & b) - { - return b; - } - template - static auto join(const FormatterImpl::ParserBuffer &, const FormatterImpl::ParserBuffer &) - { - return FormatterImpl::ParserBuffer(); - } - }; - - template - struct ParserBase { - static auto parse() - { - return innerparse(); - } - static auto innerparse() - { - return FormatterImpl::ParserBuffer(); - } - }; - - template - struct Parser : public ParserBase { }; - - template - struct Parser : public ParserBase { }; - - template - struct Parser : public ParserBase{ }; + template friend struct StreamWriterBase; public: /** @@ -216,10 +106,10 @@ namespace AdHoc { * @return the formatted string. */ template - static std::string get(const Pn & ... pn) + static inline std::string get(const Pn & ... pn) { std::stringstream s; - return run(Parser<0, 0, *S>::parse(), s, pn...).str(); + return write(s, pn...).str(); } /** @@ -229,28 +119,40 @@ namespace AdHoc { * @return the stream. */ template - static stream & write(stream & s, const Pn & ... pn) + static inline stream & write(stream & s, const Pn & ... pn) { - return run(Parser<0, 0, *S>::parse(), s, pn...); + return Parser::run(s, pn...); } private: - template class ParserBuffer, typename ... Pn> - static stream & run(const ParserBuffer &, stream & s, const Pn & ... pn) - { - StreamWriter::write(s, pn...); - return s; - } + template + struct Parser { + static inline stream & + run(stream & s, const Pn & ... pn) + { + if (pos != L) { + constexpr int ph = strchrnul(); + if constexpr (ph != pos) { + s.write((S + pos), ph - pos); + } + if constexpr (ph != L) { + packAndWrite(s, pn...); + } + } + return s; + } + template + static inline void packAndWrite(stream & s, const Pn & ... pn) + { + if constexpr (ph + off == L || sizeof...(Pck) == 32) { + StreamWriter::write(s, pn...); + } + else if constexpr (ph + off < L) { + packAndWrite(s, pn...); + } + } + }; }; - - /// @cond - template - template - void StreamWriter::write(stream & s, const Pn & ... pn) - { - next(s, Formatter::template Upto::scan(s, FormatterImpl::Buffer<0>()), pn...); - } - /// @endcond } #define AdHocFormatterTypedef(name, str, id) \ -- cgit v1.2.3