🎨 clang-format affected files!

This commit is contained in:
ThePhD 2023-12-15 14:22:34 -05:00
parent 60e18f5c8f
commit 4533970bfe
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
6 changed files with 234 additions and 203 deletions

View File

@ -543,10 +543,11 @@ inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
Formats a string with the given text_style and writes the output to ``out``. Formats a string with the given text_style and writes the output to ``out``.
*/ */
template <typename Output, typename Char, template <typename Output, typename Char,
FMT_ENABLE_IF(std::ranges::output_range<Output, Char> || std::output_iterator<remove_cvref_t<Output>, Char>)> FMT_ENABLE_IF(std::ranges::output_range<Output, Char> ||
auto vformat_to( std::output_iterator<remove_cvref_t<Output>, Char>)>
Output&& out, const text_style& ts, basic_string_view<Char> format_str, auto vformat_to(Output&& out, const text_style& ts,
basic_format_args<buffer_context<type_identity_t<Char>>> args) { basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
auto&& buf = detail::get_appendable_buffer<Char>(std::forward<Output>(out)); auto&& buf = detail::get_appendable_buffer<Char>(std::forward<Output>(out));
detail::vformat_to(buf, ts, format_str, args); detail::vformat_to(buf, ts, format_str, args);
return detail::get_iterator(buf, out); return detail::get_iterator(buf, out);
@ -555,7 +556,8 @@ auto vformat_to(
/** /**
\rst \rst
Formats arguments with the given text_style, writes the result to the output Formats arguments with the given text_style, writes the result to the output
iterator or range ``out`` and returns the iterator past the end of the output range. iterator or range ``out`` and returns the iterator past the end of the output
range.
**Example**:: **Example**::
@ -565,13 +567,15 @@ auto vformat_to(
\endrst \endrst
*/ */
template <typename Output, typename S, typename... Args, template <typename Output, typename S, typename... Args,
bool enable = (std::ranges::output_range<Output, char_t<S>> bool enable =
|| std::output_iterator<remove_cvref_t<Output>, char_t<S>>) (std::ranges::output_range<Output, char_t<S>> ||
&& detail::is_string<S>::value, std::output_iterator<remove_cvref_t<Output>,
FMT_ENABLE_IF(enable)> char_t<S>>)&&detail::is_string<S>::value,
FMT_ENABLE_IF(enable)>
inline auto format_to(Output&& out, const text_style& ts, const S& format_str, inline auto format_to(Output&& out, const text_style& ts, const S& format_str,
Args&&... args) { Args&&... args) {
return vformat_to(std::forward<Output>(out), ts, detail::to_string_view(format_str), return vformat_to(std::forward<Output>(out), ts,
detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<char_t<S>>>(args...)); fmt::make_format_args<buffer_context<char_t<S>>>(args...));
} }
@ -579,8 +583,8 @@ inline auto format_to(Output&& out, const text_style& ts, const S& format_str,
Formats a string with the given text_style and writes the output to ``out``. Formats a string with the given text_style and writes the output to ``out``.
*/ */
template <typename Output, typename Char, template <typename Output, typename Char,
FMT_ENABLE_IF(std::ranges::output_range<Output, Char> FMT_ENABLE_IF(std::ranges::output_range<Output, Char> ||
|| std::output_iterator<remove_cvref_t<Output>, Char>)> std::output_iterator<remove_cvref_t<Output>, Char>)>
auto vformat_into( auto vformat_into(
Output&& out, const text_style& ts, basic_string_view<Char> format_str, Output&& out, const text_style& ts, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) { basic_format_args<buffer_context<type_identity_t<Char>>> args) {
@ -602,14 +606,16 @@ auto vformat_into(
\endrst \endrst
*/ */
template <typename Output, typename S, typename... Args, template <typename Output, typename S, typename... Args,
bool enable = (std::ranges::output_range<Output, char_t<S>> bool enable =
|| std::output_iterator<remove_cvref_t<Output>, char_t<S>>) (std::ranges::output_range<Output, char_t<S>> ||
&& detail::is_string<S>::value, std::output_iterator<remove_cvref_t<Output>,
FMT_ENABLE_IF(enable)> char_t<S>>)&&detail::is_string<S>::value,
FMT_ENABLE_IF(enable)>
inline auto format_into(Output&& out, const text_style& ts, const S& format_str, inline auto format_into(Output&& out, const text_style& ts, const S& format_str,
Args&&... args) { Args&&... args) {
return vformat_into(std::forward<Output>(out), ts, detail::to_string_view(format_str), return vformat_into(
fmt::make_format_args<buffer_context<char_t<S>>>(args...)); std::forward<Output>(out), ts, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<char_t<S>>>(args...));
} }
#else #else
/** /**
@ -637,10 +643,9 @@ OutputIt vformat_to(
fmt::emphasis::bold | fg(fmt::color::red), "{}", 42); fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
\endrst \endrst
*/ */
template < template <typename OutputIt, typename S, typename... Args,
typename OutputIt, typename S, typename... Args, bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value&&
bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value && detail::is_string<S>::value>
detail::is_string<S>::value>
inline auto format_to(OutputIt out, const text_style& ts, const S& format_str, inline auto format_to(OutputIt out, const text_style& ts, const S& format_str,
Args&&... args) -> Args&&... args) ->
typename std::enable_if<enable, OutputIt>::type { typename std::enable_if<enable, OutputIt>::type {

View File

@ -471,7 +471,7 @@ FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
} }
} }
#if FMT_OUTPUT_RANGES # if FMT_OUTPUT_RANGES
template <typename Output, typename S, typename... Args, template <typename Output, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_CONSTEXPR auto format_to(Output&& out, const S&, Args&&... args) { FMT_CONSTEXPR auto format_to(Output&& out, const S&, Args&&... args) {
@ -479,12 +479,12 @@ FMT_CONSTEXPR auto format_to(Output&& out, const S&, Args&&... args) {
if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>, if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
detail::unknown_format>()) { detail::unknown_format>()) {
return fmt::format_to( return fmt::format_to(
std::forward<Output>(out), std::forward<Output>(out),
static_cast<basic_string_view<typename S::char_type>>(S()), static_cast<basic_string_view<typename S::char_type>>(S()),
std::forward<Args>(args)...); std::forward<Args>(args)...);
} else { } else {
return fmt::format_to(std::forward<Output>(out), return fmt::format_to(std::forward<Output>(out), compiled,
compiled, std::forward<Args>(args)...); std::forward<Args>(args)...);
} }
} }
@ -495,15 +495,15 @@ FMT_CONSTEXPR auto format_into(Output&& out, const S&, Args&&... args) {
if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>, if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
detail::unknown_format>()) { detail::unknown_format>()) {
return fmt::format_into( return fmt::format_into(
std::forward<Output>(out), std::forward<Output>(out),
static_cast<basic_string_view<typename S::char_type>>(S()), static_cast<basic_string_view<typename S::char_type>>(S()),
std::forward<Args>(args)...); std::forward<Args>(args)...);
} else { } else {
return fmt::format_into(std::forward<Output>(out), return fmt::format_into(std::forward<Output>(out), compiled,
compiled, std::forward<Args>(args)...); std::forward<Args>(args)...);
} }
} }
#else # else
template <typename OutputIt, typename S, typename... Args, template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)> FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) { FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
@ -517,7 +517,7 @@ FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
return fmt::format_to(out, compiled, std::forward<Args>(args)...); return fmt::format_to(out, compiled, std::forward<Args>(args)...);
} }
} }
#endif # endif
#endif #endif
template <typename OutputIt, typename S, typename... Args, template <typename OutputIt, typename S, typename... Args,

