From 48a6e1e59d758874b59fd34de95d0cabd147df4f Mon Sep 17 00:00:00 2001 From: q66 Date: Sat, 4 Jul 2015 14:52:02 +0100 Subject: [PATCH] formatting of associative arrays --- octa/format.hh | 42 +++++++++++++++++++++++++++++++++++++----- octa/string.hh | 25 ++++++++++++------------- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/octa/format.hh b/octa/format.hh index bfe30d5..e1467cd 100644 --- a/octa/format.hh +++ b/octa/format.hh @@ -13,6 +13,7 @@ #include "octa/algorithm.hh" #include "octa/string.hh" +#include "octa/utility.hh" namespace octa { @@ -383,6 +384,20 @@ namespace detail { template using FmtRangeTest = decltype(test_fmt_range(0)); + template + static inline octa::Ptrdiff format_ritem(R &writer, octa::Size &fmtn, + const char *fmt, + const A &...args) { + return format_impl(writer, fmtn, fmt, args...); + } + + template + static inline octa::Ptrdiff format_ritem(R &writer, octa::Size &fmtn, + const char *fmt, + const octa::Pair &pair) { + return format_impl(writer, fmtn, fmt, pair.first, pair.second); + } + template static inline octa::Ptrdiff write_range(R &writer, const FormatSpec *fl, @@ -398,7 +413,7 @@ namespace detail { octa::Ptrdiff ret = 0; octa::Size fmtn = 0; /* test first item */ - octa::Ptrdiff fret = format_impl(writer, fmtn, fl->rest(), + octa::Ptrdiff fret = format_ritem(writer, fmtn, fl->rest(), range.front()); if (fret < 0) return fret; ret += fret; @@ -409,7 +424,7 @@ namespace detail { if (v != seplen) return -1; ret += seplen; - fret = format_impl(writer, fmtn, fl->rest(), range.front()); + fret = format_ritem(writer, fmtn, fl->rest(), range.front()); if (fret < 0) return fret; ret += fret; } @@ -428,6 +443,14 @@ namespace detail { return -1; } + template())) + > static octa::True test_fmt_tostr(int); + template static octa::False test_fmt_tostr(...); + + template + using FmtTostrTest = decltype(test_fmt_tostr(0)); + struct WriteSpec: octa::FormatSpec { WriteSpec(): octa::FormatSpec() {} WriteSpec(const char *fmt): octa::FormatSpec(fmt) {} @@ -545,7 +568,7 @@ namespace detail { /* generic value */ template octa::Ptrdiff write(R &writer, const T &val, octa::EnableIf< - !octa::IsArithmetic::value, bool + !octa::IsArithmetic::value && FmtTostrTest::value, bool > = true) { if (this->spec != 's') { assert(false && "custom objects need '%s' format"); @@ -554,6 +577,15 @@ namespace detail { return write(writer, octa::to_string(val)); } + /* generic failure case */ + template + octa::Ptrdiff write(R &, const T &, octa::EnableIf< + !octa::IsArithmetic::value && !FmtTostrTest::value, bool + > = true) { + assert(false && "value cannot be formatted"); + return -1; + } + /* actual writer */ template octa::Ptrdiff write_arg(R &writer, octa::Size idx, const T &val) { @@ -693,8 +725,8 @@ namespace detail { } template - static inline octa::Ptrdiff format(R &writer, octa::Size &fmtn, - const char *fmt) { + static inline octa::Ptrdiff format_impl(R &writer, octa::Size &fmtn, + const char *fmt) { octa::Size written = 0; octa::detail::WriteSpec spec(fmt); if (spec.read_until_spec(writer, &written)) return -1; diff --git a/octa/string.hh b/octa/string.hh index 1b2c557..4f19ed5 100644 --- a/octa/string.hh +++ b/octa/string.hh @@ -452,9 +452,13 @@ template struct ToString { !octa::IsScalar::value, bool> = true ) { String ret("{"); - ret += concat(octa::iter(v), ", ", ToString>()); + ret += concat(octa::iter(v), ", ", ToString< + octa::RemoveCv< + octa::RemoveReference< + octa::RangeReference + > + > + >()); ret += "}"; return ret; } @@ -468,9 +472,7 @@ template struct ToString { } String operator()(const T &v) const { - return to_str - >>(v); + return to_str(v); } }; @@ -569,20 +571,17 @@ template struct ToString> { using Result = String; String operator()(const Argument &v) { String ret("{"); - ret += ToString>>() - (v.first); + ret += ToString()(v.first); ret += ", "; - ret += ToString>>() - (v.second); + ret += ToString()(v.second); ret += "}"; return ret; } }; -template +template()(octa::declval()))> String to_string(const T &v) { - return ToString>> - ()(v); + return ToString()(v); } template