1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-06-16 23:27:15 +02:00

Update fmt library.

This commit is contained in:
Sandu Liviu Catalin
2021-03-30 20:32:25 +03:00
parent 7a255f065f
commit eea5dd7743
12 changed files with 1875 additions and 1392 deletions

View File

@ -207,50 +207,32 @@ template <typename OutputIt, typename Char> class basic_printf_context;
*/
template <typename OutputIt, typename Char>
class printf_arg_formatter : public detail::arg_formatter_base<OutputIt, Char> {
public:
using iterator = OutputIt;
private:
using char_type = Char;
using base = detail::arg_formatter_base<OutputIt, Char>;
using context_type = basic_printf_context<OutputIt, Char>;
using format_specs = typename base::format_specs;
context_type& context_;
void write_null_pointer(char) {
this->specs()->type = 0;
this->write("(nil)");
}
void write_null_pointer(wchar_t) {
this->specs()->type = 0;
this->write(L"(nil)");
OutputIt write_null_pointer(bool is_string = false) {
auto s = this->specs();
s.type = 0;
return detail::write(this->out(),
string_view(is_string ? "(null)" : "(nil)"), s);
}
public:
using format_specs = typename base::format_specs;
printf_arg_formatter(OutputIt iter, format_specs& specs, context_type& ctx)
: base(iter, specs, detail::locale_ref()), context_(ctx) {}
/**
\rst
Constructs an argument formatter object.
*buffer* is a reference to the output buffer and *specs* contains format
specifier information for standard argument types.
\endrst
*/
printf_arg_formatter(iterator iter, format_specs& specs, context_type& ctx)
: base(iter, &specs, detail::locale_ref()), context_(ctx) {}
OutputIt operator()(monostate value) { return base::operator()(value); }
template <typename T, FMT_ENABLE_IF(fmt::detail::is_integral<T>::value)>
iterator operator()(T value) {
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if (std::is_same<T, bool>::value) {
format_specs& fmt_specs = *this->specs();
if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
fmt_specs.type = 0;
this->write(value != 0);
} else if (std::is_same<T, char_type>::value) {
format_specs& fmt_specs = *this->specs();
OutputIt operator()(T value) {
// MSVC2013 fails to compile separate overloads for bool and Char so use
// std::is_same instead.
if (std::is_same<T, Char>::value) {
format_specs fmt_specs = this->specs();
if (fmt_specs.type && fmt_specs.type != 'c')
return (*this)(static_cast<int>(value));
fmt_specs.sign = sign::none;
@ -260,56 +242,39 @@ class printf_arg_formatter : public detail::arg_formatter_base<OutputIt, Char> {
// ignored for non-numeric types
if (fmt_specs.align == align::none || fmt_specs.align == align::numeric)
fmt_specs.align = align::right;
return base::operator()(value);
} else {
return base::operator()(value);
return write_char(this->out(), static_cast<Char>(value), fmt_specs);
}
return this->out();
return base::operator()(value);
}
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
iterator operator()(T value) {
OutputIt operator()(T value) {
return base::operator()(value);
}
/** Formats a null-terminated C string. */
iterator operator()(const char* value) {
if (value)
base::operator()(value);
else if (this->specs()->type == 'p')
write_null_pointer(char_type());
else
this->write("(null)");
return this->out();
OutputIt operator()(const char* value) {
if (value) return base::operator()(value);
return write_null_pointer(this->specs().type != 'p');
}
/** Formats a null-terminated wide C string. */
iterator operator()(const wchar_t* value) {
if (value)
base::operator()(value);
else if (this->specs()->type == 'p')
write_null_pointer(char_type());
else
this->write(L"(null)");
return this->out();
OutputIt operator()(const wchar_t* value) {
if (value) return base::operator()(value);
return write_null_pointer(this->specs().type != 'p');
}
iterator operator()(basic_string_view<char_type> value) {
OutputIt operator()(basic_string_view<Char> value) {
return base::operator()(value);
}
iterator operator()(monostate value) { return base::operator()(value); }
/** Formats a pointer. */
iterator operator()(const void* value) {
if (value) return base::operator()(value);
this->specs()->type = 0;
write_null_pointer(char_type());
return this->out();
OutputIt operator()(const void* value) {
return value ? base::operator()(value) : write_null_pointer();
}
/** Formats an argument of a custom (user-defined) type. */
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
OutputIt operator()(typename basic_format_arg<context_type>::handle handle) {
handle.format(context_.parse_context(), context_);
return this->out();
}
@ -474,14 +439,19 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
const Char* end = parse_ctx_.end();
auto it = start;
while (it != end) {
if (!detail::find<false, Char>(it, end, '%', it)) {
it = end; // detail::find leaves it == nullptr if it doesn't find '%'
break;
}
char_type c = *it++;
if (c != '%') continue;
if (it != end && *it == c) {
out = std::copy(start, it, out);
out = detail::write(
out, basic_string_view<Char>(start, detail::to_unsigned(it - start)));
start = ++it;
continue;
}
out = std::copy(start, it - 1, out);
out = detail::write(out, basic_string_view<Char>(
start, detail::to_unsigned(it - 1 - start)));
format_specs specs;
specs.align = align::right;
@ -593,7 +563,8 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
// Format argument.
out = visit_format_arg(ArgFormatter(out, specs, *this), arg);
}
return std::copy(start, it, out);
return detail::write(
out, basic_string_view<Char>(start, detail::to_unsigned(it - start)));
}
template <typename Char>