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()); +} + |