View File

@ -144,11 +144,11 @@
// Only on if we know we can do the begin/end range checking properly, // Only on if we know we can do the begin/end range checking properly,
// that we have `if constexpr`, and that we have a std::ranges::subrange type // that we have `if constexpr`, and that we have a std::ranges::subrange type
#ifndef FMT_OUTPUT_RANGES #ifndef FMT_OUTPUT_RANGES
# if FMT_RANGE_CHECKS \ # if FMT_RANGE_CHECKS && defined(__cpp_if_constexpr) && \
&& defined(__cpp_if_constexpr) && (__cpp_if_constexpr >= 201606L)\ (__cpp_if_constexpr >= 201606L) && defined(__cpp_lib_ranges) && \
&& defined(__cpp_lib_ranges) && (__cpp_lib_ranges >= 201911L )\ (__cpp_lib_ranges >= 201911L) && defined(__cpp_concepts) && \
&& defined(__cpp_concepts) && (__cpp_concepts >= 202002L) \ (__cpp_concepts >= 202002L) && defined(__cpp_lib_concepts) && \
&& defined(__cpp_lib_concepts) && (__cpp_lib_concepts >= 201907L) (__cpp_lib_concepts >= 201907L)
# define FMT_OUTPUT_RANGES 1 # define FMT_OUTPUT_RANGES 1
# else # else
# define FMT_OUTPUT_RANGES 0 # define FMT_OUTPUT_RANGES 0
@ -243,7 +243,8 @@
#ifndef FMT_UNICODE #ifndef FMT_UNICODE
# if FMT_CLANG_VERSION # if FMT_CLANG_VERSION
# define FMT_UNICODE 1 # define FMT_UNICODE 1
# elif defined(_MSVC_EXECUTION_CHARACTER_SET) && (_MSVC_EXECUTION_CHARACTER_SET == 65001) # elif defined(_MSVC_EXECUTION_CHARACTER_SET) && \
(_MSVC_EXECUTION_CHARACTER_SET == 65001)
# define FMT_UNICODE 1 # define FMT_UNICODE 1
# else # else
# define FMT_UNICODE !FMT_MSC_VERSION # define FMT_UNICODE !FMT_MSC_VERSION
@ -826,9 +827,10 @@ FMT_CONSTEXPR auto copy_str(InputIt begin, InputSen end, OutputIt out)
template <typename Char, typename T, typename U, template <typename Char, typename T, typename U,
FMT_ENABLE_IF( FMT_ENABLE_IF(
std::is_same<remove_const_t<T>, U>::value && is_char<U>::value)> std::is_same<remove_const_t<T>, U>::value&& is_char<U>::value)>
FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out) -> U* { FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out) -> U* {
if (is_constant_evaluated()) return copy_str<Char, T*, T*, U*>(begin, end, out); if (is_constant_evaluated())
return copy_str<Char, T*, T*, U*>(begin, end, out);
auto size = to_unsigned(end - begin); auto size = to_unsigned(end - begin);
if (size > 0) memcpy(out, begin, size * sizeof(U)); if (size > 0) memcpy(out, begin, size * sizeof(U));
return out + size; return out + size;
@ -836,30 +838,34 @@ FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out) -> U* {
#if FMT_OUTPUT_RANGES #if FMT_OUTPUT_RANGES
template <typename Char, typename InputIt, typename InputSen, typename OutputIt, typename OutputSen> template <typename Char, typename InputIt, typename InputSen, typename OutputIt,
FMT_CONSTEXPR auto copy_str(InputIt begin, InputSen end, OutputIt out, OutputSen out_end) typename OutputSen>
FMT_CONSTEXPR auto copy_str(InputIt begin, InputSen end, OutputIt out,
OutputSen out_end)
-> std::ranges::subrange<OutputIt, OutputSen> { -> std::ranges::subrange<OutputIt, OutputSen> {
if constexpr (std::is_same<OutputSen, std::unreachable_sentinel_t>::value) { if constexpr (std::is_same<OutputSen, std::unreachable_sentinel_t>::value) {
// minor speed optimization // minor speed optimization
auto out_current = copy_str<Char>(std::move(begin), std::move(end), std::move(out)); auto out_current =
return { std::move(out_current), std::move(out_end) }; copy_str<Char>(std::move(begin), std::move(end), std::move(out));
} return {std::move(out_current), std::move(out_end)};
else { } else {
while (begin != end && out != out_end) *out++ = static_cast<Char>(*begin++); while (begin != end && out != out_end) *out++ = static_cast<Char>(*begin++);
return { std::move(out), std::move(out_end) }; return {std::move(out), std::move(out_end)};
} }
} }
template <typename Char, typename T, typename U, template <typename Char, typename T, typename U,
FMT_ENABLE_IF( FMT_ENABLE_IF(
std::is_same<remove_const_t<T>, U>::value && is_char<U>::value)> std::is_same<remove_const_t<T>, U>::value&& is_char<U>::value)>
FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out, U* out_end) -> std::ranges::subrange<U*, U*> { FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out, U* out_end)
if (is_constant_evaluated()) return copy_str<Char, T*,T*, U*, U*>(begin, end, out, out_end); -> std::ranges::subrange<U*, U*> {
if (is_constant_evaluated())
return copy_str<Char, T*, T*, U*, U*>(begin, end, out, out_end);
auto size = to_unsigned(end - begin); auto size = to_unsigned(end - begin);
auto out_size = to_unsigned(out_end - out); auto out_size = to_unsigned(out_end - out);
if (size > out_size) size = out_size; if (size > out_size) size = out_size;
if (size > 0) memcpy(out, begin, size * sizeof(U)); if (size > 0) memcpy(out, begin, size * sizeof(U));
return { out + size, out_end }; return {out + size, out_end};
} }
#endif #endif
@ -1013,7 +1019,8 @@ class iterator_buffer final : public Traits, public buffer<T> {
template <typename Output, typename T, typename Traits = buffer_traits> template <typename Output, typename T, typename Traits = buffer_traits>
class range_buffer final : public Traits, public buffer<T> { class range_buffer final : public Traits, public buffer<T> {
private: private:
using Subrange_ = std::ranges::subrange<std::ranges::iterator_t<Output>, std::ranges::sentinel_t<Output>>; using Subrange_ = std::ranges::subrange<std::ranges::iterator_t<Output>,
std::ranges::sentinel_t<Output>>;
Subrange_ out_; Subrange_ out_;
enum { buffer_size = 256 }; enum { buffer_size = 256 };
T data_[buffer_size]; T data_[buffer_size];
@ -1024,8 +1031,7 @@ class range_buffer final : public Traits, public buffer<T> {
} }
void flush() { void flush() {
if (std::ranges::empty(out_)) if (std::ranges::empty(out_)) return;
return;
auto size = this->size(); auto size = this->size();
this->clear(); this->clear();
auto it_end = copy_str<T>(data_, data_ + this->limit(size), auto it_end = copy_str<T>(data_, data_ + this->limit(size),
@ -1036,9 +1042,13 @@ class range_buffer final : public Traits, public buffer<T> {
public: public:
template <typename Out> template <typename Out>
explicit range_buffer(Out&& out, size_t n = buffer_size) explicit range_buffer(Out&& out, size_t n = buffer_size)
: Traits(n), buffer<T>(data_, 0, buffer_size), out_(std::forward<Out>(out)) {} : Traits(n),
buffer<T>(data_, 0, buffer_size),
out_(std::forward<Out>(out)) {}
range_buffer(range_buffer&& other) range_buffer(range_buffer&& other)
: Traits(other), buffer<T>(data_, 0, buffer_size), out_(std::move(other.out_)) {} : Traits(other),
buffer<T>(data_, 0, buffer_size),
out_(std::move(other.out_)) {}
~range_buffer() { flush(); } ~range_buffer() { flush(); }
auto out() -> Subrange_ { auto out() -> Subrange_ {
@ -1049,9 +1059,12 @@ class range_buffer final : public Traits, public buffer<T> {
}; };
template <typename Output, typename T, typename Traits> template <typename Output, typename T, typename Traits>
class range_buffer<std::back_insert_iterator<Output>, T, Traits> final : public Traits, public buffer<T> { class range_buffer<std::back_insert_iterator<Output>, T, Traits> final
: public Traits,
public buffer<T> {
private: private:
using Subrange_ = std::ranges::subrange<std::ranges::iterator_t<Output>, std::ranges::sentinel_t<Output>>; using Subrange_ = std::ranges::subrange<std::ranges::iterator_t<Output>,
std::ranges::sentinel_t<Output>>;
Output& out_; Output& out_;
enum { buffer_size = 256 }; enum { buffer_size = 256 };
T data_[buffer_size]; T data_[buffer_size];
@ -1071,7 +1084,9 @@ class range_buffer<std::back_insert_iterator<Output>, T, Traits> final : public
explicit range_buffer(Output& out, size_t n = buffer_size) explicit range_buffer(Output& out, size_t n = buffer_size)
: Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {} : Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {}
range_buffer(range_buffer&& other) range_buffer(range_buffer&& other)
: Traits(other), buffer<T>(data_, 0, buffer_size), out_(std::move(other.out_)) {} : Traits(other),
buffer<T>(data_, 0, buffer_size),
out_(std::move(other.out_)) {}
~range_buffer() { flush(); } ~range_buffer() { flush(); }
auto out() -> Subrange_ { auto out() -> Subrange_ {
@ -1082,9 +1097,12 @@ class range_buffer<std::back_insert_iterator<Output>, T, Traits> final : public
}; };
template <typename Output, typename T, typename Traits> template <typename Output, typename T, typename Traits>
class range_buffer<std::insert_iterator<Output>, T, Traits> final : public Traits, public buffer<T> { class range_buffer<std::insert_iterator<Output>, T, Traits> final
: public Traits,
public buffer<T> {
private: private:
using Subrange_ = std::ranges::subrange<std::ranges::iterator_t<Output>, std::ranges::sentinel_t<Output>>; using Subrange_ = std::ranges::subrange<std::ranges::iterator_t<Output>,
std::ranges::sentinel_t<Output>>;
Output& out_; Output& out_;
enum { buffer_size = 256 }; enum { buffer_size = 256 };
T data_[buffer_size]; T data_[buffer_size];
@ -1097,14 +1115,17 @@ class range_buffer<std::insert_iterator<Output>, T, Traits> final : public Trait
void flush() { void flush() {
auto size = this->size(); auto size = this->size();
this->clear(); this->clear();
copy_str<T>(data_, data_ + this->limit(size), std::inserter(out_, out_.end())); copy_str<T>(data_, data_ + this->limit(size),
std::inserter(out_, out_.end()));
} }
public: public:
explicit range_buffer(Output& out, size_t n = buffer_size) explicit range_buffer(Output& out, size_t n = buffer_size)
: Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {} : Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {}
range_buffer(range_buffer&& other) range_buffer(range_buffer&& other)
: Traits(other), buffer<T>(data_, 0, buffer_size), out_(std::move(other.out_)) {} : Traits(other),
buffer<T>(data_, 0, buffer_size),
out_(std::move(other.out_)) {}
~range_buffer() { flush(); } ~range_buffer() { flush(); }
auto out() -> Subrange_ { auto out() -> Subrange_ {
@ -1775,43 +1796,39 @@ struct is_container_push_backable : std::false_type {};
template <typename Container, typename T> template <typename Container, typename T>
struct is_container_push_backable< struct is_container_push_backable<
Container, T, Container, T,
void_t<decltype(std::declval<Container>().push_back(std::declval<T>()))> void_t<decltype(std::declval<Container>().push_back(std::declval<T>()))>>
> : std::true_type {}; : std::true_type {};
template <typename Container, typename T, typename Enable = void> template <typename Container, typename T, typename Enable = void>
struct is_container_insertable : std::false_type {}; struct is_container_insertable : std::false_type {};
template <typename Container, typename T> template <typename Container, typename T>
struct is_container_insertable< struct is_container_insertable<
Container, T, Container, T,
void_t<decltype(std::declval<Container>().insert( void_t<decltype(std::declval<Container>().insert(
std::declval<std::ranges::iterator_t<Container>>(), std::declval<std::ranges::iterator_t<Container>>(),
std::declval<T>() std::declval<T>()))>>
))> : std::integral_constant<bool, std::is_lvalue_reference<Container>::value> {
> : std::integral_constant<bool, };
std::is_lvalue_reference<Container>::value
> {};
#endif #endif
// Maps an output iterator to a buffer. // Maps an output iterator to a buffer.
#if FMT_OUTPUT_RANGES #if FMT_OUTPUT_RANGES
template <typename T, typename Output> template <typename T, typename Output> decltype(auto) get_buffer(Output&& out) {
decltype(auto) get_buffer(Output&& out) {
if constexpr (std::ranges::output_range<Output, T&>) { if constexpr (std::ranges::output_range<Output, T&>) {
return range_buffer<remove_cvref_t<Output>, T>(std::forward<Output>(out)); return range_buffer<remove_cvref_t<Output>, T>(std::forward<Output>(out));
} } else if constexpr (is_back_insert_iterator<remove_cvref_t<Output>>::value) {
else if constexpr (is_back_insert_iterator<remove_cvref_t<Output>>::value) {
using Container_ = typename remove_cvref_t<Output>::container_type; using Container_ = typename remove_cvref_t<Output>::container_type;
if constexpr (std::is_base_of<buffer<char>, Container_>::value) { if constexpr (std::is_base_of<buffer<char>, Container_>::value) {
return get_container(out); return get_container(out);
} else {
return iterator_buffer<remove_cvref_t<Output>, T>(
std::forward<Output>(out));
} }
else { } else {
return iterator_buffer<remove_cvref_t<Output>, T>(std::forward<Output>(out)); return iterator_buffer<remove_cvref_t<Output>, T>(
} std::forward<Output>(out));
}
else {
return iterator_buffer<remove_cvref_t<Output>, T>(std::forward<Output>(out));
} }
} }
@ -1823,17 +1840,14 @@ decltype(auto) get_appendable_buffer(Output&& out) {
if constexpr (is_container_push_backable<Output, T>::value) { if constexpr (is_container_push_backable<Output, T>::value) {
using Iterator_ = std::back_insert_iterator<remove_cvref_t<Output>>; using Iterator_ = std::back_insert_iterator<remove_cvref_t<Output>>;
return range_buffer<Iterator_, T>(std::forward<Output>(out)); return range_buffer<Iterator_, T>(std::forward<Output>(out));
} } else {
else {
using Iterator_ = std::insert_iterator<remove_cvref_t<Output>>; using Iterator_ = std::insert_iterator<remove_cvref_t<Output>>;
return range_buffer<Iterator_, T>(std::forward<Output>(out)); return range_buffer<Iterator_, T>(std::forward<Output>(out));
} }
} } else {
else {
return range_buffer<remove_cvref_t<Output>, T>(std::forward<Output>(out)); return range_buffer<remove_cvref_t<Output>, T>(std::forward<Output>(out));
} }
} } else {
else {
return get_buffer<T>(std::forward<Output>(out)); return get_buffer<T>(std::forward<Output>(out));
} }
} }
@ -1944,8 +1958,8 @@ struct out_storage {
using range = void; using range = void;
Out out_; Out out_;
template <typename Value, template <typename Value, FMT_ENABLE_IF(!std::is_same<remove_cvref_t<Value>,
FMT_ENABLE_IF(!std::is_same<remove_cvref_t<Value>, out_storage>::value)> out_storage>::value)>
FMT_CONSTEXPR out_storage(Value&& value) : out_(std::forward<Value>(value)) {} FMT_CONSTEXPR out_storage(Value&& value) : out_(std::forward<Value>(value)) {}
out_storage(out_storage&&) = default; out_storage(out_storage&&) = default;
@ -1955,15 +1969,14 @@ struct out_storage {
}; };
#if FMT_OUTPUT_RANGES #if FMT_OUTPUT_RANGES
template <typename OutRange> template <typename OutRange> struct out_storage<OutRange, true> {
struct out_storage<OutRange, true> {
using iterator = std::ranges::iterator_t<OutRange>; using iterator = std::ranges::iterator_t<OutRange>;
using sentinel = std::ranges::sentinel_t<OutRange>; using sentinel = std::ranges::sentinel_t<OutRange>;
using range = std::ranges::subrange<iterator, sentinel>; using range = std::ranges::subrange<iterator, sentinel>;
range out_; range out_;
template <typename Value, template <typename Value, FMT_ENABLE_IF(!std::is_same<remove_cvref_t<Value>,
FMT_ENABLE_IF(!std::is_same<remove_cvref_t<Value>, out_storage>::value)> out_storage>::value)>
FMT_CONSTEXPR out_storage(Value&& value) : out_(std::forward<Value>(value)) {} FMT_CONSTEXPR out_storage(Value&& value) : out_(std::forward<Value>(value)) {}
out_storage(out_storage&&) = default; out_storage(out_storage&&) = default;
@ -2086,10 +2099,9 @@ template <typename OutputIt, typename Char> class basic_format_context {
Storage_ out_storage_; Storage_ out_storage_;
basic_format_args<basic_format_context> args_; basic_format_args<basic_format_context> args_;
detail::locale_ref loc_; detail::locale_ref loc_;
using ItOrRange_ = conditional_t< using ItOrRange_ =
std::is_void<typename Storage_::range>::value, conditional_t<std::is_void<typename Storage_::range>::value,
typename Storage_::iterator, typename Storage_::iterator, typename Storage_::range>;
typename Storage_::range>;
public: public:
using iterator = typename Storage_::iterator; using iterator = typename Storage_::iterator;
@ -2132,9 +2144,11 @@ template <typename OutputIt, typename Char> class basic_format_context {
// Advances the begin iterator to ``it``. // Advances the begin iterator to ``it``.
void advance_to(ItOrRange_ it_or_range) { void advance_to(ItOrRange_ it_or_range) {
#if FMT_OUTPUT_RANGES #if FMT_OUTPUT_RANGES
if (!detail::is_back_insert_iterator<iterator>()) out_storage_.out_ = std::move(it_or_range); if (!detail::is_back_insert_iterator<iterator>())
out_storage_.out_ = std::move(it_or_range);
#else #else
if (!detail::is_back_insert_iterator<iterator>()) out_storage_.out_ = it_or_range; if (!detail::is_back_insert_iterator<iterator>())
out_storage_.out_ = it_or_range;
#endif #endif
} }
@ -3194,8 +3208,8 @@ FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)
rather than directly writing if it is a typical insertable rather than directly writing if it is a typical insertable
contianer type. */ contianer type. */
template <typename Output, template <typename Output,
FMT_ENABLE_IF(std::ranges::output_range<Output, char> FMT_ENABLE_IF(std::ranges::output_range<Output, char> ||
|| std::output_iterator<remove_cvref_t<Output>, char>)> std::output_iterator<remove_cvref_t<Output>, char>)>
auto vformat_to(Output&& out, string_view fmt, format_args args) { auto vformat_to(Output&& out, string_view fmt, format_args args) {
auto&& buf = detail::get_appendable_buffer<char>(std::forward<Output>(out)); auto&& buf = detail::get_appendable_buffer<char>(std::forward<Output>(out));
detail::vformat_to(buf, fmt, args, {}); detail::vformat_to(buf, fmt, args, {});
@ -3205,8 +3219,8 @@ auto vformat_to(Output&& out, string_view fmt, format_args args) {
/** Formats a string and writes the output to ``out``, writing /** Formats a string and writes the output to ``out``, writing
directly into the range [begin, end). */ directly into the range [begin, end). */
template <typename Output, template <typename Output,
FMT_ENABLE_IF(std::ranges::output_range<Output, char> FMT_ENABLE_IF(std::ranges::output_range<Output, char> ||
|| std::output_iterator<remove_cvref_t<Output>, char>)> std::output_iterator<remove_cvref_t<Output>, char>)>
auto vformat_into(Output&& out, string_view fmt, format_args args) { auto vformat_into(Output&& out, string_view fmt, format_args args) {
auto&& buf = detail::get_buffer<char>(std::forward<Output>(out)); auto&& buf = detail::get_buffer<char>(std::forward<Output>(out));
detail::vformat_to(buf, fmt, args, {}); detail::vformat_to(buf, fmt, args, {});
@ -3229,7 +3243,8 @@ auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt {
Formats ``args`` according to specifications in ``fmt``, writes the result to Formats ``args`` according to specifications in ``fmt``, writes the result to
the output range or iterator ``out`` and returns the subrange past the end of the output range or iterator ``out`` and returns the subrange past the end of
the output range. `format_to` will write to the end of a container (if it is an the output range. `format_to` will write to the end of a container (if it is an
insertable container). `format_to` does not append a terminating null character. insertable container). `format_to` does not append a terminating null
character.
**Example**:: **Example**::
@ -3243,18 +3258,20 @@ auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt {
\endrst \endrst
*/ */
template <typename Output, typename... T, template <typename Output, typename... T,
FMT_ENABLE_IF(std::ranges::output_range<Output, char> FMT_ENABLE_IF(std::ranges::output_range<Output, char> ||
|| std::output_iterator<remove_cvref_t<Output>, char>)> std::output_iterator<remove_cvref_t<Output>, char>)>
FMT_INLINE auto format_to(Output&& out, format_string<T...> fmt, T&&... args) { FMT_INLINE auto format_to(Output&& out, format_string<T...> fmt, T&&... args) {
return vformat_to(std::forward<Output>(out), fmt, fmt::make_format_args(args...)); return vformat_to(std::forward<Output>(out), fmt,
fmt::make_format_args(args...));
} }
/** /**
\rst \rst
Formats ``args`` according to specifications in ``fmt``, writes the result into Formats ``args`` according to specifications in ``fmt``, writes the result into
the output range or iterator ``out`` and returns the subrange past the end of the output range or iterator ``out`` and returns the subrange past the end of
the output range. `format_into` does not append into a contianer and only writes the output range. `format_into` does not append into a contianer and only
into it. `format_into` does not append or write a terminating null character. writes into it. `format_into` does not append or write a terminating null
character.
**Example**:: **Example**::
@ -3263,10 +3280,12 @@ FMT_INLINE auto format_to(Output&& out, format_string<T...> fmt, T&&... args) {
\endrst \endrst
*/ */
template <typename Output, typename... T, template <typename Output, typename... T,
FMT_ENABLE_IF(std::ranges::output_range<Output, char> FMT_ENABLE_IF(std::ranges::output_range<Output, char> ||
|| std::output_iterator<remove_cvref_t<Output>, char>)> std::output_iterator<remove_cvref_t<Output>, char>)>
FMT_INLINE auto format_into(Output&& out, format_string<T...> fmt, T&&... args) { FMT_INLINE auto format_into(Output&& out, format_string<T...> fmt,
return vformat_into(std::forward<Output>(out), fmt, fmt::make_format_args(args...)); T&&... args) {
return vformat_into(std::forward<Output>(out), fmt,
fmt::make_format_args(args...));
} }
#else #else
/** /**

View File

@ -1063,8 +1063,8 @@ namespace detail_exported {
#if FMT_USE_NONTYPE_TEMPLATE_ARGS #if FMT_USE_NONTYPE_TEMPLATE_ARGS
template <typename Char, size_t N> struct fixed_string { template <typename Char, size_t N> struct fixed_string {
constexpr fixed_string(const Char (&str)[N]) { constexpr fixed_string(const Char (&str)[N]) {
detail::copy_str<Char, const Char*, const Char*, Char*>(static_cast<const Char*>(str), detail::copy_str<Char, const Char*, const Char*, Char*>(
static_cast<const Char*>(str + N), data); static_cast<const Char*>(str), static_cast<const Char*>(str + N), data);
} }
Char data[N] = {}; Char data[N] = {};
}; };
@ -1161,10 +1161,10 @@ using uint32_or_64_or_128_t =
template <typename T> template <typename T>
using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>; using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>;
#define FMT_POWERS_OF_10(factor) \ #define FMT_POWERS_OF_10(factor) \
factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, \ factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
(factor) * 100000, (factor) * 1000000, (factor) * 10000000, \ (factor)*1000000, (factor)*10000000, (factor)*100000000, \
(factor) * 100000000, (factor) * 1000000000 (factor)*1000000000
// Converts value in the range [0, 100) to a string. // Converts value in the range [0, 100) to a string.
constexpr const char* digits2(size_t value) { constexpr const char* digits2(size_t value) {
@ -4543,10 +4543,9 @@ inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
#if FMT_OUTPUT_RANGES #if FMT_OUTPUT_RANGES
template <typename Output, typename Locale, template <typename Output, typename Locale,
FMT_ENABLE_IF( FMT_ENABLE_IF((std::ranges::output_range<Output, char> ||
(std::ranges::output_range<Output, char> std::output_iterator<
|| std::output_iterator<Output, char>) Output, char>)&&detail::is_locale<Locale>::value)>
&& detail::is_locale<Locale>::value)>
auto vformat_to(Output&& out, const Locale& loc, string_view fmt, auto vformat_to(Output&& out, const Locale& loc, string_view fmt,
format_args args) { format_args args) {
auto&& buf = detail::get_appendable_buffer<char>(std::forward<Output>(out)); auto&& buf = detail::get_appendable_buffer<char>(std::forward<Output>(out));
@ -4555,12 +4554,11 @@ auto vformat_to(Output&& out, const Locale& loc, string_view fmt,
} }
template <typename Output, typename Locale, template <typename Output, typename Locale,
FMT_ENABLE_IF( FMT_ENABLE_IF((std::ranges::output_range<Output, char> ||
(std::ranges::output_range<Output, char> std::output_iterator<
|| std::output_iterator<Output, char>) Output, char>)&&detail::is_locale<Locale>::value)>
&& detail::is_locale<Locale>::value)>
auto vformat_into(Output&& out, const Locale& loc, string_view fmt, auto vformat_into(Output&& out, const Locale& loc, string_view fmt,
format_args args) { format_args args) {
auto&& buf = detail::get_buffer<char>(std::forward<Output>(out)); auto&& buf = detail::get_buffer<char>(std::forward<Output>(out));
detail::vformat_to(buf, fmt, args, detail::locale_ref(loc)); detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
return detail::get_iterator(buf, out); return detail::get_iterator(buf, out);
@ -4568,22 +4566,24 @@ auto vformat_into(Output&& out, const Locale& loc, string_view fmt,
template <typename Output, typename Locale, typename... T, template <typename Output, typename Locale, typename... T,
FMT_ENABLE_IF( FMT_ENABLE_IF(
(std::ranges::output_range<Output, char> (std::ranges::output_range<Output, char> ||
|| std::output_iterator<remove_cvref_t<Output>, char>) std::output_iterator<remove_cvref_t<Output>,
&& detail::is_locale<Locale>::value)> char>)&&detail::is_locale<Locale>::value)>
FMT_INLINE auto format_to(Output&& out, const Locale& loc, FMT_INLINE auto format_to(Output&& out, const Locale& loc,
format_string<T...> fmt, T&&... args) { format_string<T...> fmt, T&&... args) {
return vformat_to(std::forward<Output>(out), loc, fmt, fmt::make_format_args(args...)); return vformat_to(std::forward<Output>(out), loc, fmt,
fmt::make_format_args(args...));
} }
template <typename Output, typename Locale, typename... T, template <typename Output, typename Locale, typename... T,
FMT_ENABLE_IF( FMT_ENABLE_IF(
(std::ranges::output_range<Output, char> (std::ranges::output_range<Output, char> ||
|| std::output_iterator<remove_cvref_t<Output>, char>) std::output_iterator<remove_cvref_t<Output>,
&& detail::is_locale<Locale>::value)> char>)&&detail::is_locale<Locale>::value)>
FMT_INLINE auto format_into(Output&& out, const Locale& loc, FMT_INLINE auto format_into(Output&& out, const Locale& loc,
format_string<T...> fmt, T&&... args) { format_string<T...> fmt, T&&... args) {
return vformat_into(std::forward<Output>(out), loc, fmt, fmt::make_format_args(args...)); return vformat_into(std::forward<Output>(out), loc, fmt,
fmt::make_format_args(args...));
} }
#else #else
template <typename OutputIt, typename Locale, template <typename OutputIt, typename Locale,

View File

@ -140,55 +140,57 @@ inline auto format(const Locale& loc, const S& format_str, T&&... args)
#if FMT_OUTPUT_RANGES #if FMT_OUTPUT_RANGES
template <typename Output, typename S, typename Char = char_t<S>, template <typename Output, typename S, typename Char = char_t<S>,
FMT_ENABLE_IF((std::ranges::output_range<Output, Char> FMT_ENABLE_IF((
|| std::output_iterator<remove_cvref_t<Output>, Char>) std::ranges::output_range<Output, Char> ||
&& detail::is_exotic_char<Char>::value)> std::output_iterator<remove_cvref_t<Output>,
Char>)&&detail::is_exotic_char<Char>::value)>
auto vformat_to(Output&& out, const S& format_str, auto vformat_to(Output&& out, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) basic_format_args<buffer_context<type_identity_t<Char>>> args) {
{
auto&& buf = detail::get_appendable_buffer<Char>(std::forward<Output>(out)); auto&& buf = detail::get_appendable_buffer<Char>(std::forward<Output>(out));
detail::vformat_to(buf, detail::to_string_view(format_str), args); detail::vformat_to(buf, detail::to_string_view(format_str), args);
return detail::get_iterator(buf, out); return detail::get_iterator(buf, out);
} }
template <typename Output, typename S, typename Char = char_t<S>, template <typename Output, typename S, typename Char = char_t<S>,
FMT_ENABLE_IF((std::ranges::output_range<Output, Char> FMT_ENABLE_IF((
|| std::output_iterator<remove_cvref_t<Output>, Char>) std::ranges::output_range<Output, Char> ||
&& detail::is_exotic_char<Char>::value)> std::output_iterator<remove_cvref_t<Output>,
auto vformat_into(Output&& out, const S& format_str, Char>)&&detail::is_exotic_char<Char>::value)>
basic_format_args<buffer_context<type_identity_t<Char>>> args) auto vformat_into(
{ Output&& out, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
auto&& buf = detail::get_buffer<Char>(std::forward<Output>(out)); auto&& buf = detail::get_buffer<Char>(std::forward<Output>(out));
detail::vformat_to(buf, detail::to_string_view(format_str), args); detail::vformat_to(buf, detail::to_string_view(format_str), args);
return detail::get_iterator(buf, out); return detail::get_iterator(buf, out);
} }
template <typename Output, typename S, typename... T, template <typename Output, typename S, typename... T, typename Char = char_t<S>,
typename Char = char_t<S>, FMT_ENABLE_IF((
FMT_ENABLE_IF((std::ranges::output_range<Output, Char> std::ranges::output_range<Output, Char> ||
|| std::output_iterator<remove_cvref_t<Output>, Char>) std::output_iterator<remove_cvref_t<Output>,
&& detail::is_exotic_char<Char>::value)> Char>)&&detail::is_exotic_char<Char>::value)>
inline auto format_to(Output&& out, const S& fmt, T&&... args) { inline auto format_to(Output&& out, const S& fmt, T&&... args) {
return vformat_to(std::forward<Output>(out), detail::to_string_view(fmt), return vformat_to(std::forward<Output>(out), detail::to_string_view(fmt),
fmt::make_format_args<buffer_context<Char>>(args...)); fmt::make_format_args<buffer_context<Char>>(args...));
} }
template <typename Output, typename S, typename... T, template <typename Output, typename S, typename... T, typename Char = char_t<S>,
typename Char = char_t<S>, FMT_ENABLE_IF((
FMT_ENABLE_IF((std::ranges::output_range<Output, Char> std::ranges::output_range<Output, Char> ||
|| std::output_iterator<remove_cvref_t<Output>, Char>) std::output_iterator<remove_cvref_t<Output>,
&& detail::is_exotic_char<Char>::value)> Char>)&&detail::is_exotic_char<Char>::value)>
inline auto format_into(Output&& out, const S& fmt, T&&... args) { inline auto format_into(Output&& out, const S& fmt, T&&... args) {
return vformat_into(std::forward<Output>(out), detail::to_string_view(fmt), return vformat_into(std::forward<Output>(out), detail::to_string_view(fmt),
fmt::make_format_args<buffer_context<Char>>(args...)); fmt::make_format_args<buffer_context<Char>>(args...));
} }
template <typename Locale, typename S, typename Output, typename... Args, template <typename Locale, typename S, typename Output, typename... Args,
typename Char = char_t<S>, typename Char = char_t<S>,
FMT_ENABLE_IF((std::ranges::output_range<Output, Char> FMT_ENABLE_IF(
|| std::output_iterator<remove_cvref_t<Output>, Char>) (std::ranges::output_range<Output, Char> ||
&& detail::is_locale<Locale>::value std::output_iterator<remove_cvref_t<Output>,
&& detail::is_exotic_char<Char>::value)> Char>)&&detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat_to( inline auto vformat_to(
Output&& out, const Locale& loc, const S& format_str, Output&& out, const Locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) { basic_format_args<buffer_context<type_identity_t<Char>>> args) {
@ -200,10 +202,11 @@ inline auto vformat_to(
template <typename Locale, typename S, typename Output, typename... Args, template <typename Locale, typename S, typename Output, typename... Args,
typename Char = char_t<S>, typename Char = char_t<S>,
FMT_ENABLE_IF((std::ranges::output_range<Output, Char> FMT_ENABLE_IF(
|| std::output_iterator<remove_cvref_t<Output>, Char>) (std::ranges::output_range<Output, Char> ||
&& detail::is_locale<Locale>::value std::output_iterator<remove_cvref_t<Output>,
&& detail::is_exotic_char<Char>::value)> Char>)&&detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat_into( inline auto vformat_into(
Output&& out, const Locale& loc, const S& format_str, Output&& out, const Locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) { basic_format_args<buffer_context<type_identity_t<Char>>> args) {
@ -216,29 +219,29 @@ inline auto vformat_into(
template < template <
typename Output, typename Locale, typename S, typename... T, typename Output, typename Locale, typename S, typename... T,
typename Char = char_t<S>, typename Char = char_t<S>,
bool enable = (std::ranges::output_range<Output, Char> bool enable = (std::ranges::output_range<Output, Char> ||
|| std::output_iterator<remove_cvref_t<Output>, Char>) std::output_iterator<remove_cvref_t<Output>, Char>)&&detail::
&& detail::is_locale<Locale>::value is_locale<Locale>::value&& detail::is_exotic_char<Char>::value,
&& detail::is_exotic_char<Char>::value,
FMT_ENABLE_IF(enable)> FMT_ENABLE_IF(enable)>
inline auto format_to(Output&& out, const Locale& loc, const S& format_str, inline auto format_to(Output&& out, const Locale& loc, const S& format_str,
T&&... args) { T&&... args) {
return vformat_to(std::forward<Output>(out), loc, detail::to_string_view(format_str), return vformat_to(std::forward<Output>(out), loc,
detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...)); fmt::make_format_args<buffer_context<Char>>(args...));
} }
template < template <
typename Output, typename Locale, typename S, typename... T, typename Output, typename Locale, typename S, typename... T,
typename Char = char_t<S>, typename Char = char_t<S>,
bool enable = (std::ranges::output_range<Output, Char> bool enable = (std::ranges::output_range<Output, Char> ||
|| std::output_iterator<remove_cvref_t<Output>, Char>) std::output_iterator<remove_cvref_t<Output>, Char>)&&detail::
&& detail::is_locale<Locale>::value is_locale<Locale>::value&& detail::is_exotic_char<Char>::value,
&& detail::is_exotic_char<Char>::value,
FMT_ENABLE_IF(enable)> FMT_ENABLE_IF(enable)>
inline auto format_into(Output&& out, const Locale& loc, const S& format_str, inline auto format_into(Output&& out, const Locale& loc, const S& format_str,
T&&... args) { T&&... args) {
return vformat_into(std::forward<Output>(out), loc, detail::to_string_view(format_str), return vformat_into(std::forward<Output>(out), loc,
fmt::make_format_args<buffer_context<Char>>(args...)); detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
} }
#else #else
template <typename OutputIt, typename S, typename Char = char_t<S>, template <typename OutputIt, typename S, typename Char = char_t<S>,
@ -275,11 +278,11 @@ inline auto vformat_to(
return detail::get_iterator(buf, out); return detail::get_iterator(buf, out);
} }
template <typename OutputIt, typename Locale, typename S, typename... T, template <
typename Char = char_t<S>, typename OutputIt, typename Locale, typename S, typename... T,
bool enable = detail::is_output_iterator<OutputIt, Char>::value && typename Char = char_t<S>,
detail::is_locale<Locale>::value && bool enable = detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_exotic_char<Char>::value> detail::is_locale<Locale>::value&& detail::is_exotic_char<Char>::value>
inline auto format_to(OutputIt out, const Locale& loc, const S& format_str, inline auto format_to(OutputIt out, const Locale& loc, const S& format_str,
T&&... args) -> T&&... args) ->
typename std::enable_if<enable, OutputIt>::type { typename std::enable_if<enable, OutputIt>::type {

View File

@ -9,15 +9,15 @@
#if FMT_OUTPUT_RANGES #if FMT_OUTPUT_RANGES
#include "gmock/gmock.h" # include <array>
#include "gtest-extra.h" # include <deque>
#include "util.h" # include <list>
# include <span>
# include <vector>
#include <vector> # include "gmock/gmock.h"
#include <list> # include "gtest-extra.h"
#include <deque> # include "util.h"
#include <array>
#include <span>
TEST(output_range_c_array_char_test, format_into) { TEST(output_range_c_array_char_test, format_into) {
char buffer[4]; char buffer[4];
@ -166,12 +166,14 @@ TEST(output_range_list_char_test, format_to) {
auto result = fmt::format_to(buffer, "{}", "abc"); auto result = fmt::format_to(buffer, "{}", "abc");
EXPECT_EQ(buffer.end(), result.begin()); EXPECT_EQ(buffer.end(), result.begin());
EXPECT_EQ(std::ranges::next(buffer.begin(), 3), result.begin()); EXPECT_EQ(std::ranges::next(buffer.begin(), 3), result.begin());
EXPECT_EQ(std::ranges::next(buffer.begin(), (std::ptrdiff_t)buffer.size()), result.begin()); EXPECT_EQ(std::ranges::next(buffer.begin(), (std::ptrdiff_t)buffer.size()),
result.begin());
EXPECT_TRUE(std::ranges::equal(fmt::string_view("abc"), buffer)); EXPECT_TRUE(std::ranges::equal(fmt::string_view("abc"), buffer));
result = fmt::format_to(buffer, "x{}y", "abc"); result = fmt::format_to(buffer, "x{}y", "abc");
EXPECT_EQ(buffer.end(), result.begin()); EXPECT_EQ(buffer.end(), result.begin());
EXPECT_EQ(std::ranges::next(buffer.begin(), 8), result.begin()); EXPECT_EQ(std::ranges::next(buffer.begin(), 8), result.begin());
EXPECT_EQ(std::ranges::next(buffer.begin(), (std::ptrdiff_t)buffer.size()), result.begin()); EXPECT_EQ(std::ranges::next(buffer.begin(), (std::ptrdiff_t)buffer.size()),
result.begin());
EXPECT_TRUE(std::ranges::equal(fmt::string_view("abcxabcy"), buffer)); EXPECT_TRUE(std::ranges::equal(fmt::string_view("abcxabcy"), buffer));
} }
@ -180,12 +182,14 @@ TEST(output_range_deque_char_test, format_to) {
auto result = fmt::format_to(buffer, "{}", "abc"); auto result = fmt::format_to(buffer, "{}", "abc");
EXPECT_EQ(buffer.end(), result.begin()); EXPECT_EQ(buffer.end(), result.begin());
EXPECT_EQ(std::ranges::next(buffer.begin(), 3), result.begin()); EXPECT_EQ(std::ranges::next(buffer.begin(), 3), result.begin());
EXPECT_EQ(std::ranges::next(buffer.begin(), (std::ptrdiff_t)buffer.size()), result.begin()); EXPECT_EQ(std::ranges::next(buffer.begin(), (std::ptrdiff_t)buffer.size()),
result.begin());
EXPECT_TRUE(std::ranges::equal(fmt::string_view("abc"), buffer)); EXPECT_TRUE(std::ranges::equal(fmt::string_view("abc"), buffer));
result = fmt::format_to(buffer, "x{}y", "abc"); result = fmt::format_to(buffer, "x{}y", "abc");
EXPECT_EQ(buffer.end(), result.begin()); EXPECT_EQ(buffer.end(), result.begin());
EXPECT_EQ(std::ranges::next(buffer.begin(), 8), result.begin()); EXPECT_EQ(std::ranges::next(buffer.begin(), 8), result.begin());
EXPECT_EQ(std::ranges::next(buffer.begin(), (std::ptrdiff_t)buffer.size()), result.begin()); EXPECT_EQ(std::ranges::next(buffer.begin(), (std::ptrdiff_t)buffer.size()),
result.begin());
EXPECT_TRUE(std::ranges::equal(fmt::string_view("abcxabcy"), buffer)); EXPECT_TRUE(std::ranges::equal(fmt::string_view("abcxabcy"), buffer));
} }