Remove allocating containers from on_num
Use std::string_view and std::array containers when FMT_STATIC_THOUSANDS_SEPARATOR is defined. This will help in the case for embedded system where even using containers that can potentially allocate results in malloc/free and new/delete being linked into the binary. In many embedded cases dynamic library allocation is prohibited and even the cost of linking in these libraries costs too high of a cost in flash size. Resolves #1762
This commit is contained in:
parent
f19b1a521e
commit
64973fb160
@ -392,6 +392,13 @@ template <typename Char> class basic_string_view {
|
||||
constexpr iterator begin() const { return data_; }
|
||||
constexpr iterator end() const { return data_ + size_; }
|
||||
|
||||
constexpr iterator cbegin() const { return data_; }
|
||||
constexpr iterator cend() const { return data_ + size_; }
|
||||
|
||||
constexpr bool empty() const { return size_ == 0; };
|
||||
|
||||
constexpr Char back() const { return data_[size_ - 1]; }
|
||||
|
||||
constexpr const Char& operator[](size_t pos) const { return data_[pos]; }
|
||||
|
||||
FMT_CONSTEXPR void remove_prefix(size_t n) {
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
#define FMT_FORMAT_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
@ -1552,13 +1553,18 @@ template <typename OutputIt, typename Char, typename UInt> struct int_writer {
|
||||
enum { sep_size = 1 };
|
||||
|
||||
void on_num() {
|
||||
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
||||
std::string groups = grouping<Char>(locale);
|
||||
#else
|
||||
constexpr const char kDefaultGroups[] = "\03";
|
||||
basic_string_view<Char> groups(kDefaultGroups, sizeof(kDefaultGroups));
|
||||
#endif
|
||||
if (groups.empty()) return on_dec();
|
||||
auto sep = thousands_sep<Char>(locale);
|
||||
if (!sep) return on_dec();
|
||||
int num_digits = count_digits(abs_value);
|
||||
int size = num_digits, n = num_digits;
|
||||
std::string::const_iterator group = groups.cbegin();
|
||||
auto group = groups.cbegin();
|
||||
while (group != groups.cend() && num_digits > *group && *group > 0 &&
|
||||
*group != max_value<char>()) {
|
||||
size += sep_size;
|
||||
@ -1568,9 +1574,9 @@ template <typename OutputIt, typename Char, typename UInt> struct int_writer {
|
||||
if (group == groups.cend()) size += sep_size * ((n - 1) / groups.back());
|
||||
char digits[40];
|
||||
format_decimal(digits, abs_value, num_digits);
|
||||
basic_memory_buffer<Char> buffer;
|
||||
// TODO(kammce): remove the * 2!
|
||||
std::array<Char, inline_buffer_size * 2> buffer;
|
||||
size += prefix_size;
|
||||
buffer.resize(size);
|
||||
basic_string_view<Char> s(&sep, sep_size);
|
||||
// Index of a decimal digit with the least significant digit having index 0.
|
||||
int digit_index = 0;
|
||||
@ -1590,7 +1596,7 @@ template <typename OutputIt, typename Char, typename UInt> struct int_writer {
|
||||
make_checked(p, s.size()));
|
||||
}
|
||||
if (prefix_size != 0) p[-1] = static_cast<Char>('-');
|
||||
write(out, basic_string_view<Char>(buffer.data(), buffer.size()), specs);
|
||||
write(out, basic_string_view<Char>(buffer.data(), size), specs);
|
||||
}
|
||||
|
||||
void on_chr() { *out++ = static_cast<Char>(abs_value); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user