Merge write_fp into write
This commit is contained in:
parent
125fc5e520
commit
3e1f70fe02
@ -1,4 +1,4 @@
|
|||||||
// Formatting library for C++
|
// Formatting library for C++ - implementation
|
||||||
//
|
//
|
||||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
|
@ -1690,7 +1690,6 @@ template <typename Range> class basic_writer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructs a ``basic_writer`` object. */
|
|
||||||
explicit basic_writer(Range out,
|
explicit basic_writer(Range out,
|
||||||
internal::locale_ref loc = internal::locale_ref())
|
internal::locale_ref loc = internal::locale_ref())
|
||||||
: out_(out.begin()), locale_(loc) {}
|
: out_(out.begin()), locale_(loc) {}
|
||||||
@ -1743,86 +1742,8 @@ template <typename Range> class basic_writer {
|
|||||||
int_writer<T, Spec>(*this, value, spec));
|
int_writer<T, Spec>(*this, value, spec));
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(float value, const format_specs& specs = format_specs()) {
|
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
||||||
write_fp(value, specs);
|
void write(T value, const format_specs& specs = {}) {
|
||||||
}
|
|
||||||
|
|
||||||
void write(double value, const format_specs& specs = format_specs()) {
|
|
||||||
write_fp(value, specs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Formats *value* using the general format for floating-point numbers
|
|
||||||
(``'g'``) and writes it to the buffer.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
void write(long double value, const format_specs& specs = format_specs()) {
|
|
||||||
write_fp(value, specs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Formats a floating-point number (float, double, or long double).
|
|
||||||
template <typename T, bool USE_GRISU = internal::use_grisu<T>()>
|
|
||||||
void write_fp(T value, const format_specs& specs);
|
|
||||||
|
|
||||||
/** Writes a character to the buffer. */
|
|
||||||
void write(char value) {
|
|
||||||
auto&& it = reserve(1);
|
|
||||||
*it++ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char_type>::value)>
|
|
||||||
void write(Char value) {
|
|
||||||
auto&& it = reserve(1);
|
|
||||||
*it++ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Writes *value* to the buffer.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
void write(string_view value) {
|
|
||||||
auto&& it = reserve(value.size());
|
|
||||||
it = internal::copy_str<char_type>(value.begin(), value.end(), it);
|
|
||||||
}
|
|
||||||
void write(wstring_view value) {
|
|
||||||
static_assert(std::is_same<char_type, wchar_t>::value, "");
|
|
||||||
auto&& it = reserve(value.size());
|
|
||||||
it = std::copy(value.begin(), value.end(), it);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writes a formatted string.
|
|
||||||
template <typename Char>
|
|
||||||
void write(const Char* s, std::size_t size, const format_specs& specs) {
|
|
||||||
write_padded(specs, str_writer<Char>{s, size});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Char>
|
|
||||||
void write(basic_string_view<Char> s,
|
|
||||||
const format_specs& specs = format_specs()) {
|
|
||||||
const Char* data = s.data();
|
|
||||||
std::size_t size = s.size();
|
|
||||||
if (specs.precision >= 0 && internal::to_unsigned(specs.precision) < size)
|
|
||||||
size =
|
|
||||||
internal::code_point_index(s, internal::to_unsigned(specs.precision));
|
|
||||||
write(data, size, specs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename UIntPtr>
|
|
||||||
void write_pointer(UIntPtr value, const format_specs* specs) {
|
|
||||||
int num_digits = internal::count_digits<4>(value);
|
|
||||||
auto pw = pointer_writer<UIntPtr>{value, num_digits};
|
|
||||||
if (!specs) return pw(reserve(to_unsigned(num_digits) + 2));
|
|
||||||
format_specs specs_copy = *specs;
|
|
||||||
if (specs_copy.align == align::none) specs_copy.align = align::right;
|
|
||||||
write_padded(specs_copy, pw);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Range>
|
|
||||||
template <typename T, bool USE_GRISU>
|
|
||||||
void basic_writer<Range>::write_fp(T value, const format_specs& specs) {
|
|
||||||
auto sign = specs.sign;
|
auto sign = specs.sign;
|
||||||
if (std::signbit(value)) { // value < 0 is false for NaN so use signbit.
|
if (std::signbit(value)) { // value < 0 is false for NaN so use signbit.
|
||||||
sign = sign::minus;
|
sign = sign::minus;
|
||||||
@ -1849,9 +1770,10 @@ void basic_writer<Range>::write_fp(T value, const format_specs& specs) {
|
|||||||
if (fspec.format == float_format::fixed) options |= grisu_options::fixed;
|
if (fspec.format == float_format::fixed) options |= grisu_options::fixed;
|
||||||
if (const_check(sizeof(value) == sizeof(float)))
|
if (const_check(sizeof(value) == sizeof(float)))
|
||||||
options |= grisu_options::binary32;
|
options |= grisu_options::binary32;
|
||||||
bool use_grisu = USE_GRISU && (specs.type != 'a' && specs.type != 'A') &&
|
bool use_grisu = internal::use_grisu<T>() &&
|
||||||
grisu_format(static_cast<double>(value), buffer, num_digits,
|
(specs.type != 'a' && specs.type != 'A') &&
|
||||||
options, exp);
|
grisu_format(static_cast<double>(value), buffer,
|
||||||
|
num_digits, options, exp);
|
||||||
char* decimal_point_pos = nullptr;
|
char* decimal_point_pos = nullptr;
|
||||||
if (!use_grisu) decimal_point_pos = sprintf_format(value, buffer, specs);
|
if (!use_grisu) decimal_point_pos = sprintf_format(value, buffer, specs);
|
||||||
|
|
||||||
@ -1890,7 +1812,58 @@ void basic_writer<Range>::write_fp(T value, const format_specs& specs) {
|
|||||||
} else {
|
} else {
|
||||||
write_padded(as, double_writer{sign, buffer, decimal_point_pos, point});
|
write_padded(as, double_writer{sign, buffer, decimal_point_pos, point});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Writes a character to the buffer.
|
||||||
|
void write(char value) {
|
||||||
|
auto&& it = reserve(1);
|
||||||
|
*it++ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char_type>::value)>
|
||||||
|
void write(Char value) {
|
||||||
|
auto&& it = reserve(1);
|
||||||
|
*it++ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes value to the buffer.
|
||||||
|
void write(string_view value) {
|
||||||
|
auto&& it = reserve(value.size());
|
||||||
|
it = internal::copy_str<char_type>(value.begin(), value.end(), it);
|
||||||
|
}
|
||||||
|
void write(wstring_view value) {
|
||||||
|
static_assert(std::is_same<char_type, wchar_t>::value, "");
|
||||||
|
auto&& it = reserve(value.size());
|
||||||
|
it = std::copy(value.begin(), value.end(), it);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes a formatted string.
|
||||||
|
template <typename Char>
|
||||||
|
void write(const Char* s, std::size_t size, const format_specs& specs) {
|
||||||
|
write_padded(specs, str_writer<Char>{s, size});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
void write(basic_string_view<Char> s,
|
||||||
|
const format_specs& specs = format_specs()) {
|
||||||
|
const Char* data = s.data();
|
||||||
|
std::size_t size = s.size();
|
||||||
|
if (specs.precision >= 0 && internal::to_unsigned(specs.precision) < size)
|
||||||
|
size =
|
||||||
|
internal::code_point_index(s, internal::to_unsigned(specs.precision));
|
||||||
|
write(data, size, specs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename UIntPtr>
|
||||||
|
void write_pointer(UIntPtr value, const format_specs* specs) {
|
||||||
|
int num_digits = internal::count_digits<4>(value);
|
||||||
|
auto pw = pointer_writer<UIntPtr>{value, num_digits};
|
||||||
|
if (!specs) return pw(reserve(to_unsigned(num_digits) + 2));
|
||||||
|
format_specs specs_copy = *specs;
|
||||||
|
if (specs_copy.align == align::none) specs_copy.align = align::right;
|
||||||
|
write_padded(specs_copy, pw);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
using writer = basic_writer<buffer_range<char>>;
|
using writer = basic_writer<buffer_range<char>>;
|
||||||
|
|
||||||
@ -1983,7 +1956,7 @@ class arg_formatter_base {
|
|||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
||||||
iterator operator()(T value) {
|
iterator operator()(T value) {
|
||||||
writer_.write_fp(value, specs_ ? *specs_ : format_specs());
|
writer_.write(value, specs_ ? *specs_ : format_specs());
|
||||||
return out();
|
return out();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Formatting library for C++
|
// Formatting library for C++ - legacy printf implementation
|
||||||
//
|
//
|
||||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
|
@ -42,13 +42,6 @@ template <typename Char> struct small_grouping : std::numpunct<Char> {
|
|||||||
TEST(LocaleTest, DoubleDecimalPoint) {
|
TEST(LocaleTest, DoubleDecimalPoint) {
|
||||||
std::locale loc(std::locale(), new numpunct<char>());
|
std::locale loc(std::locale(), new numpunct<char>());
|
||||||
EXPECT_EQ("1?23", fmt::format(loc, "{:n}", 1.23));
|
EXPECT_EQ("1?23", fmt::format(loc, "{:n}", 1.23));
|
||||||
// Test with Grisu disabled.
|
|
||||||
fmt::memory_buffer buf;
|
|
||||||
fmt::internal::writer w(buf, fmt::internal::locale_ref(loc));
|
|
||||||
auto specs = fmt::format_specs();
|
|
||||||
specs.type = 'n';
|
|
||||||
w.write_fp<double, false>(1.23, specs);
|
|
||||||
EXPECT_EQ(fmt::to_string(buf), "1?23");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LocaleTest, Format) {
|
TEST(LocaleTest, Format) {
|
||||||
|
Loading…
Reference in New Issue
Block a user