summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan.goodliffe@octal.co.uk>2019-01-18 15:41:31 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2019-01-18 16:08:57 +0000
commit138b84c1efd1e3e7b82ff1d9a19b45a905d5a031 (patch)
treee0f0d4af4b22fd8c04d0f34300a354c172ef77b6
parentstring_view plugin/factory (diff)
downloadlibadhocutil-138b84c1efd1e3e7b82ff1d9a19b45a905d5a031.tar.bz2
libadhocutil-138b84c1efd1e3e7b82ff1d9a19b45a905d5a031.tar.xz
libadhocutil-138b84c1efd1e3e7b82ff1d9a19b45a905d5a031.zip
Literal operator based inline formatting
-rw-r--r--libadhocutil/compileTimeFormatter.h44
-rw-r--r--libadhocutil/unittests/testCompileTimeFormatter.cpp14
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());
+}
+