diff options
| author | Dan Goodliffe <dan.goodliffe@octal.co.uk> | 2019-01-18 15:41:31 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2019-01-18 16:08:57 +0000 | 
| commit | 138b84c1efd1e3e7b82ff1d9a19b45a905d5a031 (patch) | |
| tree | e0f0d4af4b22fd8c04d0f34300a354c172ef77b6 | |
| parent | string_view plugin/factory (diff) | |
| download | libadhocutil-138b84c1efd1e3e7b82ff1d9a19b45a905d5a031.tar.bz2 libadhocutil-138b84c1efd1e3e7b82ff1d9a19b45a905d5a031.tar.xz libadhocutil-138b84c1efd1e3e7b82ff1d9a19b45a905d5a031.zip  | |
Literal operator based inline formatting
| -rw-r--r-- | libadhocutil/compileTimeFormatter.h | 44 | ||||
| -rw-r--r-- | libadhocutil/unittests/testCompileTimeFormatter.cpp | 14 | 
2 files changed, 45 insertions, 13 deletions
diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h index 5f0237e..6a932be 100644 --- a/libadhocutil/compileTimeFormatter.h +++ b/libadhocutil/compileTimeFormatter.h @@ -137,6 +137,11 @@ namespace AdHoc {  				std::basic_stringstream<char_type> s;  				return write(s, pn...).str();  			} +			template<typename ... Pn> +			inline auto operator()(const Pn & ... pn) const +			{ +				return get(pn...); +			}  			/**  			 * Write the result of formatting to the given stream. @@ -149,6 +154,11 @@ namespace AdHoc {  			{  				return Parser<stream, 0, Pn...>::run(s, pn...);  			} +			template<typename stream, typename ... Pn> +			inline stream & operator()(stream & s, const Pn & ... pn) const +			{ +				return write(s, pn...); +			}  		private:  			template<typename stream, auto pos, typename ... Pn> @@ -179,23 +189,31 @@ namespace AdHoc {  				}  			};  	}; + +	namespace literals { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template" +#endif +		template<typename T, T ... t> struct FMT +		{ +			static constexpr char __FMT[] = {t...}; +		}; +		template<typename T, T ... t> inline auto operator""_fmt() noexcept +		{ +			return AdHoc::Formatter<FMT<T, t...>::__FMT, sizeof...(t)>(); +		} +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +	}  }  #define AdHocFormatterTypedef(name, str, id) \ -	inline constexpr auto id = str; \ -	typedef ::AdHoc::Formatter<id> name +    inline constexpr auto id = str; \ +    typedef ::AdHoc::Formatter<id> name  #define AdHocFormatter(name, str) \ -	AdHocFormatterTypedef(name, str, MAKE_UNIQUE(name)) - -// As far as I know, only clang/llvm version 5+ can compile this -// so long as std=c++17 -#if __clang_major__ >= 5 && __cplusplus >= 201703 -#define scprintf(strmp, fmt, ...) \ -	([](decltype(strmp) & strm) -> auto & { \ -		static constexpr auto __FMT = fmt; \ -		return ::AdHoc::Formatter<__FMT>::write(strm, ##__VA_ARGS__); \ -	}(strmp)) -#endif +    AdHocFormatterTypedef(name, str, MAKE_UNIQUE(name))  #endif diff --git a/libadhocutil/unittests/testCompileTimeFormatter.cpp b/libadhocutil/unittests/testCompileTimeFormatter.cpp index 37d1947..65fbaa0 100644 --- a/libadhocutil/unittests/testCompileTimeFormatter.cpp +++ b/libadhocutil/unittests/testCompileTimeFormatter.cpp @@ -458,3 +458,17 @@ BOOST_AUTO_TEST_CASE(scprintf)  }  #endif +using namespace AdHoc::literals; + +BOOST_AUTO_TEST_CASE(user_defined_literal_fmt_get) +{ +	BOOST_CHECK_EQUAL("foo 42", "foo %?"_fmt(42)); +} + +BOOST_AUTO_TEST_CASE(user_defined_literal_fmt_write) +{ +	std::stringstream str; +	"foo %?"_fmt(str, 42); +	BOOST_CHECK_EQUAL("foo 42", str.str()); +} +  | 
