forked from OctaForge/libostd
use the '#' flag to expand values within range subformats
parent
cfcb35575a
commit
80ad58f079
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue