diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-12-09 13:45:32 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-12-09 13:45:32 +0000 |
commit | 12d4648dbc72f0261e8b515e85d9ad59ce6f61d4 (patch) | |
tree | c9e2cd98f0c9db370becfb2b4c0bda3368b28c04 | |
parent | Bit messy and fiddly, but removes the template string length limit of (just u... (diff) | |
download | libadhocutil-12d4648dbc72f0261e8b515e85d9ad59ce6f61d4.tar.bz2 libadhocutil-12d4648dbc72f0261e8b515e85d9ad59ce6f61d4.tar.xz libadhocutil-12d4648dbc72f0261e8b515e85d9ad59ce6f61d4.zip |
Pass format string as template argument into writer to avoid copying out bytes from stream write
-rw-r--r-- | libadhocutil/compileTimeFormatter.h | 135 | ||||
-rw-r--r-- | libadhocutil/unittests/testCompileTimeFormatter.cpp | 12 |
2 files changed, 71 insertions, 76 deletions
diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h index 1e82956..1a09bb1 100644 --- a/libadhocutil/compileTimeFormatter.h +++ b/libadhocutil/compileTimeFormatter.h @@ -5,115 +5,110 @@ namespace AdHoc { constexpr int WRAP_AT = 120; - template <bool, char...> struct Buffer { }; + template <bool, int, char...> struct Buffer { }; - template <char stop, int offset, char ...> + template <const char * const & S, char stop, int start, int offset, char ...> struct Upto { template<typename stream> - static auto stuff(stream &, const Buffer<false> & f) + static auto stuff(stream &, const Buffer<false, start> & f) { return f; } }; - template <char stop, int offset, char s0, char... sn> - struct Upto<stop, offset, s0, sn...> { - template<typename stream, char... sm> - static auto stuff(stream & s, const Buffer<false, sm...> &) + template <const char * const & S, char stop, int start, int offset, char s0, char... sn> + struct Upto<S, stop, start, offset, s0, sn...> { + template<typename stream, int len, char... sm> + static auto stuff(stream & s, const Buffer<false, len, sm...> &) { - return Upto<stop, offset + 1, sn...>::stuff(s, Buffer<false, sm..., s0>()); + return Upto<S, stop, start, offset + 1, sn...>::stuff(s, Buffer<false, len, sm..., s0>()); } }; - template <char stop, int offset, char... sn> - struct Upto<stop, offset, stop, sn...> { - template<typename stream, char... sm> - static auto stuff(stream & s, const Buffer<false, sm...> &) + template <const char * const & S, char stop, int start, int offset, char... sn> + struct Upto<S, stop, start, offset, stop, sn...> { + template<typename stream, int len, char... sm> + static auto stuff(stream & s, const Buffer<false, len, sm...> &) { - char buf[] = {sm...}; - s.write(buf, sizeof...(sm)); - return Buffer<false, stop, sn...>(); + s.write(S + start, sizeof...(sm)); + return Buffer<false, sizeof...(sm), stop, sn...>(); } }; - template <char stop, int offset, char... sn> - struct Upto<stop, offset, 0, sn...> { - template<typename stream, char... sm> - static auto stuff(stream & s, const Buffer<false, sm...> &) + template <const char * const & S, char stop, int start, int offset, char... sn> + struct Upto<S, stop, start, offset, 0, sn...> { + template<typename stream, int len, char... sm> + static auto stuff(stream & s, const Buffer<false, len, sm...> &) { - char buf[] = {sm...}; - s.write(buf, sizeof...(sm)); - return Buffer<false, 0, sn...>(); + s.write(S + start, sizeof...(sm)); + return Buffer<false, sizeof...(sm), 0, sn...>(); } }; - template <char stop, char s0, char... sn> - struct Upto<stop, WRAP_AT, s0, sn...> { - template<typename stream, char... sm> - static auto stuff(stream & s, const Buffer<false, sm...> &) + template <const char * const & S, char stop, int start, char s0, char... sn> + struct Upto<S, stop, start, WRAP_AT, s0, sn...> { + template<typename stream, int len, char... sm> + static auto stuff(stream & s, const Buffer<false, len, sm...> &) { - char buf[] = {sm...}; - s.write(buf, sizeof...(sm)); - return Buffer<false, s0, sn...>(); + s.write(S + start, sizeof...(sm)); + return Buffer<false, sizeof...(sm), s0, sn...>(); } }; - template <char stop, char... sn> - struct Upto<stop, WRAP_AT, stop, sn...> { - template<typename stream, char... sm> - static auto stuff(stream & s, const Buffer<false, sm...> &) + template <const char * const & S, char stop, int start, char... sn> + struct Upto<S, stop, start, WRAP_AT, stop, sn...> { + template<typename stream, int len, char... sm> + static auto stuff(stream & s, const Buffer<false, len, sm...> &) { - char buf[] = {sm...}; - s.write(buf, sizeof...(sm)); - return Buffer<false, stop, sn...>(); + s.write(S + start, sizeof...(sm)); + return Buffer<false, sizeof...(sm), stop, sn...>(); } }; - template <char stop, char... sn> - struct Upto<stop, WRAP_AT, 0, sn...> { - template<typename stream, char... sm> - static auto stuff(stream & s, const Buffer<false, sm...> &) + template <const char * const & S, char stop, int start, char... sn> + struct Upto<S, stop, start, WRAP_AT, 0, sn...> { + template<typename stream, int len, char... sm> + static auto stuff(stream & s, const Buffer<false, len, sm...> &) { - char buf[] = {sm...}; - s.write(buf, sizeof...(sm)); - return Buffer<false, 0, sn...>(); + s.write(S + start, sizeof...(sm)); + return Buffer<false, sizeof...(sm), 0, sn...>(); } }; - template <typename stream, char ... sn> + 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<'%', 0, sn...>::stuff(s, Buffer<false>()), pn...); + next(s, Upto<S, '%', start, 0, sn...>::stuff(s, Buffer<false, 0>()), pn...); } - template<typename ... Pn, char... ssn, template <bool, char...> class Buffer> - static void next(stream & s, const Buffer<false, ssn...>&, const Pn & ... pn) + template<typename ... Pn, int len, char... ssn, template <bool, int, char...> class Buffer> + static void next(stream & s, const Buffer<false, len, ssn...>&, const Pn & ... pn) { - StreamWriter<stream, ssn...>::write(s, pn...); + StreamWriter<S, start + len, stream, ssn...>::write(s, pn...); } }; - template<typename stream> - struct StreamWriter<stream> { + template<const char * const & S, int start, typename stream> + struct StreamWriter<S, start, stream> { template<typename ... Pn> static void write(stream &, const Pn & ...) { } }; - template<typename stream> - struct StreamWriter<stream, 0> { + template<const char * const & S, int start, typename stream> + struct StreamWriter<S, start, stream, 0> { template<typename ... Pn> static void write(stream &, const Pn & ...) { } }; // Default stream writer formatter - template<typename stream, char ... sn> - struct StreamWriter<stream, '%', '?', sn...> { + template<const char * const & S, int start, typename stream, char ... sn> + struct StreamWriter<S, start, stream, '%', '?', sn...> { template<typename P, typename ... Pn> static void write(stream & s, const P & p, const Pn & ... pn) { s << p; - StreamWriter<stream, sn...>::write(s, pn...); + StreamWriter<S, start + 2, stream, sn...>::write(s, pn...); } }; // Unknown stream writer formatter - template<typename stream, char ... sn> - struct StreamWriter<stream, '%', sn...> { + template<const char * const & S, int start, typename stream, char ... sn> + struct StreamWriter<S, start, stream, '%', sn...> { template<typename ... Pn> static void write(stream &, const Pn & ...) { @@ -133,19 +128,19 @@ namespace AdHoc { return Parser<S, offset + 1, roffset + 1, S[offset + 1], sn..., s0>::innerparse(); } template<char...ssn> - static auto append(const Buffer<true, ssn...> & b) + static auto append(const Buffer<true, 0, 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 Buffer<false, ssn...> & b) + static auto append(const Buffer<false, 0, ssn...> & b) { return b; } template<bool more, char...ssn, char...ssm> - static auto join(const Buffer<true, ssn...> &, const Buffer<more, ssm...> &) + static auto join(const Buffer<true, 0, ssn...> &, const Buffer<more, 0, ssm...> &) { - return Buffer<more, ssn..., ssm...>(); + return Buffer<more, 0, ssn..., ssm...>(); } }; @@ -153,11 +148,11 @@ namespace AdHoc { struct Parser<S, offset, WRAP_AT, s0, sn...> { static auto parse() { - return Buffer<true, sn..., s0>(); + return Buffer<true, 0, sn..., s0>(); } static auto innerparse() { - return Buffer<true, sn..., s0>(); + return Buffer<true, 0, sn..., s0>(); } }; @@ -165,11 +160,11 @@ namespace AdHoc { struct Parser<S, offset, WRAP_AT, 0, sn...> { static auto parse() { - return Buffer<false, sn...>(); + return Buffer<false, 0, sn...>(); } static auto innerparse() { - return Buffer<false, sn...>(); + return Buffer<false, 0, sn...>(); } }; @@ -177,11 +172,11 @@ namespace AdHoc { struct Parser<S, offset, roffset, 0, sn...> { static auto parse() { - return Buffer<false, sn..., 0>(); + return Buffer<false, 0, sn..., 0>(); } static auto innerparse() { - return Buffer<false, sn..., 0>(); + return Buffer<false, 0, sn..., 0>(); } }; @@ -193,10 +188,10 @@ namespace AdHoc { run(Parser<S, 0, 0, *S>::parse(), s, pn...); } - template<typename stream, char...ssn, template<bool, char...> class Buffer, typename ... Pn> - static void run(const Buffer<false, ssn...> &, stream & s, const Pn & ... pn) + template<typename stream, char...ssn, template<bool, int, char...> class Buffer, typename ... Pn> + static void run(const Buffer<false, 0, ssn...> &, stream & s, const Pn & ... pn) { - StreamWriter<stream, ssn...>::write(s, pn...); + StreamWriter<S, 0, stream, ssn...>::write(s, pn...); } }; } diff --git a/libadhocutil/unittests/testCompileTimeFormatter.cpp b/libadhocutil/unittests/testCompileTimeFormatter.cpp index 00f1e6f..ffb528b 100644 --- a/libadhocutil/unittests/testCompileTimeFormatter.cpp +++ b/libadhocutil/unittests/testCompileTimeFormatter.cpp @@ -90,19 +90,19 @@ BOOST_AUTO_TEST_CASE ( multi ) namespace AdHoc { // Custom stream writer formatter, formats as (bracketed expression) - template<typename stream, char ... sn> - struct StreamWriter<stream, '%', '(', ')', sn...> { + template<const char * const & S, int start, typename stream, char ... sn> + struct StreamWriter<S, start, stream, '%', '(', ')', sn...> { template<typename P, typename ... Pn> static void write(stream & s, const P & p, const Pn & ... pn) { s << "-( " << p << " )-"; - StreamWriter<stream, sn...>::write(s, pn...); + StreamWriter<S, start + 3, stream, sn...>::write(s, pn...); } }; // Custom stream writer formatter, formats // right-aligned by given width - template<typename stream, char ... sn> - struct StreamWriter<stream, '%', 'r', 'a', sn...> { + template<const char * const & S, int start, typename stream, char ... sn> + struct StreamWriter<S, start, stream, '%', 'r', 'a', sn...> { template<typename P, typename ... Pn> static void write(stream & s, int width, const P & p, const Pn & ... pn) { @@ -110,7 +110,7 @@ namespace AdHoc { buf << p; std::string spaces(width - buf.str().length(), ' '); s << spaces << buf.str(); - StreamWriter<stream, sn...>::write(s, pn...); + StreamWriter<S, start + 3, stream, sn...>::write(s, pn...); } }; } |