Reduce <algorithm> usage (#1998)
This commit is contained in:
parent
a07627b1f8
commit
b5dac0f0f8
@ -8,6 +8,7 @@
|
|||||||
#ifndef FMT_CHRONO_H_
|
#ifndef FMT_CHRONO_H_
|
||||||
#define FMT_CHRONO_H_
|
#define FMT_CHRONO_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#ifndef FMT_COMPILE_H_
|
#ifndef FMT_COMPILE_H_
|
||||||
#define FMT_COMPILE_H_
|
#define FMT_COMPILE_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
@ -784,9 +784,7 @@ class iterator_buffer final : public Traits, public buffer<T> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit iterator_buffer(OutputIt out, size_t n = buffer_size)
|
explicit iterator_buffer(OutputIt out, size_t n = buffer_size)
|
||||||
: Traits(n),
|
: Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {}
|
||||||
buffer<T>(data_, 0, buffer_size),
|
|
||||||
out_(out) {}
|
|
||||||
~iterator_buffer() { flush(); }
|
~iterator_buffer() { flush(); }
|
||||||
|
|
||||||
OutputIt out() {
|
OutputIt out() {
|
||||||
@ -1918,7 +1916,7 @@ FMT_END_NAMESPACE
|
|||||||
#endif // FMT_CORE_H_
|
#endif // FMT_CORE_H_
|
||||||
|
|
||||||
// Define FMT_DYNAMIC_ARGS to make core.h provide dynamic_format_arg_store
|
// Define FMT_DYNAMIC_ARGS to make core.h provide dynamic_format_arg_store
|
||||||
// (not recommended).
|
// DEPRECATED! Include fmt/args.h directly instead.
|
||||||
#ifdef FMT_DYNAMIC_ARGS
|
#ifdef FMT_DYNAMIC_ARGS
|
||||||
# include "args.h"
|
#include "args.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#ifndef FMT_FORMAT_INL_H_
|
#ifndef FMT_FORMAT_INL_H_
|
||||||
#define FMT_FORMAT_INL_H_
|
#define FMT_FORMAT_INL_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
@ -33,13 +33,13 @@
|
|||||||
#ifndef FMT_FORMAT_H_
|
#ifndef FMT_FORMAT_H_
|
||||||
#define FMT_FORMAT_H_
|
#define FMT_FORMAT_H_
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <utility> // std::swap
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
@ -561,13 +561,24 @@ inline size_t code_point_index(basic_string_view<char8_type> s, size_t n) {
|
|||||||
const char8_type* data = s.data();
|
const char8_type* data = s.data();
|
||||||
size_t num_code_points = 0;
|
size_t num_code_points = 0;
|
||||||
for (size_t i = 0, size = s.size(); i != size; ++i) {
|
for (size_t i = 0, size = s.size(); i != size; ++i) {
|
||||||
if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) {
|
if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) return i;
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return s.size();
|
return s.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
|
||||||
|
// instead (#1998).
|
||||||
|
template <typename OutputIt, typename Size, typename T>
|
||||||
|
OutputIt fill_n(OutputIt out, Size count, const T& value) {
|
||||||
|
for (Size i = 0; i < count; ++i) *out++ = value;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
template <typename T, typename Size>
|
||||||
|
inline T* fill_n(T* out, Size count, char value) {
|
||||||
|
std::memset(out, value, to_unsigned(count));
|
||||||
|
return out + count;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename InputIt, typename OutChar>
|
template <typename InputIt, typename OutChar>
|
||||||
using needs_conversion = bool_constant<
|
using needs_conversion = bool_constant<
|
||||||
std::is_same<typename std::iterator_traits<InputIt>::value_type,
|
std::is_same<typename std::iterator_traits<InputIt>::value_type,
|
||||||
@ -577,14 +588,21 @@ using needs_conversion = bool_constant<
|
|||||||
template <typename OutChar, typename InputIt, typename OutputIt,
|
template <typename OutChar, typename InputIt, typename OutputIt,
|
||||||
FMT_ENABLE_IF(!needs_conversion<InputIt, OutChar>::value)>
|
FMT_ENABLE_IF(!needs_conversion<InputIt, OutChar>::value)>
|
||||||
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
|
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
|
||||||
return std::copy(begin, end, it);
|
while (begin != end) *it++ = *begin++;
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutChar, typename InputIt,
|
||||||
|
FMT_ENABLE_IF(!needs_conversion<InputIt, OutChar>::value)>
|
||||||
|
inline OutChar* copy_str(InputIt begin, InputIt end, OutChar* out) {
|
||||||
|
return std::uninitialized_copy(begin, end, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutChar, typename InputIt, typename OutputIt,
|
template <typename OutChar, typename InputIt, typename OutputIt,
|
||||||
FMT_ENABLE_IF(needs_conversion<InputIt, OutChar>::value)>
|
FMT_ENABLE_IF(needs_conversion<InputIt, OutChar>::value)>
|
||||||
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
|
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
|
||||||
return std::transform(begin, end, it,
|
while (begin != end) *it++ = static_cast<char8_type>(*begin++);
|
||||||
[](char c) { return static_cast<char8_type>(c); });
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char, typename InputIt>
|
template <typename Char, typename InputIt>
|
||||||
@ -617,7 +635,7 @@ void buffer<T>::append(const U* begin, const U* end) {
|
|||||||
|
|
||||||
template <typename OutputIt, typename T, typename Traits>
|
template <typename OutputIt, typename T, typename Traits>
|
||||||
void iterator_buffer<OutputIt, T, Traits>::flush() {
|
void iterator_buffer<OutputIt, T, Traits>::flush() {
|
||||||
out_ = std::copy_n(data_, this->limit(this->size()), out_);
|
out_ = copy_str<T>(data_, data_ + this->limit(this->size()), out_);
|
||||||
this->clear();
|
this->clear();
|
||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -754,7 +772,7 @@ void basic_memory_buffer<T, SIZE, Allocator>::grow(size_t size) {
|
|||||||
if (size > new_capacity)
|
if (size > new_capacity)
|
||||||
new_capacity = size;
|
new_capacity = size;
|
||||||
else if (new_capacity > max_size)
|
else if (new_capacity > max_size)
|
||||||
new_capacity = (std::max)(size, max_size);
|
new_capacity = size > max_size ? size : max_size;
|
||||||
T* old_data = this->data();
|
T* old_data = this->data();
|
||||||
T* new_data =
|
T* new_data =
|
||||||
std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
|
std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
|
||||||
@ -1493,8 +1511,10 @@ class cstring_type_checker : public ErrorHandler {
|
|||||||
template <typename OutputIt, typename Char>
|
template <typename OutputIt, typename Char>
|
||||||
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t<Char>& fill) {
|
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t<Char>& fill) {
|
||||||
auto fill_size = fill.size();
|
auto fill_size = fill.size();
|
||||||
if (fill_size == 1) return std::fill_n(it, n, fill[0]);
|
if (fill_size == 1) return detail::fill_n(it, n, fill[0]);
|
||||||
for (size_t i = 0; i < n; ++i) it = std::copy_n(fill.data(), fill_size, it);
|
auto data = fill.data();
|
||||||
|
for (size_t i = 0; i < n; ++i)
|
||||||
|
it = copy_str<Char>(data, data + fill_size, it);
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1570,7 +1590,7 @@ OutputIt write_int(OutputIt out, int num_digits, string_view prefix,
|
|||||||
return write_padded<align::right>(out, specs, data.size, [=](iterator it) {
|
return write_padded<align::right>(out, specs, data.size, [=](iterator it) {
|
||||||
if (prefix.size() != 0)
|
if (prefix.size() != 0)
|
||||||
it = copy_str<Char>(prefix.begin(), prefix.end(), it);
|
it = copy_str<Char>(prefix.begin(), prefix.end(), it);
|
||||||
it = std::fill_n(it, data.padding, static_cast<Char>('0'));
|
it = detail::fill_n(it, data.padding, static_cast<Char>('0'));
|
||||||
return f(it);
|
return f(it);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1779,7 +1799,7 @@ inline Char* write_significand(Char* out, UInt significand,
|
|||||||
if (integral_size == 1)
|
if (integral_size == 1)
|
||||||
out[0] = out[1];
|
out[0] = out[1];
|
||||||
else
|
else
|
||||||
std::copy_n(out + 1, integral_size, out);
|
std::uninitialized_copy_n(out + 1, integral_size, out);
|
||||||
out[integral_size] = decimal_point;
|
out[integral_size] = decimal_point;
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
@ -1831,7 +1851,8 @@ OutputIt write_float(OutputIt out, const DecimalFP& fp,
|
|||||||
if (use_exp_format()) {
|
if (use_exp_format()) {
|
||||||
int num_zeros = 0;
|
int num_zeros = 0;
|
||||||
if (fspecs.showpoint) {
|
if (fspecs.showpoint) {
|
||||||
num_zeros = (std::max)(fspecs.precision - significand_size, 0);
|
num_zeros = fspecs.precision - significand_size;
|
||||||
|
if (num_zeros < 0) num_zeros = 0;
|
||||||
size += to_unsigned(num_zeros);
|
size += to_unsigned(num_zeros);
|
||||||
} else if (significand_size == 1) {
|
} else if (significand_size == 1) {
|
||||||
decimal_point = Char();
|
decimal_point = Char();
|
||||||
@ -1847,7 +1868,7 @@ OutputIt write_float(OutputIt out, const DecimalFP& fp,
|
|||||||
// Insert a decimal point after the first digit and add an exponent.
|
// Insert a decimal point after the first digit and add an exponent.
|
||||||
it = write_significand(it, significand, significand_size, 1,
|
it = write_significand(it, significand, significand_size, 1,
|
||||||
decimal_point);
|
decimal_point);
|
||||||
if (num_zeros > 0) it = std::fill_n(it, num_zeros, zero);
|
if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
|
||||||
*it++ = static_cast<Char>(exp_char);
|
*it++ = static_cast<Char>(exp_char);
|
||||||
return write_exponent<Char>(output_exp, it);
|
return write_exponent<Char>(output_exp, it);
|
||||||
};
|
};
|
||||||
@ -1871,10 +1892,10 @@ OutputIt write_float(OutputIt out, const DecimalFP& fp,
|
|||||||
return write_padded<align::right>(out, specs, size, [&](iterator it) {
|
return write_padded<align::right>(out, specs, size, [&](iterator it) {
|
||||||
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
|
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
|
||||||
it = write_significand<Char>(it, significand, significand_size);
|
it = write_significand<Char>(it, significand, significand_size);
|
||||||
it = std::fill_n(it, fp.exponent, zero);
|
it = detail::fill_n(it, fp.exponent, zero);
|
||||||
if (!fspecs.showpoint) return it;
|
if (!fspecs.showpoint) return it;
|
||||||
*it++ = decimal_point;
|
*it++ = decimal_point;
|
||||||
return num_zeros > 0 ? std::fill_n(it, num_zeros, zero) : it;
|
return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
|
||||||
});
|
});
|
||||||
} else if (exp > 0) {
|
} else if (exp > 0) {
|
||||||
// 1234e-2 -> 12.34[0+]
|
// 1234e-2 -> 12.34[0+]
|
||||||
@ -1884,7 +1905,7 @@ OutputIt write_float(OutputIt out, const DecimalFP& fp,
|
|||||||
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
|
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
|
||||||
it = write_significand(it, significand, significand_size, exp,
|
it = write_significand(it, significand, significand_size, exp,
|
||||||
decimal_point);
|
decimal_point);
|
||||||
return num_zeros > 0 ? std::fill_n(it, num_zeros, zero) : it;
|
return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 1234e-6 -> 0.001234
|
// 1234e-6 -> 0.001234
|
||||||
@ -1899,7 +1920,7 @@ OutputIt write_float(OutputIt out, const DecimalFP& fp,
|
|||||||
*it++ = zero;
|
*it++ = zero;
|
||||||
if (num_zeros == 0 && significand_size == 0 && !fspecs.showpoint) return it;
|
if (num_zeros == 0 && significand_size == 0 && !fspecs.showpoint) return it;
|
||||||
*it++ = decimal_point;
|
*it++ = decimal_point;
|
||||||
it = std::fill_n(it, num_zeros, zero);
|
it = detail::fill_n(it, num_zeros, zero);
|
||||||
return write_significand<Char>(it, significand, significand_size);
|
return write_significand<Char>(it, significand, significand_size);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -2030,7 +2051,7 @@ OutputIt write(OutputIt out, string_view value) {
|
|||||||
template <typename Char, typename OutputIt>
|
template <typename Char, typename OutputIt>
|
||||||
OutputIt write(OutputIt out, basic_string_view<Char> value) {
|
OutputIt write(OutputIt out, basic_string_view<Char> value) {
|
||||||
auto it = reserve(out, value.size());
|
auto it = reserve(out, value.size());
|
||||||
it = std::copy(value.begin(), value.end(), it);
|
it = copy_str<Char>(value.begin(), value.end(), it);
|
||||||
return base_iterator(out, it);
|
return base_iterator(out, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2172,7 +2193,7 @@ class arg_formatter_base {
|
|||||||
void write(wstring_view value) {
|
void write(wstring_view value) {
|
||||||
static_assert(std::is_same<Char, wchar_t>::value, "");
|
static_assert(std::is_same<Char, wchar_t>::value, "");
|
||||||
auto&& it = reserve(value.size());
|
auto&& it = reserve(value.size());
|
||||||
it = std::copy(value.begin(), value.end(), it);
|
it = copy_str<Char>(value.begin(), value.end(), it);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ch>
|
template <typename Ch>
|
||||||
@ -3674,7 +3695,7 @@ struct formatter<arg_join<It, Sentinel, Char>, Char>
|
|||||||
if (it != value.end) {
|
if (it != value.end) {
|
||||||
out = base::format(*it++, ctx);
|
out = base::format(*it++, ctx);
|
||||||
while (it != value.end) {
|
while (it != value.end) {
|
||||||
out = std::copy(value.sep.begin(), value.sep.end(), out);
|
out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
|
||||||
ctx.advance_to(out);
|
ctx.advance_to(out);
|
||||||
out = base::format(*it++, ctx);
|
out = base::format(*it++, ctx);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#ifndef FMT_FORMAT_
|
#ifndef FMT_FORMAT_
|
||||||
#define FMT_FORMAT_
|
#define FMT_FORMAT_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user