summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2018-08-31 00:22:18 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2018-08-31 00:22:18 +0100
commitb5b53699d96ed1bcbb46120611af4740fea673f7 (patch)
treea3f61c5760a1f9fd880ec314f486deec0ee62416
parentAdd constexpr functions for identifying char ranges (diff)
downloadlibadhocutil-b5b53699d96ed1bcbb46120611af4740fea673f7.tar.bz2
libadhocutil-b5b53699d96ed1bcbb46120611af4740fea673f7.tar.xz
libadhocutil-b5b53699d96ed1bcbb46120611af4740fea673f7.zip
Add basic support for setting the width/precision in the format string
-rw-r--r--libadhocutil/detail/compileTimeFormatters.h37
-rw-r--r--libadhocutil/unittests/testCompileTimeFormatter.cpp7
2 files changed, 44 insertions, 0 deletions
diff --git a/libadhocutil/detail/compileTimeFormatters.h b/libadhocutil/detail/compileTimeFormatters.h
index 8579f92..00ee852 100644
--- a/libadhocutil/detail/compileTimeFormatters.h
+++ b/libadhocutil/detail/compileTimeFormatters.h
@@ -4,6 +4,7 @@
#include "../compileTimeFormatter.h"
#include <boost/assert.hpp>
#include <iomanip>
+#include <type_traits>
namespace AdHoc {
#define BASICCONV(PARAMTYPE, OP, ...) \
@@ -92,6 +93,42 @@ namespace AdHoc {
StreamWriter::next(s, pn...);
}
};
+
+ ////
+ // Width/precision embedded in format string
+ // Limitted to 3 digits at the moment
+ template<const auto & S, auto L, auto pos, typename stream, auto n0, auto nn, auto ... sn>
+ struct StreamWriter<S, L, pos, stream, typename std::enable_if<ispositivedigit(n0) && !isdigit(nn)>::type, '%', n0, nn, sn...> {
+ template<typename ... Pn>
+ static inline void write(stream & s, const Pn & ... pn)
+ {
+ constexpr auto p = (n0 - '0');
+ s << std::setw(p) << std::setprecision(p);
+ StreamWriter<S, L, pos + 1, stream, void, '%', nn, sn...>::write(s, pn...);
+ }
+ };
+ template<const auto & S, auto L, auto pos, typename stream, auto n0, auto n1, auto nn, auto ... sn>
+ struct StreamWriter<S, L, pos, stream, typename std::enable_if<ispositivedigit(n0) && isdigit(n1) && !isdigit(nn)>::type, '%', n0, n1, nn, sn...> {
+ template<typename ... Pn>
+ static inline void write(stream & s, const Pn & ... pn)
+ {
+ constexpr auto p = ((n0 - '0') * 10) + (n1 - '0');
+ s << std::setw(p) << std::setprecision(p);
+ StreamWriter<S, L, pos + 2, stream, void, '%', nn, sn...>::write(s, pn...);
+ }
+ };
+ template<const auto & S, auto L, auto pos, typename stream, auto n0, auto n1, auto n2, auto nn, auto ... sn>
+ struct StreamWriter<S, L, pos, stream, typename std::enable_if<ispositivedigit(n0) && isdigit(n1) && isdigit(n2) && !isdigit(nn)>::type, '%', n0, n1, n2, nn, sn...> {
+ template<typename ... Pn>
+ static inline void write(stream & s, const Pn & ... pn)
+ {
+ constexpr auto p = ((n0 - '0') * 100) + ((n1 - '0') * 10) + (n2 - '0');
+ s << std::setw(p) << std::setprecision(p);
+ StreamWriter<S, L, pos + 3, stream, void, '%', nn, sn...>::write(s, pn...);
+ }
+ };
+ ////
+
StreamWriterT('.', '*') {
template<typename ... Pn>
static inline void write(stream & s, int l, const Pn & ... pn)
diff --git a/libadhocutil/unittests/testCompileTimeFormatter.cpp b/libadhocutil/unittests/testCompileTimeFormatter.cpp
index 2b9a796..138d5dc 100644
--- a/libadhocutil/unittests/testCompileTimeFormatter.cpp
+++ b/libadhocutil/unittests/testCompileTimeFormatter.cpp
@@ -329,11 +329,18 @@ GLIBC_FMT_TEST(s2, "in %s %s.", "string", "other");
GLIBC_FMT_TEST(s3, "in %.*s.", 3, "other");
GLIBC_FMT_TEST(s4, "in %.*s.", 5, "other");
GLIBC_FMT_TEST(s5, "in %.*s.", 7, "other");
+GLIBC_FMT_TEST(s35, "in %3s.", "other");
+GLIBC_FMT_TEST(s55, "in %5s.", "other");
+GLIBC_FMT_TEST(s115, "in %11s.", "other");
GLIBC_FMT_TEST(c1, "in %c.", 'b');
GLIBC_FMT_TEST(c2, "in %c.", 'B');
GLIBC_FMT_TEST(d1, "in %d.", 123);
+GLIBC_FMT_TEST(d01, "in %0d.", 123);
+GLIBC_FMT_TEST(d051, "in %05d.", 123);
+GLIBC_FMT_TEST(d0511, "in % 50d.", 123);
+GLIBC_FMT_TEST(d05121, "in %0510d.", 123);
GLIBC_FMT_TEST(d2, "in %d.", 123456);
GLIBC_FMT_TEST(d3, "in %hd.", (int16_t)-12345);
GLIBC_FMT_TEST(d4, "in %hhd.", (int8_t)-123);