summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2016-12-09 13:45:32 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2016-12-09 13:45:32 +0000
commit12d4648dbc72f0261e8b515e85d9ad59ce6f61d4 (patch)
treec9e2cd98f0c9db370becfb2b4c0bda3368b28c04
parentBit messy and fiddly, but removes the template string length limit of (just u... (diff)
downloadlibadhocutil-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.h135
-rw-r--r--libadhocutil/unittests/testCompileTimeFormatter.cpp12
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...);
}
};
}