mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Don't use stringstream
This commit is contained in:
@ -17,7 +17,6 @@
|
|||||||
#include <cstring> // std::memmove
|
#include <cstring> // std::memmove
|
||||||
#include <cwchar>
|
#include <cwchar>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
# include <locale>
|
# include <locale>
|
||||||
@ -119,20 +118,18 @@ template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_FUNC auto write_int(unsigned long long value, const format_specs& specs,
|
FMT_FUNC auto write_int(appender out, unsigned long long value,
|
||||||
locale_ref loc) -> std::string {
|
const format_specs& specs, locale_ref loc) -> bool {
|
||||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
auto locale = loc.get<std::locale>();
|
auto locale = loc.get<std::locale>();
|
||||||
// We cannot use the num_put<char> facet because it may produce output in
|
// We cannot use the num_put<char> facet because it may produce output in
|
||||||
// a wrong encoding.
|
// a wrong encoding.
|
||||||
if (!std::has_facet<num_format_facet<std::locale>>(locale)) return {};
|
if (!std::has_facet<num_format_facet<std::locale>>(locale)) return {};
|
||||||
auto&& buf = std::basic_stringbuf<char>();
|
|
||||||
auto out = std::ostreambuf_iterator<char>(&buf);
|
|
||||||
std::use_facet<num_format_facet<std::locale>>(locale).put(out, value, specs,
|
std::use_facet<num_format_facet<std::locale>>(locale).put(out, value, specs,
|
||||||
locale);
|
locale);
|
||||||
return buf.str();
|
return true;
|
||||||
#endif
|
#endif
|
||||||
return {};
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
@ -2014,33 +2014,35 @@ auto write_int(OutputIt out, UInt value, unsigned prefix,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_API auto write_int(unsigned long long value, const format_specs& specs,
|
FMT_API auto write_int(appender out, unsigned long long value,
|
||||||
locale_ref loc) -> std::string;
|
const format_specs& specs, locale_ref loc) -> bool;
|
||||||
template <typename Char>
|
template <typename OutputIt, typename Char>
|
||||||
inline auto write_int(unsigned long long, const basic_format_specs<Char>&,
|
inline auto write_int(OutputIt, unsigned long long,
|
||||||
locale_ref) -> std::string {
|
const basic_format_specs<Char>&, locale_ref) -> bool {
|
||||||
return {};
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIt, typename UInt, typename Char>
|
template <typename OutputIt, typename UInt, typename Char>
|
||||||
auto write_int(OutputIt& out, UInt value, unsigned prefix,
|
auto write_int(OutputIt& out, UInt value, unsigned prefix,
|
||||||
const basic_format_specs<Char>& specs, locale_ref loc) -> bool {
|
const basic_format_specs<Char>& specs, locale_ref loc) -> bool {
|
||||||
auto str = std::string();
|
auto result = false;
|
||||||
|
auto buf = memory_buffer();
|
||||||
if (sizeof(value) <= sizeof(unsigned long long))
|
if (sizeof(value) <= sizeof(unsigned long long))
|
||||||
str = write_int(static_cast<unsigned long long>(value), specs, loc);
|
result = write_int(appender(buf), static_cast<unsigned long long>(value),
|
||||||
if (str.empty()) {
|
specs, loc);
|
||||||
|
if (!result) {
|
||||||
auto grouping = digit_grouping<Char>(loc);
|
auto grouping = digit_grouping<Char>(loc);
|
||||||
out = write_int(out, value, prefix, specs, grouping);
|
out = write_int(out, value, prefix, specs, grouping);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
size_t size = to_unsigned((prefix != 0 ? 1 : 0) + str.size());
|
size_t size = to_unsigned((prefix != 0 ? 1 : 0) + buf.size());
|
||||||
out = write_padded<align::right>(
|
out = write_padded<align::right>(
|
||||||
out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
|
out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
|
||||||
if (prefix != 0) {
|
if (prefix != 0) {
|
||||||
char sign = static_cast<char>(prefix);
|
char sign = static_cast<char>(prefix);
|
||||||
*it++ = static_cast<Char>(sign);
|
*it++ = static_cast<Char>(sign);
|
||||||
}
|
}
|
||||||
return copy_str<Char>(str.data(), str.data() + str.size(), it);
|
return copy_str<Char>(buf.data(), buf.data() + buf.size(), it);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4180,17 +4182,14 @@ template <typename Locale> class num_format_facet : public Locale::facet {
|
|||||||
public:
|
public:
|
||||||
static FMT_API typename Locale::id id;
|
static FMT_API typename Locale::id id;
|
||||||
|
|
||||||
using iter_type = std::ostreambuf_iterator<char>;
|
void put(appender out, unsigned long long val, const format_specs& specs,
|
||||||
|
Locale& loc) const {
|
||||||
auto put(iter_type out, unsigned long long val, const format_specs& specs,
|
do_put(out, val, specs, loc);
|
||||||
Locale& loc) const -> iter_type {
|
|
||||||
return do_put(out, val, specs, loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual auto do_put(iter_type out, unsigned long long val,
|
virtual void do_put(appender out, unsigned long long val,
|
||||||
const format_specs& specs, Locale& loc) const
|
const format_specs& specs, Locale& loc) const = 0;
|
||||||
-> iter_type = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if FMT_USE_USER_DEFINED_LITERALS
|
#if FMT_USE_USER_DEFINED_LITERALS
|
||||||
|
@ -522,20 +522,18 @@ TEST(locale_test, sign) {
|
|||||||
|
|
||||||
class num_format : public fmt::num_format_facet<std::locale> {
|
class num_format : public fmt::num_format_facet<std::locale> {
|
||||||
protected:
|
protected:
|
||||||
iter_type do_put(iter_type out, unsigned long long, const fmt::format_specs&,
|
void do_put(fmt::appender out, unsigned long long, const fmt::format_specs&,
|
||||||
std::locale&) const override;
|
std::locale&) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
num_format::iter_type num_format::do_put(iter_type out, unsigned long long,
|
void num_format::do_put(fmt::appender out, unsigned long long value,
|
||||||
const fmt::format_specs&,
|
const fmt::format_specs&, std::locale&) const {
|
||||||
std::locale&) const {
|
fmt::format_to(out, "[{}]", value);
|
||||||
const char s[] = "foo";
|
|
||||||
return std::copy_n(s, sizeof(s) - 1, out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(locale_test, num_format) {
|
TEST(locale_test, num_format) {
|
||||||
auto loc = std::locale(std::locale(), new num_format());
|
auto loc = std::locale(std::locale(), new num_format());
|
||||||
EXPECT_EQ(fmt::format(loc, "{:L}", 42), "foo");
|
EXPECT_EQ(fmt::format(loc, "{:L}", 42), "[42]");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FMT_STATIC_THOUSANDS_SEPARATOR
|
#endif // FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
|
Reference in New Issue
Block a user