use the '#' flag to expand values within range subformats

master
Daniel Kolesa 2015-07-10 00:49:07 +01:00
parent cfcb35575a
commit 80ad58f079
2 changed files with 35 additions and 17 deletions

View File

@ -261,7 +261,8 @@ protected:
} }
bool read_spec_range() { bool read_spec_range() {
p_nested_escape = !(p_flags & FMT_FLAG_DASH); int sflags = p_flags;
p_nested_escape = !(sflags & FMT_FLAG_DASH);
++p_fmt; ++p_fmt;
const char *begin_inner = p_fmt; const char *begin_inner = p_fmt;
if (!read_until_dummy()) { if (!read_until_dummy()) {
@ -274,6 +275,7 @@ protected:
curfmt = p_fmt; curfmt = p_fmt;
} }
p_fmt = curfmt; p_fmt = curfmt;
p_flags = sflags;
/* find delimiter or ending */ /* find delimiter or ending */
const char *begin_delim = p_fmt; const char *begin_delim = p_fmt;
const char *p = strchr(begin_delim, '%'); const char *p = strchr(begin_delim, '%');
@ -459,21 +461,28 @@ namespace detail {
template<typename R, typename T> template<typename R, typename T>
static inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc, static inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc,
const char *fmt, const T &item) { bool, const char *fmt,
const T &item) {
return format_impl(writer, fmtn, esc, fmt, item); return format_impl(writer, fmtn, esc, fmt, item);
} }
template<typename R, typename T, typename U> template<typename R, typename T, typename U>
static inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc, static inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc,
bool expandval,
const char *fmt, const char *fmt,
const Pair<T, U> &pair) { const Pair<T, U> &pair) {
return format_impl(writer, fmtn, esc, fmt, pair.first, pair.second); if (expandval) {
return format_impl(writer, fmtn, esc, fmt, pair.first,
pair.second);
}
return format_impl(writer, fmtn, esc, fmt, pair);
} }
template<typename R, typename T> template<typename R, typename T>
static inline Ptrdiff write_range(R &writer, const FormatSpec *fl, static inline Ptrdiff write_range(R &writer, const FormatSpec *fl,
bool escape, const char *sep, bool escape, bool expandval,
Size seplen, const T &val, const char *sep, Size seplen,
const T &val,
EnableIf<FmtRangeTest<T>::value, EnableIf<FmtRangeTest<T>::value,
bool> = true) { bool> = true) {
auto range = octa::iter(val); auto range = octa::iter(val);
@ -481,8 +490,8 @@ namespace detail {
Ptrdiff ret = 0; Ptrdiff ret = 0;
Size fmtn = 0; Size fmtn = 0;
/* test first item */ /* test first item */
Ptrdiff fret = format_ritem(writer, fmtn, escape, fl->rest(), Ptrdiff fret = format_ritem(writer, fmtn, escape, expandval,
range.front()); fl->rest(), range.front());
if (fret < 0) return fret; if (fret < 0) return fret;
ret += fret; ret += fret;
range.pop_front(); range.pop_front();
@ -492,8 +501,8 @@ namespace detail {
if (v != seplen) if (v != seplen)
return -1; return -1;
ret += seplen; ret += seplen;
fret = format_ritem(writer, fmtn, escape, fl->rest(), fret = format_ritem(writer, fmtn, escape, expandval,
range.front()); fl->rest(), range.front());
if (fret < 0) return fret; if (fret < 0) return fret;
ret += fret; ret += fret;
} }
@ -501,7 +510,7 @@ namespace detail {
} }
template<typename R, typename T> template<typename R, typename T>
static inline Ptrdiff write_range(R &, const FormatSpec *, bool, static inline Ptrdiff write_range(R &, const FormatSpec *, bool, bool,
const char *, Size, const T &, const char *, Size, const T &,
EnableIf<!FmtRangeTest<T>::value, EnableIf<!FmtRangeTest<T>::value,
bool> = true) { bool> = true) {
@ -775,22 +784,26 @@ namespace detail {
/* range writer */ /* range writer */
template<typename R, typename T> template<typename R, typename T>
Ptrdiff write_range(R &writer, Size idx, const char *sep, Ptrdiff write_range(R &writer, Size idx, bool expandval,
Size seplen, const T &val) { const char *sep, Size seplen, const T &val) {
if (idx) { if (idx) {
assert(false && "not enough format args"); assert(false && "not enough format args");
return -1; return -1;
} }
return detail::write_range(writer, this, this->p_nested_escape, return detail::write_range(writer, this, this->p_nested_escape,
sep, seplen, val); expandval, sep, seplen, val);
} }
template<typename R, typename T, typename ...A> template<typename R, typename T, typename ...A>
Ptrdiff write_range(R &writer, Size idx, const char *sep, Ptrdiff write_range(R &writer, Size idx, bool expandval,
Size seplen, const T &val, const A &...args) { const char *sep, Size seplen, const T &val,
if (idx) return write_range(writer, idx - 1, sep, seplen, args...); const A &...args) {
if (idx) {
return write_range(writer, idx - 1, expandval, sep,
seplen, args...);
}
return detail::write_range(writer, this, return detail::write_range(writer, this,
this->p_nested_escape, sep, seplen, val); this->p_nested_escape, expandval, sep, seplen, val);
} }
}; };
@ -811,6 +824,7 @@ namespace detail {
new_fmt[spec.nested_len()] = '\0'; new_fmt[spec.nested_len()] = '\0';
detail::WriteSpec nspec(new_fmt, spec.nested_escape()); detail::WriteSpec nspec(new_fmt, spec.nested_escape());
Ptrdiff sw = nspec.write_range(writer, argpos - 1, Ptrdiff sw = nspec.write_range(writer, argpos - 1,
(spec.flags() & FMT_FLAG_HASH),
spec.nested_sep(), spec.nested_sep_len(), args...); spec.nested_sep(), spec.nested_sep_len(), args...);
if (sw < 0) return sw; if (sw < 0) return sw;
written += sw; written += sw;

View File

@ -577,6 +577,10 @@ template<typename T, typename U> struct ToString<Pair<T, U>> {
} }
}; };
template<typename T> struct ToString<const T>: ToString<T> {};
template<typename T> struct ToString<volatile T>: ToString<T> {};
template<typename T> struct ToString<const volatile T>: ToString<T> {};
template<typename T, typename = decltype(ToString<T>()(declval<T>()))> template<typename T, typename = decltype(ToString<T>()(declval<T>()))>
String to_string(const T &v) { String to_string(const T &v) {
return ToString<T>()(v); return ToString<T>()(v);