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...);  		}  	};  }  | 
