diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-12-30 22:38:23 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-12-30 22:38:23 +0000 | 
| commit | 772bd173742753c1cc7b21ca79e20fab7f36abd3 (patch) | |
| tree | 08d8192e374d4a74d48b36838ed9f9462dcbeb92 | |
| parent | Use compile time formatter in place of boost::format where suitable and impro... (diff) | |
| download | libadhocutil-772bd173742753c1cc7b21ca79e20fab7f36abd3.tar.bz2 libadhocutil-772bd173742753c1cc7b21ca79e20fab7f36abd3.tar.xz libadhocutil-772bd173742753c1cc7b21ca79e20fab7f36abd3.zip  | |
Refactor to reduce AdHoc namespace polutionlibadhocutil-0.4.1
| -rw-r--r-- | libadhocutil/compileTimeFormatter.h | 198 | 
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) \  | 
