aboutsummaryrefslogtreecommitdiff
path: root/lib/libcxx/include/__format
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-04-05 01:46:13 -0400
committerGitHub <noreply@github.com>2025-04-05 01:46:13 -0400
commit0cd31fc7ff157551cfbba5da35cd79f118d2a2e3 (patch)
treea308488f5d85184c8ec402fb3f55f1cf2704443e /lib/libcxx/include/__format
parent8acedfd5baabab705946ad097746f9183ef62420 (diff)
parentcefe65c1b8abe65a22d4b68410db1be264fdeda0 (diff)
downloadzig-0cd31fc7ff157551cfbba5da35cd79f118d2a2e3.tar.gz
zig-0cd31fc7ff157551cfbba5da35cd79f118d2a2e3.zip
Merge pull request #22780 from ziglang/llvm20
LLVM 20
Diffstat (limited to 'lib/libcxx/include/__format')
-rw-r--r--lib/libcxx/include/__format/buffer.h628
-rw-r--r--lib/libcxx/include/__format/concepts.h8
-rw-r--r--lib/libcxx/include/__format/container_adaptor.h6
-rw-r--r--lib/libcxx/include/__format/enable_insertable.h2
-rw-r--r--lib/libcxx/include/__format/escaped_output_table.h4
-rw-r--r--lib/libcxx/include/__format/extended_grapheme_cluster_table.h4
-rw-r--r--lib/libcxx/include/__format/format_arg.h37
-rw-r--r--lib/libcxx/include/__format/format_arg_store.h18
-rw-r--r--lib/libcxx/include/__format/format_args.h4
-rw-r--r--lib/libcxx/include/__format/format_context.h24
-rw-r--r--lib/libcxx/include/__format/format_error.h6
-rw-r--r--lib/libcxx/include/__format/format_functions.h77
-rw-r--r--lib/libcxx/include/__format/format_parse_context.h4
-rw-r--r--lib/libcxx/include/__format/format_string.h4
-rw-r--r--lib/libcxx/include/__format/format_to_n_result.h2
-rw-r--r--lib/libcxx/include/__format/formatter.h3
-rw-r--r--lib/libcxx/include/__format/formatter_bool.h8
-rw-r--r--lib/libcxx/include/__format/formatter_char.h14
-rw-r--r--lib/libcxx/include/__format/formatter_floating_point.h22
-rw-r--r--lib/libcxx/include/__format/formatter_integer.h37
-rw-r--r--lib/libcxx/include/__format/formatter_integral.h11
-rw-r--r--lib/libcxx/include/__format/formatter_output.h18
-rw-r--r--lib/libcxx/include/__format/formatter_pointer.h12
-rw-r--r--lib/libcxx/include/__format/formatter_string.h69
-rw-r--r--lib/libcxx/include/__format/formatter_tuple.h2
-rw-r--r--lib/libcxx/include/__format/indic_conjunct_break_table.h4
-rw-r--r--lib/libcxx/include/__format/parser_std_format_spec.h30
-rw-r--r--lib/libcxx/include/__format/range_default_formatter.h14
-rw-r--r--lib/libcxx/include/__format/range_formatter.h2
-rw-r--r--lib/libcxx/include/__format/unicode.h26
-rw-r--r--lib/libcxx/include/__format/width_estimation_table.h4
-rw-r--r--lib/libcxx/include/__format/write_escaped.h6
32 files changed, 620 insertions, 490 deletions
diff --git a/lib/libcxx/include/__format/buffer.h b/lib/libcxx/include/__format/buffer.h
index 8598f0a1c0..0c054bbc3a 100644
--- a/lib/libcxx/include/__format/buffer.h
+++ b/lib/libcxx/include/__format/buffer.h
@@ -14,6 +14,7 @@
#include <__algorithm/fill_n.h>
#include <__algorithm/max.h>
#include <__algorithm/min.h>
+#include <__algorithm/ranges_copy.h>
#include <__algorithm/ranges_copy_n.h>
#include <__algorithm/transform.h>
#include <__algorithm/unwrap_iter.h>
@@ -29,6 +30,7 @@
#include <__iterator/wrap_iter.h>
#include <__memory/addressof.h>
#include <__memory/allocate_at_least.h>
+#include <__memory/allocator.h>
#include <__memory/allocator_traits.h>
#include <__memory/construct_at.h>
#include <__memory/ranges_construct_at.h>
@@ -37,7 +39,7 @@
#include <__type_traits/conditional.h>
#include <__utility/exception_guard.h>
#include <__utility/move.h>
-#include <cstddef>
+#include <stdexcept>
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -53,24 +55,147 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace __format {
+// A helper to limit the total size of code units written.
+class _LIBCPP_HIDE_FROM_ABI __max_output_size {
+public:
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __max_output_size(size_t __max_size) : __max_size_{__max_size} {}
+
+ // This function adjusts the size of a (bulk) write operations. It ensures the
+ // number of code units written by a __output_buffer never exceeds
+ // __max_size_ code units.
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __write_request(size_t __code_units) {
+ size_t __result =
+ __code_units_written_ < __max_size_ ? std::min(__code_units, __max_size_ - __code_units_written_) : 0;
+ __code_units_written_ += __code_units;
+ return __result;
+ }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __code_units_written() const noexcept { return __code_units_written_; }
+
+private:
+ size_t __max_size_;
+ // The code units that would have been written if there was no limit.
+ // format_to_n returns this value.
+ size_t __code_units_written_{0};
+};
+
/// A "buffer" that handles writing to the proper iterator.
///
/// This helper is used together with the @ref back_insert_iterator to offer
/// type-erasure for the formatting functions. This reduces the number to
/// template instantiations.
+///
+/// The design is the following:
+/// - There is an external object that connects the buffer to the output.
+/// - This buffer object:
+/// - inherits publicly from this class.
+/// - has a static or dynamic buffer.
+/// - has a static member function to make space in its buffer write
+/// operations. This can be done by increasing the size of the internal
+/// buffer or by writing the contents of the buffer to the output iterator.
+///
+/// This member function is a constructor argument, so its name is not
+/// fixed. The code uses the name __prepare_write.
+/// - The number of output code units can be limited by a __max_output_size
+/// object. This is used in format_to_n This object:
+/// - Contains the maximum number of code units to be written.
+/// - Contains the number of code units that are requested to be written.
+/// This number is returned to the user of format_to_n.
+/// - The write functions call the object's __request_write member function.
+/// This function:
+/// - Updates the number of code units that are requested to be written.
+/// - Returns the number of code units that can be written without
+/// exceeding the maximum number of code units to be written.
+///
+/// Documentation for the buffer usage members:
+/// - __ptr_
+/// The start of the buffer.
+/// - __capacity_
+/// The number of code units that can be written. This means
+/// [__ptr_, __ptr_ + __capacity_) is a valid range to write to.
+/// - __size_
+/// The number of code units written in the buffer. The next code unit will
+/// be written at __ptr_ + __size_. This __size_ may NOT contain the total
+/// number of code units written by the __output_buffer. Whether or not it
+/// does depends on the sub-class used. Typically the total number of code
+/// units written is not interesting. It is interesting for format_to_n which
+/// has its own way to track this number.
+///
+/// Documentation for the modifying buffer operations:
+/// The subclasses have a function with the following signature:
+///
+/// static void __prepare_write(
+/// __output_buffer<_CharT>& __buffer, size_t __code_units);
+///
+/// This function is called when a write function writes more code units than
+/// the buffer's available space. When an __max_output_size object is provided
+/// the number of code units is the number of code units returned from
+/// __max_output_size::__request_write function.
+///
+/// - The __buffer contains *this. Since the class containing this function
+/// inherits from __output_buffer it's safe to cast it to the subclass being
+/// used.
+/// - The __code_units is the number of code units the caller will write + 1.
+/// - This value does not take the available space of the buffer into account.
+/// - The push_back function is more efficient when writing before resizing,
+/// this means the buffer should always have room for one code unit. Hence
+/// the + 1 is the size.
+/// - When the function returns there is room for at least one additional code
+/// unit. There is no requirement there is room for __code_units code units:
+/// - The class has some "bulk" operations. For example, __copy which copies
+/// the contents of a basic_string_view to the output. If the sub-class has
+/// a fixed size buffer the size of the basic_string_view may be larger
+/// than the buffer. In that case it's impossible to honor the requested
+/// size.
+/// - When the buffer has room for at least one code unit the function may be
+/// a no-op.
+/// - When the function makes space for more code units it uses one for these
+/// functions to signal the change:
+/// - __buffer_flushed()
+/// - This function is typically used for a fixed sized buffer.
+/// - The current contents of [__ptr_, __ptr_ + __size_) have been
+/// processed.
+/// - __ptr_ remains unchanged.
+/// - __capacity_ remains unchanged.
+/// - __size_ will be set to 0.
+/// - __buffer_moved(_CharT* __ptr, size_t __capacity)
+/// - This function is typically used for a dynamic sized buffer. There the
+/// location of the buffer changes due to reallocations.
+/// - __ptr_ will be set to __ptr. (This value may be the old value of
+/// __ptr_).
+/// - __capacity_ will be set to __capacity. (This value may be the old
+/// value of __capacity_).
+/// - __size_ remains unchanged,
+/// - The range [__ptr, __ptr + __size_) contains the original data of the
+/// range [__ptr_, __ptr_ + __size_).
+///
+/// The push_back function expects a valid buffer and a capacity of at least 1.
+/// This means:
+/// - The class is constructed with a valid buffer,
+/// - __buffer_moved is called with a valid buffer is used before the first
+/// write operation,
+/// - no write function is ever called, or
+/// - the class is constructed with a __max_output_size object with __max_size 0.
+///
+/// The latter option allows formatted_size to use the output buffer without
+/// ever writing anything to the buffer.
template <__fmt_char_type _CharT>
class _LIBCPP_TEMPLATE_VIS __output_buffer {
public:
- using value_type = _CharT;
+ using value_type _LIBCPP_NODEBUG = _CharT;
+ using __prepare_write_type _LIBCPP_NODEBUG = void (*)(__output_buffer<_CharT>&, size_t);
- template <class _Tp>
- _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr, size_t __capacity, _Tp* __obj)
- : __ptr_(__ptr),
- __capacity_(__capacity),
- __flush_([](_CharT* __p, size_t __n, void* __o) { static_cast<_Tp*>(__o)->__flush(__p, __n); }),
- __obj_(__obj) {}
+ [[nodiscard]]
+ _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr, size_t __capacity, __prepare_write_type __function)
+ : __output_buffer{__ptr, __capacity, __function, nullptr} {}
- _LIBCPP_HIDE_FROM_ABI void __reset(_CharT* __ptr, size_t __capacity) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(
+ _CharT* __ptr, size_t __capacity, __prepare_write_type __function, __max_output_size* __max_output_size)
+ : __ptr_(__ptr), __capacity_(__capacity), __prepare_write_(__function), __max_output_size_(__max_output_size) {}
+
+ _LIBCPP_HIDE_FROM_ABI void __buffer_flushed() { __size_ = 0; }
+
+ _LIBCPP_HIDE_FROM_ABI void __buffer_moved(_CharT* __ptr, size_t __capacity) {
__ptr_ = __ptr;
__capacity_ = __capacity;
}
@@ -79,12 +204,18 @@ public:
// Used in std::back_insert_iterator.
_LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) {
+ if (__max_output_size_ && __max_output_size_->__write_request(1) == 0)
+ return;
+
+ _LIBCPP_ASSERT_INTERNAL(
+ __ptr_ && __size_ < __capacity_ && __available() >= 1, "attempted to write outside the buffer");
+
__ptr_[__size_++] = __c;
// Profiling showed flushing after adding is more efficient than flushing
// when entering the function.
if (__size_ == __capacity_)
- __flush();
+ __prepare_write(0);
}
/// Copies the input __str to the buffer.
@@ -105,25 +236,20 @@ public:
// upper case. For integral these strings are short.
// TODO FMT Look at the improvements above.
size_t __n = __str.size();
-
- __flush_on_overflow(__n);
- if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <).
- std::copy_n(__str.data(), __n, std::addressof(__ptr_[__size_]));
- __size_ += __n;
- return;
+ if (__max_output_size_) {
+ __n = __max_output_size_->__write_request(__n);
+ if (__n == 0)
+ return;
}
- // The output doesn't fit in the internal buffer.
- // Copy the data in "__capacity_" sized chunks.
- _LIBCPP_ASSERT_INTERNAL(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
const _InCharT* __first = __str.data();
do {
- size_t __chunk = std::min(__n, __capacity_);
+ __prepare_write(__n);
+ size_t __chunk = std::min(__n, __available());
std::copy_n(__first, __chunk, std::addressof(__ptr_[__size_]));
- __size_ = __chunk;
+ __size_ += __chunk;
__first += __chunk;
__n -= __chunk;
- __flush();
} while (__n);
}
@@ -137,121 +263,59 @@ public:
_LIBCPP_ASSERT_INTERNAL(__first <= __last, "not a valid range");
size_t __n = static_cast<size_t>(__last - __first);
- __flush_on_overflow(__n);
- if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <).
- std::transform(__first, __last, std::addressof(__ptr_[__size_]), std::move(__operation));
- __size_ += __n;
- return;
+ if (__max_output_size_) {
+ __n = __max_output_size_->__write_request(__n);
+ if (__n == 0)
+ return;
}
- // The output doesn't fit in the internal buffer.
- // Transform the data in "__capacity_" sized chunks.
- _LIBCPP_ASSERT_INTERNAL(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
do {
- size_t __chunk = std::min(__n, __capacity_);
+ __prepare_write(__n);
+ size_t __chunk = std::min(__n, __available());
std::transform(__first, __first + __chunk, std::addressof(__ptr_[__size_]), __operation);
- __size_ = __chunk;
+ __size_ += __chunk;
__first += __chunk;
__n -= __chunk;
- __flush();
} while (__n);
}
/// A \c fill_n wrapper.
_LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) {
- __flush_on_overflow(__n);
- if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <).
- std::fill_n(std::addressof(__ptr_[__size_]), __n, __value);
- __size_ += __n;
- return;
+ if (__max_output_size_) {
+ __n = __max_output_size_->__write_request(__n);
+ if (__n == 0)
+ return;
}
- // The output doesn't fit in the internal buffer.
- // Fill the buffer in "__capacity_" sized chunks.
- _LIBCPP_ASSERT_INTERNAL(__size_ == 0, "the buffer should be flushed by __flush_on_overflow");
do {
- size_t __chunk = std::min(__n, __capacity_);
+ __prepare_write(__n);
+ size_t __chunk = std::min(__n, __available());
std::fill_n(std::addressof(__ptr_[__size_]), __chunk, __value);
- __size_ = __chunk;
+ __size_ += __chunk;
__n -= __chunk;
- __flush();
} while (__n);
}
- _LIBCPP_HIDE_FROM_ABI void __flush() {
- __flush_(__ptr_, __size_, __obj_);
- __size_ = 0;
- }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __capacity() const { return __capacity_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __size() const { return __size_; }
private:
_CharT* __ptr_;
size_t __capacity_;
size_t __size_{0};
- void (*__flush_)(_CharT*, size_t, void*);
- void* __obj_;
+ void (*__prepare_write_)(__output_buffer<_CharT>&, size_t);
+ __max_output_size* __max_output_size_;
- /// Flushes the buffer when the output operation would overflow the buffer.
- ///
- /// A simple approach for the overflow detection would be something along the
- /// lines:
- /// \code
- /// // The internal buffer is large enough.
- /// if (__n <= __capacity_) {
- /// // Flush when we really would overflow.
- /// if (__size_ + __n >= __capacity_)
- /// __flush();
- /// ...
- /// }
- /// \endcode
- ///
- /// This approach works for all cases but one:
- /// A __format_to_n_buffer_base where \ref __enable_direct_output is true.
- /// In that case the \ref __capacity_ of the buffer changes during the first
- /// \ref __flush. During that operation the output buffer switches from its
- /// __writer_ to its __storage_. The \ref __capacity_ of the former depends
- /// on the value of n, of the latter is a fixed size. For example:
- /// - a format_to_n call with a 10'000 char buffer,
- /// - the buffer is filled with 9'500 chars,
- /// - adding 1'000 elements would overflow the buffer so the buffer gets
- /// changed and the \ref __capacity_ decreases from 10'000 to
- /// __buffer_size (256 at the time of writing).
- ///
- /// This means that the \ref __flush for this class may need to copy a part of
- /// the internal buffer to the proper output. In this example there will be
- /// 500 characters that need this copy operation.
- ///
- /// Note it would be more efficient to write 500 chars directly and then swap
- /// the buffers. This would make the code more complex and \ref format_to_n is
- /// not the most common use case. Therefore the optimization isn't done.
- _LIBCPP_HIDE_FROM_ABI void __flush_on_overflow(size_t __n) {
- if (__size_ + __n >= __capacity_)
- __flush();
- }
-};
-
-/// A storage using an internal buffer.
-///
-/// This storage is used when writing a single element to the output iterator
-/// is expensive.
-template <__fmt_char_type _CharT>
-class _LIBCPP_TEMPLATE_VIS __internal_storage {
-public:
- _LIBCPP_HIDE_FROM_ABI _CharT* __begin() { return __buffer_; }
-
- static constexpr size_t __buffer_size = 256 / sizeof(_CharT);
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __available() const { return __capacity_ - __size_; }
-private:
- _CharT __buffer_[__buffer_size];
+ _LIBCPP_HIDE_FROM_ABI void __prepare_write(size_t __code_units) {
+ // Always have space for one additional code unit. This is a precondition of the push_back function.
+ __code_units += 1;
+ if (__available() < __code_units)
+ __prepare_write_(*this, __code_units + 1);
+ }
};
-/// A storage writing directly to the storage.
-///
-/// This requires the storage to be a contiguous buffer of \a _CharT.
-/// Since the output is directly written to the underlying storage this class
-/// is just an empty class.
-template <__fmt_char_type _CharT>
-class _LIBCPP_TEMPLATE_VIS __direct_storage {};
-
template <class _OutIt, class _CharT>
concept __enable_direct_output =
__fmt_char_type<_CharT> &&
@@ -260,40 +324,6 @@ concept __enable_direct_output =
// `#ifdef`.
|| same_as<_OutIt, __wrap_iter<_CharT*>>);
-/// Write policy for directly writing to the underlying output.
-template <class _OutIt, __fmt_char_type _CharT>
-class _LIBCPP_TEMPLATE_VIS __writer_direct {
-public:
- _LIBCPP_HIDE_FROM_ABI explicit __writer_direct(_OutIt __out_it) : __out_it_(__out_it) {}
-
- _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() { return __out_it_; }
-
- _LIBCPP_HIDE_FROM_ABI void __flush(_CharT*, size_t __n) {
- // _OutIt can be a __wrap_iter<CharT*>. Therefore the original iterator
- // is adjusted.
- __out_it_ += __n;
- }
-
-private:
- _OutIt __out_it_;
-};
-
-/// Write policy for copying the buffer to the output.
-template <class _OutIt, __fmt_char_type _CharT>
-class _LIBCPP_TEMPLATE_VIS __writer_iterator {
-public:
- _LIBCPP_HIDE_FROM_ABI explicit __writer_iterator(_OutIt __out_it) : __out_it_{std::move(__out_it)} {}
-
- _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return std::move(__out_it_); }
-
- _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) {
- __out_it_ = std::ranges::copy_n(__ptr, __n, std::move(__out_it_)).out;
- }
-
-private:
- _OutIt __out_it_;
-};
-
/// Concept to see whether a \a _Container is insertable.
///
/// The concept is used to validate whether multiple calls to a
@@ -311,196 +341,220 @@ concept __insertable =
/// Extract the container type of a \ref back_insert_iterator.
template <class _It>
struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container {
- using type = void;
+ using type _LIBCPP_NODEBUG = void;
};
template <__insertable _Container>
struct _LIBCPP_TEMPLATE_VIS __back_insert_iterator_container<back_insert_iterator<_Container>> {
- using type = _Container;
+ using type _LIBCPP_NODEBUG = _Container;
};
-/// Write policy for inserting the buffer in a container.
-template <class _Container>
-class _LIBCPP_TEMPLATE_VIS __writer_container {
+// A dynamically growing buffer.
+template <__fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __allocating_buffer : public __output_buffer<_CharT> {
public:
- using _CharT = typename _Container::value_type;
+ __allocating_buffer(const __allocating_buffer&) = delete;
+ __allocating_buffer& operator=(const __allocating_buffer&) = delete;
- _LIBCPP_HIDE_FROM_ABI explicit __writer_container(back_insert_iterator<_Container> __out_it)
- : __container_{__out_it.__get_container()} {}
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __allocating_buffer() : __allocating_buffer{nullptr} {}
- _LIBCPP_HIDE_FROM_ABI auto __out_it() { return std::back_inserter(*__container_); }
+ [[nodiscard]]
+ _LIBCPP_HIDE_FROM_ABI explicit __allocating_buffer(__max_output_size* __max_output_size)
+ : __output_buffer<_CharT>{__small_buffer_, __buffer_size_, __prepare_write, __max_output_size} {}
- _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) {
- __container_->insert(__container_->end(), __ptr, __ptr + __n);
+ _LIBCPP_HIDE_FROM_ABI ~__allocating_buffer() {
+ if (__ptr_ != __small_buffer_)
+ _Alloc{}.deallocate(__ptr_, this->__capacity());
}
-private:
- _Container* __container_;
-};
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, this->__size()}; }
-/// Selects the type of the writer used for the output iterator.
-template <class _OutIt, class _CharT>
-class _LIBCPP_TEMPLATE_VIS __writer_selector {
- using _Container = typename __back_insert_iterator_container<_OutIt>::type;
+private:
+ using _Alloc _LIBCPP_NODEBUG = allocator<_CharT>;
-public:
- using type =
- conditional_t<!same_as<_Container, void>,
- __writer_container<_Container>,
- conditional_t<__enable_direct_output<_OutIt, _CharT>,
- __writer_direct<_OutIt, _CharT>,
- __writer_iterator<_OutIt, _CharT>>>;
-};
+ // Since allocating is expensive the class has a small internal buffer. When
+ // its capacity is exceeded a dynamic buffer will be allocated.
+ static constexpr size_t __buffer_size_ = 256;
+ _CharT __small_buffer_[__buffer_size_];
-/// The generic formatting buffer.
-template <class _OutIt, __fmt_char_type _CharT>
- requires(output_iterator<_OutIt, const _CharT&>)
-class _LIBCPP_TEMPLATE_VIS __format_buffer {
- using _Storage =
- conditional_t<__enable_direct_output<_OutIt, _CharT>, __direct_storage<_CharT>, __internal_storage<_CharT>>;
+ _CharT* __ptr_{__small_buffer_};
-public:
- _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it)
- requires(same_as<_Storage, __internal_storage<_CharT>>)
- : __output_(__storage_.__begin(), __storage_.__buffer_size, this), __writer_(std::move(__out_it)) {}
+ _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) {
+ if (__capacity < __buffer_size_)
+ return;
- _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it)
- requires(same_as<_Storage, __direct_storage<_CharT>>)
- : __output_(std::__unwrap_iter(__out_it), size_t(-1), this), __writer_(std::move(__out_it)) {}
+ _LIBCPP_ASSERT_INTERNAL(__capacity > this->__capacity(), "the buffer must grow");
- _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return __output_.__make_output_iterator(); }
+ // _CharT is an implicit lifetime type so can be used without explicit
+ // construction or destruction.
+ _Alloc __alloc;
+ auto __result = std::__allocate_at_least(__alloc, __capacity);
+ std::copy_n(__ptr_, this->__size(), __result.ptr);
+ if (__ptr_ != __small_buffer_)
+ __alloc.deallocate(__ptr_, this->__capacity());
- _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { __writer_.__flush(__ptr, __n); }
+ __ptr_ = __result.ptr;
+ this->__buffer_moved(__ptr_, __result.count);
+ }
- _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && {
- __output_.__flush();
- return std::move(__writer_).__out_it();
+ _LIBCPP_HIDE_FROM_ABI void __prepare_write(size_t __size_hint) {
+ __grow_buffer(std::max<size_t>(this->__capacity() + __size_hint, this->__capacity() * 1.6));
}
-private:
- _LIBCPP_NO_UNIQUE_ADDRESS _Storage __storage_;
- __output_buffer<_CharT> __output_;
- typename __writer_selector<_OutIt, _CharT>::type __writer_;
+ _LIBCPP_HIDE_FROM_ABI static void __prepare_write(__output_buffer<_CharT>& __buffer, size_t __size_hint) {
+ static_cast<__allocating_buffer<_CharT>&>(__buffer).__prepare_write(__size_hint);
+ }
};
-/// A buffer that counts the number of insertions.
-///
-/// Since \ref formatted_size only needs to know the size, the output itself is
-/// discarded.
-template <__fmt_char_type _CharT>
-class _LIBCPP_TEMPLATE_VIS __formatted_size_buffer {
+// A buffer that directly writes to the underlying buffer.
+template <class _OutIt, __fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __direct_iterator_buffer : public __output_buffer<_CharT> {
public:
- _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return __output_.__make_output_iterator(); }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __direct_iterator_buffer(_OutIt __out_it)
+ : __direct_iterator_buffer{__out_it, nullptr} {}
- _LIBCPP_HIDE_FROM_ABI void __flush(const _CharT*, size_t __n) { __size_ += __n; }
+ [[nodiscard]]
+ _LIBCPP_HIDE_FROM_ABI explicit __direct_iterator_buffer(_OutIt __out_it, __max_output_size* __max_output_size)
+ : __output_buffer<_CharT>{std::__unwrap_iter(__out_it), __buffer_size, __prepare_write, __max_output_size},
+ __out_it_(__out_it) {}
- _LIBCPP_HIDE_FROM_ABI size_t __result() && {
- __output_.__flush();
- return __size_;
- }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return __out_it_ + this->__size(); }
private:
- __internal_storage<_CharT> __storage_;
- __output_buffer<_CharT> __output_{__storage_.__begin(), __storage_.__buffer_size, this};
- size_t __size_{0};
-};
+ // The function format_to expects a buffer large enough for the output. The
+ // function format_to_n has its own helper class that restricts the number of
+ // write options. So this function class can pretend to have an infinite
+ // buffer.
+ static constexpr size_t __buffer_size = -1;
+
+ _OutIt __out_it_;
-/// The base of a buffer that counts and limits the number of insertions.
-template <class _OutIt, __fmt_char_type _CharT, bool>
- requires(output_iterator<_OutIt, const _CharT&>)
-struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base {
- using _Size = iter_difference_t<_OutIt>;
+ _LIBCPP_HIDE_FROM_ABI static void
+ __prepare_write([[maybe_unused]] __output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) {
+ std::__throw_length_error("__direct_iterator_buffer");
+ }
+};
+// A buffer that writes its output to the end of a container.
+template <class _OutIt, __fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __container_inserter_buffer : public __output_buffer<_CharT> {
public:
- _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size)
- : __writer_(std::move(__out_it)), __max_size_(std::max(_Size(0), __max_size)) {}
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __container_inserter_buffer(_OutIt __out_it)
+ : __container_inserter_buffer{__out_it, nullptr} {}
- _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) {
- if (_Size(__size_) <= __max_size_)
- __writer_.__flush(__ptr, std::min(_Size(__n), __max_size_ - __size_));
- __size_ += __n;
+ [[nodiscard]]
+ _LIBCPP_HIDE_FROM_ABI explicit __container_inserter_buffer(_OutIt __out_it, __max_output_size* __max_output_size)
+ : __output_buffer<_CharT>{__small_buffer_, __buffer_size, __prepare_write, __max_output_size},
+ __container_{__out_it.__get_container()} {}
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __out_it() && {
+ __container_->insert(__container_->end(), __small_buffer_, __small_buffer_ + this->__size());
+ return std::back_inserter(*__container_);
}
-protected:
- __internal_storage<_CharT> __storage_;
- __output_buffer<_CharT> __output_{__storage_.__begin(), __storage_.__buffer_size, this};
- typename __writer_selector<_OutIt, _CharT>::type __writer_;
+private:
+ typename __back_insert_iterator_container<_OutIt>::type* __container_;
+
+ // This class uses a fixed size buffer and appends the elements in
+ // __buffer_size chunks. An alternative would be to use an allocating buffer
+ // and append the output in a single write operation. Benchmarking showed no
+ // performance difference.
+ static constexpr size_t __buffer_size = 256;
+ _CharT __small_buffer_[__buffer_size];
+
+ _LIBCPP_HIDE_FROM_ABI void __prepare_write() {
+ __container_->insert(__container_->end(), __small_buffer_, __small_buffer_ + this->__size());
+ this->__buffer_flushed();
+ }
- _Size __max_size_;
- _Size __size_{0};
+ _LIBCPP_HIDE_FROM_ABI static void
+ __prepare_write(__output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) {
+ static_cast<__container_inserter_buffer<_OutIt, _CharT>&>(__buffer).__prepare_write();
+ }
};
-/// The base of a buffer that counts and limits the number of insertions.
-///
-/// This version is used when \c __enable_direct_output<_OutIt, _CharT> == true.
-///
-/// This class limits the size available to the direct writer so it will not
-/// exceed the maximum number of code units.
+// A buffer that writes to an iterator.
+//
+// Unlike the __container_inserter_buffer this class' performance does benefit
+// from allocating and then inserting.
template <class _OutIt, __fmt_char_type _CharT>
- requires(output_iterator<_OutIt, const _CharT&>)
-class _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base<_OutIt, _CharT, true> {
- using _Size = iter_difference_t<_OutIt>;
-
+class _LIBCPP_TEMPLATE_VIS __iterator_buffer : public __allocating_buffer<_CharT> {
public:
- _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size)
- : __output_(std::__unwrap_iter(__out_it), __max_size, this),
- __writer_(std::move(__out_it)),
- __max_size_(__max_size) {
- if (__max_size <= 0) [[unlikely]]
- __output_.__reset(__storage_.__begin(), __storage_.__buffer_size);
- }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __iterator_buffer(_OutIt __out_it)
+ : __allocating_buffer<_CharT>{}, __out_it_{std::move(__out_it)} {}
- _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) {
- // A __flush to the direct writer happens in the following occasions:
- // - The format function has written the maximum number of allowed code
- // units. At this point it's no longer valid to write to this writer. So
- // switch to the internal storage. This internal storage doesn't need to
- // be written anywhere so the __flush for that storage writes no output.
- // - Like above, but the next "mass write" operation would overflow the
- // buffer. In that case the buffer is pre-emptively switched. The still
- // valid code units will be written separately.
- // - The format_to_n function is finished. In this case there's no need to
- // switch the buffer, but for simplicity the buffers are still switched.
- // When the __max_size <= 0 the constructor already switched the buffers.
- if (__size_ == 0 && __ptr != __storage_.__begin()) {
- __writer_.__flush(__ptr, __n);
- __output_.__reset(__storage_.__begin(), __storage_.__buffer_size);
- } else if (__size_ < __max_size_) {
- // Copies a part of the internal buffer to the output up to n characters.
- // See __output_buffer<_CharT>::__flush_on_overflow for more information.
- _Size __s = std::min(_Size(__n), __max_size_ - __size_);
- std::copy_n(__ptr, __s, __writer_.__out_it());
- __writer_.__flush(__ptr, __s);
- }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __iterator_buffer(_OutIt __out_it, __max_output_size* __max_output_size)
+ : __allocating_buffer<_CharT>{__max_output_size}, __out_it_{std::move(__out_it)} {}
- __size_ += __n;
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __out_it() && {
+ return std::ranges::copy(this->__view(), std::move(__out_it_)).out;
}
-protected:
- __internal_storage<_CharT> __storage_;
- __output_buffer<_CharT> __output_;
- __writer_direct<_OutIt, _CharT> __writer_;
+private:
+ _OutIt __out_it_;
+};
+
+// Selects the type of the buffer used for the output iterator.
+template <class _OutIt, __fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __buffer_selector {
+ using _Container _LIBCPP_NODEBUG = __back_insert_iterator_container<_OutIt>::type;
- _Size __max_size_;
- _Size __size_{0};
+public:
+ using type _LIBCPP_NODEBUG =
+ conditional_t<!same_as<_Container, void>,
+ __container_inserter_buffer<_OutIt, _CharT>,
+ conditional_t<__enable_direct_output<_OutIt, _CharT>,
+ __direct_iterator_buffer<_OutIt, _CharT>,
+ __iterator_buffer<_OutIt, _CharT>>>;
};
-/// The buffer that counts and limits the number of insertions.
+// A buffer that counts and limits the number of insertions.
template <class _OutIt, __fmt_char_type _CharT>
- requires(output_iterator<_OutIt, const _CharT&>)
-struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer final
- : public __format_to_n_buffer_base< _OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>> {
- using _Base = __format_to_n_buffer_base<_OutIt, _CharT, __enable_direct_output<_OutIt, _CharT>>;
- using _Size = iter_difference_t<_OutIt>;
+class _LIBCPP_TEMPLATE_VIS __format_to_n_buffer : private __buffer_selector<_OutIt, _CharT>::type {
+public:
+ using _Base _LIBCPP_NODEBUG = __buffer_selector<_OutIt, _CharT>::type;
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_to_n_buffer(_OutIt __out_it, iter_difference_t<_OutIt> __n)
+ : _Base{std::move(__out_it), std::addressof(__max_output_size_)},
+ __max_output_size_{__n < 0 ? size_t{0} : static_cast<size_t>(__n)} {}
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return _Base::__make_output_iterator(); }
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __result() && {
+ return {static_cast<_Base&&>(*this).__out_it(),
+ static_cast<iter_difference_t<_OutIt>>(__max_output_size_.__code_units_written())};
+ }
+
+private:
+ __max_output_size __max_output_size_;
+};
+// A buffer that counts the number of insertions.
+//
+// Since formatted_size only needs to know the size, the output itself is
+// discarded.
+template <__fmt_char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __formatted_size_buffer : private __output_buffer<_CharT> {
public:
- _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer(_OutIt __out_it, _Size __max_size)
- : _Base(std::move(__out_it), __max_size) {}
- _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return this->__output_.__make_output_iterator(); }
+ using _Base _LIBCPP_NODEBUG = __output_buffer<_CharT>;
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __formatted_size_buffer()
+ : _Base{nullptr, 0, __prepare_write, std::addressof(__max_output_size_)} {}
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return _Base::__make_output_iterator(); }
+
+ // This function does not need to be r-value qualified, however this is
+ // consistent with similar objects.
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __result() && { return __max_output_size_.__code_units_written(); }
+
+private:
+ __max_output_size __max_output_size_{0};
- _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __result() && {
- this->__output_.__flush();
- return {std::move(this->__writer_).__out_it(), this->__size_};
+ _LIBCPP_HIDE_FROM_ABI static void
+ __prepare_write([[maybe_unused]] __output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) {
+ // Note this function does not satisfy the requirement of giving a 1 code unit buffer.
+ _LIBCPP_ASSERT_INTERNAL(
+ false, "Since __max_output_size_.__max_size_ == 0 there should never be call to this function.");
}
};
@@ -524,14 +578,14 @@ public:
// would lead to a circular include with formatter for vector<bool>.
template <__fmt_char_type _CharT>
class _LIBCPP_TEMPLATE_VIS __retarget_buffer {
- using _Alloc = allocator<_CharT>;
+ using _Alloc _LIBCPP_NODEBUG = allocator<_CharT>;
public:
- using value_type = _CharT;
+ using value_type _LIBCPP_NODEBUG = _CharT;
struct __iterator {
- using difference_type = ptrdiff_t;
- using value_type = _CharT;
+ using difference_type _LIBCPP_NODEBUG = ptrdiff_t;
+ using value_type _LIBCPP_NODEBUG = _CharT;
_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer)
: __buffer_(std::addressof(__buffer)) {}
@@ -646,7 +700,7 @@ private:
} // namespace __format
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/concepts.h b/lib/libcxx/include/__format/concepts.h
index 13380e9b91..28297c612d 100644
--- a/lib/libcxx/include/__format/concepts.h
+++ b/lib/libcxx/include/__format/concepts.h
@@ -34,7 +34,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _CharT>
concept __fmt_char_type =
same_as<_CharT, char>
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
|| same_as<_CharT, wchar_t>
# endif
;
@@ -44,7 +44,7 @@ concept __fmt_char_type =
// (Note testing for (w)format_context would be a valid choice, but requires
// selecting the proper one depending on the type of _CharT.)
template <class _CharT>
-using __fmt_iter_for = _CharT*;
+using __fmt_iter_for _LIBCPP_NODEBUG = _CharT*;
template <class _Tp, class _Context, class _Formatter = typename _Context::template formatter_type<remove_const_t<_Tp>>>
concept __formattable_with =
@@ -75,8 +75,8 @@ template <class _Tp>
concept __fmt_pair_like =
__is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
-# endif //_LIBCPP_STD_VER >= 23
-#endif //_LIBCPP_STD_VER >= 20
+# endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/container_adaptor.h b/lib/libcxx/include/__format/container_adaptor.h
index 9f49ca03bf..48d42ee7d9 100644
--- a/lib/libcxx/include/__format/container_adaptor.h
+++ b/lib/libcxx/include/__format/container_adaptor.h
@@ -37,8 +37,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Adaptor, class _CharT>
struct _LIBCPP_TEMPLATE_VIS __formatter_container_adaptor {
private:
- using __maybe_const_container = __fmt_maybe_const<typename _Adaptor::container_type, _CharT>;
- using __maybe_const_adaptor = __maybe_const<is_const_v<__maybe_const_container>, _Adaptor>;
+ using __maybe_const_container _LIBCPP_NODEBUG = __fmt_maybe_const<typename _Adaptor::container_type, _CharT>;
+ using __maybe_const_adaptor _LIBCPP_NODEBUG = __maybe_const<is_const_v<__maybe_const_container>, _Adaptor>;
formatter<ranges::ref_view<__maybe_const_container>, _CharT> __underlying_;
public:
@@ -66,7 +66,7 @@ template <class _CharT, class _Tp, formattable<_CharT> _Container>
struct _LIBCPP_TEMPLATE_VIS formatter<stack<_Tp, _Container>, _CharT>
: public __formatter_container_adaptor<stack<_Tp, _Container>, _CharT> {};
-#endif //_LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/enable_insertable.h b/lib/libcxx/include/__format/enable_insertable.h
index 86ef94a325..29fe566ff0 100644
--- a/lib/libcxx/include/__format/enable_insertable.h
+++ b/lib/libcxx/include/__format/enable_insertable.h
@@ -28,7 +28,7 @@ inline constexpr bool __enable_insertable = false;
} // namespace __format
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/escaped_output_table.h b/lib/libcxx/include/__format/escaped_output_table.h
index f7be2dc61f..7a0b352398 100644
--- a/lib/libcxx/include/__format/escaped_output_table.h
+++ b/lib/libcxx/include/__format/escaped_output_table.h
@@ -63,7 +63,7 @@
#include <__algorithm/ranges_upper_bound.h>
#include <__config>
-#include <cstddef>
+#include <__cstddef/ptrdiff_t.h>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -856,7 +856,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[711] = {
// clang-format on
} // namespace __escaped_output_table
-#endif //_LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/extended_grapheme_cluster_table.h b/lib/libcxx/include/__format/extended_grapheme_cluster_table.h
index 48581d8a5d..7653a9e03b 100644
--- a/lib/libcxx/include/__format/extended_grapheme_cluster_table.h
+++ b/lib/libcxx/include/__format/extended_grapheme_cluster_table.h
@@ -63,8 +63,8 @@
#include <__algorithm/ranges_upper_bound.h>
#include <__config>
+#include <__cstddef/ptrdiff_t.h>
#include <__iterator/access.h>
-#include <cstddef>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -1656,7 +1656,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[1496] = {
} // namespace __extended_grapheme_custer_property_boundary
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_arg.h b/lib/libcxx/include/__format/format_arg.h
index aa02f81dc4..10f0ba9928 100644
--- a/lib/libcxx/include/__format/format_arg.h
+++ b/lib/libcxx/include/__format/format_arg.h
@@ -13,6 +13,7 @@
#include <__assert>
#include <__concepts/arithmetic.h>
#include <__config>
+#include <__cstddef/size_t.h>
#include <__format/concepts.h>
#include <__format/format_parse_context.h>
#include <__functional/invoke.h>
@@ -113,7 +114,7 @@ _LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_
case __format::__arg_t::__long_long:
return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__long_long_);
case __format::__arg_t::__i128:
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__i128_);
# else
__libcpp_unreachable();
@@ -123,7 +124,7 @@ _LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_
case __format::__arg_t::__unsigned_long_long:
return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_);
case __format::__arg_t::__u128:
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__u128_);
# else
__libcpp_unreachable();
@@ -148,7 +149,7 @@ _LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_
__libcpp_unreachable();
}
-# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
+# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
template <class _Rp, class _Visitor, class _Context>
_LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
@@ -164,7 +165,7 @@ _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<
case __format::__arg_t::__long_long:
return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__long_long_);
case __format::__arg_t::__i128:
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__i128_);
# else
__libcpp_unreachable();
@@ -174,7 +175,7 @@ _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<
case __format::__arg_t::__unsigned_long_long:
return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_);
case __format::__arg_t::__u128:
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__u128_);
# else
__libcpp_unreachable();
@@ -199,7 +200,7 @@ _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<
__libcpp_unreachable();
}
-# endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
+# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
/// Contains the values used in basic_format_arg.
///
@@ -207,7 +208,7 @@ _LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<
/// separate arrays.
template <class _Context>
class __basic_format_arg_value {
- using _CharT = typename _Context::char_type;
+ using _CharT _LIBCPP_NODEBUG = typename _Context::char_type;
public:
/// Contains the implementation for basic_format_arg::handle.
@@ -237,7 +238,7 @@ public:
unsigned __unsigned_;
long long __long_long_;
unsigned long long __unsigned_long_long_;
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
__int128_t __i128_;
__uint128_t __u128_;
# endif
@@ -261,7 +262,7 @@ public:
_LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(long long __value) noexcept : __long_long_(__value) {}
_LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(unsigned long long __value) noexcept
: __unsigned_long_long_(__value) {}
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
_LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__int128_t __value) noexcept : __i128_(__value) {}
_LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__uint128_t __value) noexcept : __u128_(__value) {}
# endif
@@ -276,7 +277,7 @@ public:
};
template <class _Context>
-class _LIBCPP_TEMPLATE_VIS basic_format_arg {
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS basic_format_arg {
public:
class _LIBCPP_TEMPLATE_VIS handle;
@@ -284,14 +285,14 @@ public:
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return __type_ != __format::__arg_t::__none; }
-# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
+# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
// This function is user facing, so it must wrap the non-standard types of
// the "variant" in a handle to stay conforming. See __arg_t for more details.
template <class _Visitor>
_LIBCPP_HIDE_FROM_ABI decltype(auto) visit(this basic_format_arg __arg, _Visitor&& __vis) {
switch (__arg.__type_) {
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
case __format::__arg_t::__i128: {
typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_};
return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
@@ -312,7 +313,7 @@ public:
template <class _Rp, class _Visitor>
_LIBCPP_HIDE_FROM_ABI _Rp visit(this basic_format_arg __arg, _Visitor&& __vis) {
switch (__arg.__type_) {
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
case __format::__arg_t::__i128: {
typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_};
return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
@@ -328,7 +329,7 @@ public:
}
}
-# endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
+# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
private:
using char_type = typename _Context::char_type;
@@ -370,13 +371,13 @@ private:
// This function is user facing, so it must wrap the non-standard types of
// the "variant" in a handle to stay conforming. See __arg_t for more details.
template <class _Visitor, class _Context>
-# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
+# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
_LIBCPP_DEPRECATED_IN_CXX26
# endif
_LIBCPP_HIDE_FROM_ABI decltype(auto)
visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
switch (__arg.__type_) {
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
case __format::__arg_t::__i128: {
typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_};
return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
@@ -386,13 +387,13 @@ _LIBCPP_DEPRECATED_IN_CXX26
typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_};
return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h});
}
-# endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
+# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
default:
return std::__visit_format_arg(std::forward<_Visitor>(__vis), __arg);
}
}
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_arg_store.h b/lib/libcxx/include/__format/format_arg_store.h
index 23a599e995..4c5ee9e9e4 100644
--- a/lib/libcxx/include/__format/format_arg_store.h
+++ b/lib/libcxx/include/__format/format_arg_store.h
@@ -22,6 +22,7 @@
#include <__type_traits/conditional.h>
#include <__type_traits/extent.h>
#include <__type_traits/remove_const.h>
+#include <cstdint>
#include <string>
#include <string_view>
@@ -48,7 +49,7 @@ template <class _Context, same_as<typename _Context::char_type> _Tp>
consteval __arg_t __determine_arg_t() {
return __arg_t::__char_type;
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <class _Context, class _CharT>
requires(same_as<typename _Context::char_type, wchar_t> && same_as<_CharT, char>)
consteval __arg_t __determine_arg_t() {
@@ -63,7 +64,7 @@ consteval __arg_t __determine_arg_t() {
return __arg_t::__int;
else if constexpr (sizeof(_Tp) <= sizeof(long long))
return __arg_t::__long_long;
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
else if constexpr (sizeof(_Tp) == sizeof(__int128_t))
return __arg_t::__i128;
# endif
@@ -78,7 +79,7 @@ consteval __arg_t __determine_arg_t() {
return __arg_t::__unsigned;
else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long))
return __arg_t::__unsigned_long_long;
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
else if constexpr (sizeof(_Tp) == sizeof(__uint128_t))
return __arg_t::__u128;
# endif
@@ -172,7 +173,7 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp& __valu
// final else requires no adjustment.
if constexpr (__arg == __arg_t::__char_type)
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
if constexpr (same_as<typename _Context::char_type, wchar_t> && same_as<_Dp, char>)
return basic_format_arg<_Context>{__arg, static_cast<wchar_t>(static_cast<unsigned char>(__value))};
else
@@ -233,6 +234,11 @@ struct __packed_format_arg_store {
uint64_t __types_ = 0;
};
+template <class _Context>
+struct __packed_format_arg_store<_Context, 0> {
+ uint64_t __types_ = 0;
+};
+
template <class _Context, size_t _Np>
struct __unpacked_format_arg_store {
basic_format_arg<_Context> __args_[_Np];
@@ -251,7 +257,7 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
}
}
- using _Storage =
+ using _Storage _LIBCPP_NODEBUG =
conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)),
__format::__packed_format_arg_store<_Context, sizeof...(_Args)>,
__format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>;
@@ -259,7 +265,7 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
_Storage __storage;
};
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_args.h b/lib/libcxx/include/__format/format_args.h
index 07923570f3..b98663c06e 100644
--- a/lib/libcxx/include/__format/format_args.h
+++ b/lib/libcxx/include/__format/format_args.h
@@ -11,10 +11,10 @@
#define _LIBCPP___FORMAT_FORMAT_ARGS_H
#include <__config>
+#include <__cstddef/size_t.h>
#include <__format/format_arg.h>
#include <__format/format_arg_store.h>
#include <__fwd/format.h>
-#include <cstddef>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -71,7 +71,7 @@ private:
template <class _Context, class... _Args>
basic_format_args(__format_arg_store<_Context, _Args...>) -> basic_format_args<_Context>;
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_context.h b/lib/libcxx/include/__format/format_context.h
index 20c07559ea..4dbfdbc02a 100644
--- a/lib/libcxx/include/__format/format_context.h
+++ b/lib/libcxx/include/__format/format_context.h
@@ -23,9 +23,8 @@
#include <__memory/addressof.h>
#include <__utility/move.h>
#include <__variant/monostate.h>
-#include <cstddef>
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#if _LIBCPP_HAS_LOCALIZATION
# include <__locale>
# include <optional>
#endif
@@ -45,7 +44,7 @@ template <class _OutIt, class _CharT>
requires output_iterator<_OutIt, const _CharT&>
class _LIBCPP_TEMPLATE_VIS basic_format_context;
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
/**
* Helper to create a basic_format_context.
*
@@ -67,7 +66,7 @@ __format_context_create(_OutIt __out_it, basic_format_args<basic_format_context<
# endif
using format_context = basic_format_context<back_insert_iterator<__format::__output_buffer<char>>, char>;
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
using wformat_context = basic_format_context< back_insert_iterator<__format::__output_buffer<wchar_t>>, wchar_t>;
# endif
@@ -89,7 +88,7 @@ public:
_LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> arg(size_t __id) const noexcept {
return __args_.get(__id);
}
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
_LIBCPP_HIDE_FROM_ABI std::locale locale() {
if (!__loc_)
__loc_ = std::locale{};
@@ -102,7 +101,7 @@ public:
private:
iterator __out_it_;
basic_format_args<basic_format_context> __args_;
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
// The Standard doesn't specify how the locale is stored.
// [format.context]/6
@@ -132,6 +131,7 @@ private:
: __out_it_(std::move(__out_it)), __args_(__args) {}
# endif
+public:
basic_format_context(const basic_format_context&) = delete;
basic_format_context& operator=(const basic_format_context&) = delete;
};
@@ -163,7 +163,7 @@ public:
template <class _Context>
_LIBCPP_HIDE_FROM_ABI explicit basic_format_context(iterator __out_it, _Context& __ctx)
: __out_it_(std::move(__out_it)),
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
__loc_([](void* __c) { return static_cast<_Context*>(__c)->locale(); }),
# endif
__ctx_(std::addressof(__ctx)),
@@ -180,20 +180,20 @@ public:
__format::__determine_arg_t<basic_format_context, decltype(__arg)>(),
__basic_format_arg_value<basic_format_context>(__arg)};
};
-# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
+# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
return static_cast<_Context*>(__c)->arg(__id).visit(std::move(__visitor));
# else
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
return std::visit_format_arg(std::move(__visitor), static_cast<_Context*>(__c)->arg(__id));
_LIBCPP_SUPPRESS_DEPRECATED_POP
-# endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
+# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
}) {
}
_LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> arg(size_t __id) const noexcept {
return __arg_(__ctx_, __id);
}
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
_LIBCPP_HIDE_FROM_ABI std::locale locale() { return __loc_(__ctx_); }
# endif
_LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); }
@@ -202,7 +202,7 @@ public:
private:
iterator __out_it_;
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
std::locale (*__loc_)(void* __ctx);
# endif
@@ -211,7 +211,7 @@ private:
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_error.h b/lib/libcxx/include/__format/format_error.h
index ed40e395d6..b92e6d1de0 100644
--- a/lib/libcxx/include/__format/format_error.h
+++ b/lib/libcxx/include/__format/format_error.h
@@ -35,15 +35,15 @@ public:
};
_LIBCPP_DIAGNOSTIC_POP
-_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_format_error(const char* __s) {
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+[[noreturn]] inline _LIBCPP_HIDE_FROM_ABI void __throw_format_error(const char* __s) {
+# if _LIBCPP_HAS_EXCEPTIONS
throw format_error(__s);
# else
_LIBCPP_VERBOSE_ABORT("format_error was thrown in -fno-exceptions mode with message \"%s\"", __s);
# endif
}
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_functions.h b/lib/libcxx/include/__format/format_functions.h
index d14b49aff1..5feaf7e5a0 100644
--- a/lib/libcxx/include/__format/format_functions.h
+++ b/lib/libcxx/include/__format/format_functions.h
@@ -31,7 +31,6 @@
#include <__format/formatter_pointer.h>
#include <__format/formatter_string.h>
#include <__format/parser_std_format_spec.h>
-#include <__iterator/back_insert_iterator.h>
#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h> // iter_value_t
@@ -40,7 +39,7 @@
#include <string>
#include <string_view>
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#if _LIBCPP_HAS_LOCALIZATION
# include <__locale>
#endif
@@ -61,7 +60,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// to do this optimization now.
using format_args = basic_format_args<format_context>;
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
using wformat_args = basic_format_args<wformat_context>;
# endif
@@ -70,7 +69,7 @@ template <class _Context = format_context, class... _Args>
return std::__format_arg_store<_Context, _Args...>(__args...);
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <class... _Args>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> make_wformat_args(_Args&... __args) {
return std::__format_arg_store<wformat_context, _Args...>(__args...);
@@ -206,7 +205,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(
case __arg_t::__long_long:
return __format::__compile_time_validate_argument<_CharT, long long>(__parse_ctx, __ctx);
case __arg_t::__i128:
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx);
# else
std::__throw_format_error("Invalid argument");
@@ -217,7 +216,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(
case __arg_t::__unsigned_long_long:
return __format::__compile_time_validate_argument<_CharT, unsigned long long>(__parse_ctx, __ctx);
case __arg_t::__u128:
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx);
# else
std::__throw_format_error("Invalid argument");
@@ -355,12 +354,12 @@ public:
};
_LIBCPP_HIDE_FROM_ABI inline __runtime_format_string<char> runtime_format(string_view __fmt) noexcept { return __fmt; }
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
_LIBCPP_HIDE_FROM_ABI inline __runtime_format_string<wchar_t> runtime_format(wstring_view __fmt) noexcept {
return __fmt;
}
# endif
-# endif //_LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
template <class _CharT, class... _Args>
struct _LIBCPP_TEMPLATE_VIS basic_format_string {
@@ -379,7 +378,7 @@ struct _LIBCPP_TEMPLATE_VIS basic_format_string {
private:
basic_string_view<_CharT> __str_;
- using _Context = __format::__compile_time_basic_format_context<_CharT>;
+ using _Context _LIBCPP_NODEBUG = __format::__compile_time_basic_format_context<_CharT>;
static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{
__format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...};
@@ -397,7 +396,7 @@ private:
template <class... _Args>
using format_string = basic_format_string<char, type_identity_t<_Args>...>;
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <class... _Args>
using wformat_string = basic_format_string<wchar_t, type_identity_t<_Args>...>;
# endif
@@ -411,7 +410,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(_OutIt __out_it,
return std::__format::__vformat_to(
basic_format_parse_context{__fmt, __args.__size()}, std::__format_context_create(std::move(__out_it), __args));
else {
- __format::__format_buffer<_OutIt, _CharT> __buffer{std::move(__out_it)};
+ typename __format::__buffer_selector<_OutIt, _CharT>::type __buffer{std::move(__out_it)};
std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
std::__format_context_create(__buffer.__make_output_iterator(), __args));
return std::move(__buffer).__out_it();
@@ -426,7 +425,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(_OutIt __out_it, s
return std::__vformat_to(std::move(__out_it), __fmt, __args);
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
@@ -440,7 +439,7 @@ format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_format_args(__args...));
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
@@ -452,20 +451,20 @@ format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
// fires too eagerly, see http://llvm.org/PR61563.
template <class = void>
[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(string_view __fmt, format_args __args) {
- string __res;
- std::vformat_to(std::back_inserter(__res), __fmt, __args);
- return __res;
+ __format::__allocating_buffer<char> __buffer;
+ std::vformat_to(__buffer.__make_output_iterator(), __fmt, __args);
+ return string{__buffer.__view()};
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
// fires too eagerly, see http://llvm.org/PR61563.
template <class = void>
[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
vformat(wstring_view __fmt, wformat_args __args) {
- wstring __res;
- std::vformat_to(std::back_inserter(__res), __fmt, __args);
- return __res;
+ __format::__allocating_buffer<wchar_t> __buffer;
+ std::vformat_to(__buffer.__make_output_iterator(), __fmt, __args);
+ return wstring{__buffer.__view()};
}
# endif
@@ -475,7 +474,7 @@ format(format_string<_Args...> __fmt, _Args&&... __args) {
return std::vformat(__fmt.get(), std::make_format_args(__args...));
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <class... _Args>
[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
format(wformat_string<_Args...> __fmt, _Args&&... __args) {
@@ -501,7 +500,7 @@ format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args.
return std::__vformat_to_n<format_context>(std::move(__out_it), __n, __fmt.get(), std::make_format_args(__args...));
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, _Args&&... __args) {
@@ -523,7 +522,7 @@ formatted_size(format_string<_Args...> __fmt, _Args&&... __args) {
return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_format_args(__args...)});
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <class... _Args>
[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
@@ -531,7 +530,7 @@ formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
}
# endif
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
template <class _OutIt, class _CharT, class _FormatOutIt>
requires(output_iterator<_OutIt, const _CharT&>)
@@ -544,7 +543,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(
return std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()},
std::__format_context_create(std::move(__out_it), __args, std::move(__loc)));
else {
- __format::__format_buffer<_OutIt, _CharT> __buffer{std::move(__out_it)};
+ typename __format::__buffer_selector<_OutIt, _CharT>::type __buffer{std::move(__out_it)};
std::__format::__vformat_to(
basic_format_parse_context{__fmt, __args.__size()},
std::__format_context_create(__buffer.__make_output_iterator(), __args, std::move(__loc)));
@@ -558,7 +557,7 @@ vformat_to(_OutIt __out_it, locale __loc, string_view __fmt, format_args __args)
return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, __args);
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) {
@@ -572,7 +571,7 @@ format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&.
return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), std::make_format_args(__args...));
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
@@ -585,20 +584,20 @@ format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&
template <class = void>
[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
vformat(locale __loc, string_view __fmt, format_args __args) {
- string __res;
- std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args);
- return __res;
+ __format::__allocating_buffer<char> __buffer;
+ std::vformat_to(__buffer.__make_output_iterator(), std::move(__loc), __fmt, __args);
+ return string{__buffer.__view()};
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
// fires too eagerly, see http://llvm.org/PR61563.
template <class = void>
[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
- wstring __res;
- std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args);
- return __res;
+ __format::__allocating_buffer<wchar_t> __buffer;
+ std::vformat_to(__buffer.__make_output_iterator(), std::move(__loc), __fmt, __args);
+ return wstring{__buffer.__view()};
}
# endif
@@ -608,7 +607,7 @@ format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
return std::vformat(std::move(__loc), __fmt.get(), std::make_format_args(__args...));
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <class... _Args>
[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
@@ -637,7 +636,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to
std::move(__out_it), __n, std::move(__loc), __fmt.get(), std::make_format_args(__args...));
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to_n(
_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
@@ -661,7 +660,7 @@ formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_format_args(__args...)});
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <class... _Args>
[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
@@ -669,9 +668,9 @@ formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args)
}
# endif
-# endif // _LIBCPP_HAS_NO_LOCALIZATION
+# endif // _LIBCPP_HAS_LOCALIZATION
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_parse_context.h b/lib/libcxx/include/__format/format_parse_context.h
index aefcd5497f..459db751c9 100644
--- a/lib/libcxx/include/__format/format_parse_context.h
+++ b/lib/libcxx/include/__format/format_parse_context.h
@@ -94,11 +94,11 @@ private:
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_parse_context);
using format_parse_context = basic_format_parse_context<char>;
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
using wformat_parse_context = basic_format_parse_context<wchar_t>;
# endif
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_string.h b/lib/libcxx/include/__format/format_string.h
index bdf3cff7f4..5db5973dd5 100644
--- a/lib/libcxx/include/__format/format_string.h
+++ b/lib/libcxx/include/__format/format_string.h
@@ -12,10 +12,10 @@
#include <__assert>
#include <__config>
+#include <__cstddef/size_t.h>
#include <__format/format_error.h>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h> // iter_value_t
-#include <cstddef>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -153,7 +153,7 @@ __parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
} // namespace __format
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/format_to_n_result.h b/lib/libcxx/include/__format/format_to_n_result.h
index 6f30546dec..344299e32f 100644
--- a/lib/libcxx/include/__format/format_to_n_result.h
+++ b/lib/libcxx/include/__format/format_to_n_result.h
@@ -28,7 +28,7 @@ struct _LIBCPP_TEMPLATE_VIS format_to_n_result {
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result);
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter.h b/lib/libcxx/include/__format/formatter.h
index e2f418f936..39c2670dd8 100644
--- a/lib/libcxx/include/__format/formatter.h
+++ b/lib/libcxx/include/__format/formatter.h
@@ -40,6 +40,9 @@ struct _LIBCPP_TEMPLATE_VIS formatter {
# if _LIBCPP_STD_VER >= 23
template <class _Tp>
+constexpr bool enable_nonlocking_formatter_optimization = false;
+
+template <class _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) {
if constexpr (requires { __formatter.set_debug_format(); })
__formatter.set_debug_format();
diff --git a/lib/libcxx/include/__format/formatter_bool.h b/lib/libcxx/include/__format/formatter_bool.h
index 17dc69541e..d08acd4744 100644
--- a/lib/libcxx/include/__format/formatter_bool.h
+++ b/lib/libcxx/include/__format/formatter_bool.h
@@ -20,7 +20,7 @@
#include <__format/parser_std_format_spec.h>
#include <__utility/unreachable.h>
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#if _LIBCPP_HAS_LOCALIZATION
# include <__locale>
#endif
@@ -69,7 +69,11 @@ public:
__format_spec::__parser<_CharT> __parser_;
};
-#endif //_LIBCPP_STD_VER >= 20
+# if _LIBCPP_STD_VER >= 23
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<bool> = true;
+# endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter_char.h b/lib/libcxx/include/__format/formatter_char.h
index d33e84368a..8b8fd2d42c 100644
--- a/lib/libcxx/include/__format/formatter_char.h
+++ b/lib/libcxx/include/__format/formatter_char.h
@@ -77,16 +77,24 @@ public:
template <>
struct _LIBCPP_TEMPLATE_VIS formatter<char, char> : public __formatter_char<char> {};
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <>
struct _LIBCPP_TEMPLATE_VIS formatter<char, wchar_t> : public __formatter_char<wchar_t> {};
template <>
struct _LIBCPP_TEMPLATE_VIS formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {};
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
-# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_STD_VER >= 23
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<char> = true;
+# if _LIBCPP_HAS_WIDE_CHARACTERS
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<wchar_t> = true;
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+# endif // _LIBCPP_STD_VER >= 23
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter_floating_point.h b/lib/libcxx/include/__format/formatter_floating_point.h
index fa42ba203b..ac4be9b619 100644
--- a/lib/libcxx/include/__format/formatter_floating_point.h
+++ b/lib/libcxx/include/__format/formatter_floating_point.h
@@ -23,6 +23,7 @@
#include <__concepts/arithmetic.h>
#include <__concepts/same_as.h>
#include <__config>
+#include <__cstddef/ptrdiff_t.h>
#include <__format/concepts.h>
#include <__format/format_parse_context.h>
#include <__format/formatter.h>
@@ -36,9 +37,8 @@
#include <__utility/move.h>
#include <__utility/unreachable.h>
#include <cmath>
-#include <cstddef>
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#if _LIBCPP_HAS_LOCALIZATION
# include <__locale>
#endif
@@ -141,7 +141,7 @@ struct __traits<double> {
/// on the stack or the heap.
template <floating_point _Fp>
class _LIBCPP_TEMPLATE_VIS __float_buffer {
- using _Traits = __traits<_Fp>;
+ using _Traits _LIBCPP_NODEBUG = __traits<_Fp>;
public:
// TODO FMT Improve this constructor to do a better estimate.
@@ -491,7 +491,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer(
}
}
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
template <class _OutIt, class _Fp, class _CharT>
_LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(
_OutIt __out_it,
@@ -576,7 +576,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(
// alignment
return __formatter::__fill(std::move(__out_it), __padding.__after_, __specs.__fill_);
}
-# endif // _LIBCPP_HAS_NO_LOCALIZATION
+# endif // _LIBCPP_HAS_LOCALIZATION
template <class _OutIt, class _CharT>
_LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite(
@@ -705,7 +705,7 @@ __format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__par
}
}
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
if (__specs.__std_.__locale_specific_form_)
return __formatter::__format_locale_specific_form(__ctx.out(), __buffer, __result, __ctx.locale(), __specs);
# endif
@@ -774,7 +774,15 @@ struct _LIBCPP_TEMPLATE_VIS formatter<double, _CharT> : public __formatter_float
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<long double, _CharT> : public __formatter_floating_point<_CharT> {};
-#endif //_LIBCPP_STD_VER >= 20
+# if _LIBCPP_STD_VER >= 23
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<float> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<double> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<long double> = true;
+# endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter_integer.h b/lib/libcxx/include/__format/formatter_integer.h
index 41400f0047..3f51b10d75 100644
--- a/lib/libcxx/include/__format/formatter_integer.h
+++ b/lib/libcxx/include/__format/formatter_integer.h
@@ -67,7 +67,7 @@ template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<long, _CharT> : public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<long long, _CharT> : public __formatter_integer<_CharT> {};
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT> : public __formatter_integer<_CharT> {};
# endif
@@ -83,12 +83,43 @@ template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long, _CharT> : public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long long, _CharT> : public __formatter_integer<_CharT> {};
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT> : public __formatter_integer<_CharT> {};
# endif
-#endif //_LIBCPP_STD_VER >= 20
+# if _LIBCPP_STD_VER >= 23
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<signed char> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<short> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<int> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<long> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<long long> = true;
+# if _LIBCPP_HAS_INT128
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<__int128_t> = true;
+# endif
+
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<unsigned char> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<unsigned short> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<unsigned> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<unsigned long> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<unsigned long long> = true;
+# if _LIBCPP_HAS_INT128
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<__uint128_t> = true;
+# endif
+# endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter_integral.h b/lib/libcxx/include/__format/formatter_integral.h
index eca966f888..996b7620b3 100644
--- a/lib/libcxx/include/__format/formatter_integral.h
+++ b/lib/libcxx/include/__format/formatter_integral.h
@@ -27,11 +27,12 @@
#include <__type_traits/make_unsigned.h>
#include <__utility/unreachable.h>
#include <array>
+#include <cstdint>
#include <limits>
#include <string>
#include <string_view>
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#if _LIBCPP_HAS_LOCALIZATION
# include <__locale>
#endif
@@ -297,7 +298,7 @@ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_integer(
_Iterator __last = __formatter::__to_buffer(__first, __end, __value, __base);
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
if (__specs.__std_.__locale_specific_form_) {
const auto& __np = std::use_facet<numpunct<_CharT>>(__ctx.locale());
string __grouping = __np.grouping();
@@ -411,7 +412,7 @@ struct _LIBCPP_TEMPLATE_VIS __bool_strings<char> {
static constexpr string_view __false{"false"};
};
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <>
struct _LIBCPP_TEMPLATE_VIS __bool_strings<wchar_t> {
static constexpr wstring_view __true{L"true"};
@@ -422,7 +423,7 @@ struct _LIBCPP_TEMPLATE_VIS __bool_strings<wchar_t> {
template <class _CharT, class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
__format_bool(bool __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) {
-# ifndef _LIBCPP_HAS_NO_LOCALIZATION
+# if _LIBCPP_HAS_LOCALIZATION
if (__specs.__std_.__locale_specific_form_) {
const auto& __np = std::use_facet<numpunct<_CharT>>(__ctx.locale());
basic_string<_CharT> __str = __value ? __np.truename() : __np.falsename();
@@ -436,7 +437,7 @@ __format_bool(bool __value, _FormatContext& __ctx, __format_spec::__parsed_speci
} // namespace __formatter
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter_output.h b/lib/libcxx/include/__format/formatter_output.h
index 1498f64c4a..e1f1309cd2 100644
--- a/lib/libcxx/include/__format/formatter_output.h
+++ b/lib/libcxx/include/__format/formatter_output.h
@@ -16,6 +16,8 @@
#include <__bit/countl.h>
#include <__concepts/same_as.h>
#include <__config>
+#include <__cstddef/ptrdiff_t.h>
+#include <__cstddef/size_t.h>
#include <__format/buffer.h>
#include <__format/concepts.h>
#include <__format/formatter.h>
@@ -28,7 +30,6 @@
#include <__memory/pointer_traits.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
-#include <cstddef>
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -168,7 +169,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value)
}
}
-# ifndef _LIBCPP_HAS_NO_UNICODE
+# if _LIBCPP_HAS_UNICODE
template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
requires(same_as<_CharT, char>)
_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
@@ -182,7 +183,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::
return __out_it;
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2)
_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
@@ -200,13 +201,13 @@ template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
}
-# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-# else // _LIBCPP_HAS_NO_UNICODE
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+# else // _LIBCPP_HAS_UNICODE
template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt>
_LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) {
return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]);
}
-# endif // _LIBCPP_HAS_NO_UNICODE
+# endif // _LIBCPP_HAS_UNICODE
/// Writes the input to the output with the required padding.
///
@@ -294,8 +295,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(
///
/// \pre !__specs.__has_precision()
///
-/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the
-/// input is ASCII.
+/// \note When \c _LIBCPP_HAS_UNICODE is false the function assumes the input is ASCII.
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision(
basic_string_view<_CharT> __str,
@@ -326,7 +326,7 @@ _LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __pre
} // namespace __formatter
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter_pointer.h b/lib/libcxx/include/__format/formatter_pointer.h
index 6941343efd..4ef48c168d 100644
--- a/lib/libcxx/include/__format/formatter_pointer.h
+++ b/lib/libcxx/include/__format/formatter_pointer.h
@@ -11,13 +11,13 @@
#define _LIBCPP___FORMAT_FORMATTER_POINTER_H
#include <__config>
+#include <__cstddef/nullptr_t.h>
#include <__format/concepts.h>
#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
-#include <cstddef>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -65,7 +65,15 @@ struct _LIBCPP_TEMPLATE_VIS formatter<void*, _CharT> : public __formatter_pointe
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<const void*, _CharT> : public __formatter_pointer<_CharT> {};
-#endif //_LIBCPP_STD_VER >= 20
+# if _LIBCPP_STD_VER >= 23
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<nullptr_t> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<void*> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<const void*> = true;
+# endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter_string.h b/lib/libcxx/include/__format/formatter_string.h
index 347439fc8d..30084e5822 100644
--- a/lib/libcxx/include/__format/formatter_string.h
+++ b/lib/libcxx/include/__format/formatter_string.h
@@ -59,44 +59,26 @@ public:
// Formatter const char*.
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<const _CharT*, _CharT> : public __formatter_string<_CharT> {
- using _Base = __formatter_string<_CharT>;
+ using _Base _LIBCPP_NODEBUG = __formatter_string<_CharT>;
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _CharT* __str, _FormatContext& __ctx) const {
_LIBCPP_ASSERT_INTERNAL(__str, "The basic_format_arg constructor should have prevented an invalid pointer.");
-
- __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx);
-# if _LIBCPP_STD_VER >= 23
- if (_Base::__parser_.__type_ == __format_spec::__type::__debug)
- return __formatter::__format_escaped_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
-# endif
-
- // When using a center or right alignment and the width option the length
- // of __str must be known to add the padding upfront. This case is handled
- // by the base class by converting the argument to a basic_string_view.
+ // Converting the input to a basic_string_view means the data is looped over twice;
+ // - once to determine the length, and
+ // - once to process the data.
//
- // When using left alignment and the width option the padding is added
- // after outputting __str so the length can be determined while outputting
- // __str. The same holds true for the precision, during outputting __str it
- // can be validated whether the precision threshold has been reached. For
- // now these optimizations aren't implemented. Instead the base class
- // handles these options.
- // TODO FMT Implement these improvements.
- if (__specs.__has_width() || __specs.__has_precision())
- return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
-
- // No formatting required, copy the string to the output.
- auto __out_it = __ctx.out();
- while (*__str)
- *__out_it++ = *__str++;
- return __out_it;
+ // This sounds slower than writing the output directly. However internally
+ // the output algorithms have optimizations for "bulk" operations, which
+ // makes this faster than a single-pass character-by-character output.
+ return _Base::format(basic_string_view<_CharT>(__str), __ctx);
}
};
// Formatter char*.
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> : public formatter<const _CharT*, _CharT> {
- using _Base = formatter<const _CharT*, _CharT>;
+ using _Base _LIBCPP_NODEBUG = formatter<const _CharT*, _CharT>;
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT* __str, _FormatContext& __ctx) const {
@@ -107,7 +89,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> : public formatter<const
// Formatter char[].
template <__fmt_char_type _CharT, size_t _Size>
struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> : public __formatter_string<_CharT> {
- using _Base = __formatter_string<_CharT>;
+ using _Base _LIBCPP_NODEBUG = __formatter_string<_CharT>;
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
@@ -120,7 +102,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> : public __formatte
template <__fmt_char_type _CharT, class _Traits, class _Allocator>
struct _LIBCPP_TEMPLATE_VIS formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
: public __formatter_string<_CharT> {
- using _Base = __formatter_string<_CharT>;
+ using _Base _LIBCPP_NODEBUG = __formatter_string<_CharT>;
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
@@ -133,7 +115,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter<basic_string<_CharT, _Traits, _Allocator>,
// Formatter std::string_view.
template <__fmt_char_type _CharT, class _Traits>
struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT> : public __formatter_string<_CharT> {
- using _Base = __formatter_string<_CharT>;
+ using _Base _LIBCPP_NODEBUG = __formatter_string<_CharT>;
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
@@ -143,7 +125,32 @@ struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT
}
};
-#endif //_LIBCPP_STD_VER >= 20
+# if _LIBCPP_STD_VER >= 23
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<char*> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<const char*> = true;
+template <size_t _Size>
+inline constexpr bool enable_nonlocking_formatter_optimization<char[_Size]> = true;
+template <class _Traits, class _Allocator>
+inline constexpr bool enable_nonlocking_formatter_optimization<basic_string<char, _Traits, _Allocator>> = true;
+template <class _Traits>
+inline constexpr bool enable_nonlocking_formatter_optimization<basic_string_view<char, _Traits>> = true;
+
+# if _LIBCPP_HAS_WIDE_CHARACTERS
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<wchar_t*> = true;
+template <>
+inline constexpr bool enable_nonlocking_formatter_optimization<const wchar_t*> = true;
+template <size_t _Size>
+inline constexpr bool enable_nonlocking_formatter_optimization<wchar_t[_Size]> = true;
+template <class _Traits, class _Allocator>
+inline constexpr bool enable_nonlocking_formatter_optimization<basic_string<wchar_t, _Traits, _Allocator>> = true;
+template <class _Traits>
+inline constexpr bool enable_nonlocking_formatter_optimization<basic_string_view<wchar_t, _Traits>> = true;
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+# endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/formatter_tuple.h b/lib/libcxx/include/__format/formatter_tuple.h
index 030097a879..bb841ef114 100644
--- a/lib/libcxx/include/__format/formatter_tuple.h
+++ b/lib/libcxx/include/__format/formatter_tuple.h
@@ -143,7 +143,7 @@ template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
struct _LIBCPP_TEMPLATE_VIS formatter<tuple<_Args...>, _CharT>
: public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {};
-#endif //_LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/indic_conjunct_break_table.h b/lib/libcxx/include/__format/indic_conjunct_break_table.h
index 44521d2749..df6cfe6a02 100644
--- a/lib/libcxx/include/__format/indic_conjunct_break_table.h
+++ b/lib/libcxx/include/__format/indic_conjunct_break_table.h
@@ -63,8 +63,8 @@
#include <__algorithm/ranges_upper_bound.h>
#include <__config>
+#include <__cstddef/ptrdiff_t.h>
#include <__iterator/access.h>
-#include <cstddef>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -343,7 +343,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[201] = {
} // namespace __indic_conjunct_break
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/parser_std_format_spec.h b/lib/libcxx/include/__format/parser_std_format_spec.h
index 150bdde89f..415261acf0 100644
--- a/lib/libcxx/include/__format/parser_std_format_spec.h
+++ b/lib/libcxx/include/__format/parser_std_format_spec.h
@@ -52,13 +52,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace __format_spec {
-_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void
+[[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void
__throw_invalid_option_format_error(const char* __id, const char* __option) {
std::__throw_format_error(
(string("The format specifier for ") + __id + " does not allow the " + __option + " option").c_str());
}
-_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __throw_invalid_type_format_error(const char* __id) {
+[[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void __throw_invalid_type_format_error(const char* __id) {
std::__throw_format_error(
(string("The type option contains an invalid value for ") + __id + " formatting argument").c_str());
}
@@ -268,7 +268,7 @@ struct __code_point<char> {
char __data[4] = {' '};
};
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <>
struct __code_point<wchar_t> {
wchar_t __data[4 / sizeof(wchar_t)] = {L' '};
@@ -321,7 +321,7 @@ struct __parsed_specifications {
// value in formatting functions.
static_assert(sizeof(__parsed_specifications<char>) == 16);
static_assert(is_trivially_copyable_v<__parsed_specifications<char>>);
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
static_assert(sizeof(__parsed_specifications<wchar_t>) == 16);
static_assert(is_trivially_copyable_v<__parsed_specifications<wchar_t>>);
# endif
@@ -580,11 +580,11 @@ private:
std::__throw_format_error("The fill option contains an invalid value");
}
-# ifndef _LIBCPP_HAS_NO_UNICODE
+# if _LIBCPP_HAS_UNICODE
// range-fill and tuple-fill are identical
template <contiguous_iterator _Iterator>
requires same_as<_CharT, char>
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
|| (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2)
# endif
_LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end) {
@@ -617,7 +617,7 @@ private:
return true;
}
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
template <contiguous_iterator _Iterator>
requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4)
_LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end) {
@@ -643,9 +643,9 @@ private:
return true;
}
-# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
-# else // _LIBCPP_HAS_NO_UNICODE
+# else // _LIBCPP_HAS_UNICODE
// range-fill and tuple-fill are identical
template <contiguous_iterator _Iterator>
_LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end) {
@@ -670,7 +670,7 @@ private:
return true;
}
-# endif // _LIBCPP_HAS_NO_UNICODE
+# endif // _LIBCPP_HAS_UNICODE
template <contiguous_iterator _Iterator>
_LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(_Iterator& __begin) {
@@ -874,7 +874,7 @@ private:
// Validates whether the reserved bitfields don't change the size.
static_assert(sizeof(__parser<char>) == 16);
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
static_assert(sizeof(__parser<wchar_t>) == 16);
# endif
@@ -1026,7 +1026,7 @@ __column_width_result(size_t, _Iterator) -> __column_width_result<_Iterator>;
/// "rounded up".
enum class __column_width_rounding { __down, __up };
-# ifndef _LIBCPP_HAS_NO_UNICODE
+# if _LIBCPP_HAS_UNICODE
namespace __detail {
template <contiguous_iterator _Iterator>
@@ -1148,7 +1148,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_colu
__result.__width_ += __ascii_size;
return __result;
}
-# else // !defined(_LIBCPP_HAS_NO_UNICODE)
+# else // _LIBCPP_HAS_UNICODE
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<typename basic_string_view<_CharT>::const_iterator>
__estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding) noexcept {
@@ -1159,11 +1159,11 @@ __estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __col
return {__width, __str.begin() + __width};
}
-# endif // !defined(_LIBCPP_HAS_NO_UNICODE)
+# endif // _LIBCPP_HAS_UNICODE
} // namespace __format_spec
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/range_default_formatter.h b/lib/libcxx/include/__format/range_default_formatter.h
index b35223ae93..bb4c520f5e 100644
--- a/lib/libcxx/include/__format/range_default_formatter.h
+++ b/lib/libcxx/include/__format/range_default_formatter.h
@@ -40,7 +40,7 @@ concept __const_formattable_range =
ranges::input_range<const _Rp> && formattable<ranges::range_reference_t<const _Rp>, _CharT>;
template <class _Rp, class _CharT>
-using __fmt_maybe_const = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>;
+using __fmt_maybe_const _LIBCPP_NODEBUG = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>;
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
@@ -95,7 +95,7 @@ struct _LIBCPP_TEMPLATE_VIS __range_default_formatter;
template <ranges::input_range _Rp, class _CharT>
struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::sequence, _Rp, _CharT> {
private:
- using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>;
+ using __maybe_const_r _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>;
range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_;
public:
@@ -122,8 +122,8 @@ public:
template <ranges::input_range _Rp, class _CharT>
struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::map, _Rp, _CharT> {
private:
- using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>;
- using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>;
+ using __maybe_const_map _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>;
+ using __element_type _LIBCPP_NODEBUG = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>;
range_formatter<__element_type, _CharT> __underlying_;
public:
@@ -150,8 +150,8 @@ public:
template <ranges::input_range _Rp, class _CharT>
struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::set, _Rp, _CharT> {
private:
- using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>;
- using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>;
+ using __maybe_const_set _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>;
+ using __element_type _LIBCPP_NODEBUG = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>;
range_formatter<__element_type, _CharT> __underlying_;
public:
@@ -207,7 +207,7 @@ template <ranges::input_range _Rp, class _CharT>
requires(format_kind<_Rp> != range_format::disabled && formattable<ranges::range_reference_t<_Rp>, _CharT>)
struct _LIBCPP_TEMPLATE_VIS formatter<_Rp, _CharT> : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
-#endif //_LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/range_formatter.h b/lib/libcxx/include/__format/range_formatter.h
index 6915630743..def55c86ce 100644
--- a/lib/libcxx/include/__format/range_formatter.h
+++ b/lib/libcxx/include/__format/range_formatter.h
@@ -257,7 +257,7 @@ private:
basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]");
};
-#endif //_LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/unicode.h b/lib/libcxx/include/__format/unicode.h
index de7d0fea1d..46096fda1e 100644
--- a/lib/libcxx/include/__format/unicode.h
+++ b/lib/libcxx/include/__format/unicode.h
@@ -54,7 +54,7 @@ struct __consume_result {
};
static_assert(sizeof(__consume_result) == sizeof(char32_t));
-# ifndef _LIBCPP_HAS_NO_UNICODE
+# if _LIBCPP_HAS_UNICODE
/// Implements the grapheme cluster boundary rules
///
@@ -123,7 +123,7 @@ class __code_point_view;
/// UTF-8 specialization.
template <>
class __code_point_view<char> {
- using _Iterator = basic_string_view<char>::const_iterator;
+ using _Iterator _LIBCPP_NODEBUG = basic_string_view<char>::const_iterator;
public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
@@ -235,7 +235,7 @@ private:
_Iterator __last_;
};
-# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# if _LIBCPP_HAS_WIDE_CHARACTERS
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_high(wchar_t __value) {
return __value >= 0xd800 && __value <= 0xdbff;
}
@@ -249,7 +249,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_low(wchar_t __value) {
/// - 4 UTF-32 (for example Linux)
template <>
class __code_point_view<wchar_t> {
- using _Iterator = typename basic_string_view<wchar_t>::const_iterator;
+ using _Iterator _LIBCPP_NODEBUG = typename basic_string_view<wchar_t>::const_iterator;
public:
static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "sizeof(wchar_t) has a not implemented value");
@@ -292,7 +292,7 @@ private:
_Iterator __first_;
_Iterator __last_;
};
-# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
// State machine to implement the Extended Grapheme Cluster Boundary
//
@@ -300,8 +300,8 @@ private:
// This implements the extended rules see
// https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
class __extended_grapheme_cluster_break {
- using __EGC_property = __extended_grapheme_custer_property_boundary::__property;
- using __inCB_property = __indic_conjunct_break::__property;
+ using __EGC_property _LIBCPP_NODEBUG = __extended_grapheme_custer_property_boundary::__property;
+ using __inCB_property _LIBCPP_NODEBUG = __indic_conjunct_break::__property;
public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_break(char32_t __first_code_point)
@@ -527,7 +527,7 @@ private:
/// Therefore only this code point is extracted.
template <class _CharT>
class __extended_grapheme_cluster_view {
- using _Iterator = typename basic_string_view<_CharT>::const_iterator;
+ using _Iterator _LIBCPP_NODEBUG = typename basic_string_view<_CharT>::const_iterator;
public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(_Iterator __first, _Iterator __last)
@@ -566,13 +566,13 @@ private:
template <contiguous_iterator _Iterator>
__extended_grapheme_cluster_view(_Iterator, _Iterator) -> __extended_grapheme_cluster_view<iter_value_t<_Iterator>>;
-# else // _LIBCPP_HAS_NO_UNICODE
+# else // _LIBCPP_HAS_UNICODE
// For ASCII every character is a "code point".
-// This makes it easier to write code agnostic of the _LIBCPP_HAS_NO_UNICODE define.
+// This makes it easier to write code agnostic of the _LIBCPP_HAS_UNICODE define.
template <class _CharT>
class __code_point_view {
- using _Iterator = typename basic_string_view<_CharT>::const_iterator;
+ using _Iterator _LIBCPP_NODEBUG = typename basic_string_view<_CharT>::const_iterator;
public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
@@ -591,11 +591,11 @@ private:
_Iterator __last_;
};
-# endif // _LIBCPP_HAS_NO_UNICODE
+# endif // _LIBCPP_HAS_UNICODE
} // namespace __unicode
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/width_estimation_table.h b/lib/libcxx/include/__format/width_estimation_table.h
index 11f61dea18..5b4b3950c6 100644
--- a/lib/libcxx/include/__format/width_estimation_table.h
+++ b/lib/libcxx/include/__format/width_estimation_table.h
@@ -63,7 +63,7 @@
#include <__algorithm/ranges_upper_bound.h>
#include <__config>
-#include <cstddef>
+#include <__cstddef/ptrdiff_t.h>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -263,7 +263,7 @@ inline constexpr uint32_t __table_upper_bound = 0x0003fffd;
} // namespace __width_estimation_table
-#endif //_LIBCPP_STD_VER >= 20
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/lib/libcxx/include/__format/write_escaped.h b/lib/libcxx/include/__format/write_escaped.h
index 052ea98c3c..aa74940032 100644
--- a/lib/libcxx/include/__format/write_escaped.h
+++ b/lib/libcxx/include/__format/write_escaped.h
@@ -16,6 +16,7 @@
#include <__charconv/to_chars_result.h>
#include <__chrono/statically_widen.h>
#include <__format/escaped_output_table.h>
+#include <__format/extended_grapheme_cluster_table.h>
#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
#include <__format/unicode.h>
@@ -41,8 +42,7 @@ namespace __formatter {
/// Writes a string using format's width estimation algorithm.
///
-/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the
-/// input is ASCII.
+/// \note When \c _LIBCPP_HAS_UNICODE is false the function assumes the input is ASCII.
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI auto
__write_string(basic_string_view<_CharT> __str,
@@ -103,7 +103,7 @@ _LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_Cha
template <class _CharT>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
__is_escaped_sequence_written(basic_string<_CharT>& __str, bool __last_escaped, char32_t __value) {
-# ifdef _LIBCPP_HAS_NO_UNICODE
+# if !_LIBCPP_HAS_UNICODE
// For ASCII assume everything above 127 is printable.
if (__value > 127)
return false;