summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2020-03-28 13:52:28 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2020-03-28 13:52:28 +0000
commit7c9af89ffdb6ee575bd5406dd2404ecde13b9347 (patch)
tree21f36fef48d1f3da262bd3cbab6b7249006a8e58
parentC++ fixed string literal CTF (diff)
downloadlibadhocutil-7c9af89ffdb6ee575bd5406dd2404ecde13b9347.tar.bz2
libadhocutil-7c9af89ffdb6ee575bd5406dd2404ecde13b9347.tar.xz
libadhocutil-7c9af89ffdb6ee575bd5406dd2404ecde13b9347.zip
Add [s]cprintf functions
-rw-r--r--libadhocutil/compileTimeFormatter.h18
-rw-r--r--libadhocutil/unittests/testCompileTimeFormatter.cpp55
2 files changed, 64 insertions, 9 deletions
diff --git a/libadhocutil/compileTimeFormatter.h b/libadhocutil/compileTimeFormatter.h
index c3837fe..46b7ec9 100644
--- a/libadhocutil/compileTimeFormatter.h
+++ b/libadhocutil/compileTimeFormatter.h
@@ -277,6 +277,24 @@ namespace AdHoc {
#define AdHocFormatter(name, str) \
using name = LiteralFormatter<str>
+ template<const support::basic_fixed_string Str, typename ... Pn>
+ inline auto scprintf(const Pn & ... pn)
+ {
+ return FormatterDetail<Str, Str.size()>::get(pn...);
+ }
+
+ template<const support::basic_fixed_string Str, typename stream, typename ... Pn>
+ inline auto & scprintf(stream & strm, const Pn & ... pn)
+ {
+ return FormatterDetail<Str, Str.size()>::write(strm, pn...);
+ }
+
+ template<const support::basic_fixed_string Str, typename ... Pn>
+ inline auto & cprintf(const Pn & ... pn)
+ {
+ return scprintf<Str>(std::cout, pn...);
+ }
+
#else
// Classic pre-C++20 implementation
#include "unique.h"
diff --git a/libadhocutil/unittests/testCompileTimeFormatter.cpp b/libadhocutil/unittests/testCompileTimeFormatter.cpp
index 369b804..2109e01 100644
--- a/libadhocutil/unittests/testCompileTimeFormatter.cpp
+++ b/libadhocutil/unittests/testCompileTimeFormatter.cpp
@@ -446,15 +446,52 @@ BOOST_AUTO_TEST_CASE(smartptr)
smartptr_fmt::get(shrd);
}
-// This tests scprintf macro, which in turn requires compiler support
-#ifdef scprintf
-BOOST_AUTO_TEST_CASE(scprintf)
-{
- auto str = std::make_unique<std::stringstream>();
- auto & strret = scprintf(*str, "Some literal format string (%d, %c).", 0, 'f');
- BOOST_CHECK_EQUAL(str.get(), &strret); // We got back our original stream
- BOOST_CHECK_EQUAL(str->str(), "Some literal format string (0, f).");
- scprintf(*str, "Some literal format string, no args.");
+#ifdef __cpp_nontype_template_parameter_class
+BOOST_AUTO_TEST_CASE(literal_format_string)
+{
+ std::stringstream str;
+ LiteralFormatter<"literal format string %?.">::write(str, 42);
+ BOOST_CHECK_EQUAL("literal format string 42.", str.str());
+}
+
+BOOST_AUTO_TEST_CASE(cprintf_args)
+{
+ auto & strret = cprintf<"Some literal format string (%d, %c).">(0, 'f');
+ BOOST_CHECK_EQUAL(&std::cout, &strret);
+}
+
+BOOST_AUTO_TEST_CASE(scprintf_strm_args)
+{
+ std::stringstream str;
+ auto & strret = scprintf<"Some literal format string (%d, %c).">(str, 0, 'f');
+ BOOST_CHECK_EQUAL(&str, &strret);
+ BOOST_CHECK_EQUAL(str.str(), "Some literal format string (0, f).");
+}
+
+BOOST_AUTO_TEST_CASE(scprintf_get_args)
+{
+ auto stng = scprintf<"Some literal format string (%d, %c).">(0, 'f');
+ BOOST_CHECK_EQUAL(stng, "Some literal format string (0, f).");
+}
+
+BOOST_AUTO_TEST_CASE(cprintf_no_args)
+{
+ auto & strret = cprintf<"Some literal format string.">();
+ BOOST_CHECK_EQUAL(&std::cout, &strret);
+}
+
+BOOST_AUTO_TEST_CASE(scprintf_strm_no_args)
+{
+ std::stringstream str;
+ auto & strret = scprintf<"Some literal format string.">(str);
+ BOOST_CHECK_EQUAL(&str, &strret);
+ BOOST_CHECK_EQUAL(str.str(), "Some literal format string.");
+}
+
+BOOST_AUTO_TEST_CASE(scprintf_get_no_args)
+{
+ auto stng = scprintf<"Some literal format string.">();
+ BOOST_CHECK_EQUAL(stng, "Some literal format string.");
}
#endif