Import Cobalt 24.master.0.1033952
diff --git a/third_party/llvm-project/libcxx/include/__format/buffer.h b/third_party/llvm-project/libcxx/include/__format/buffer.h
index ddfe767..0f669ba 100644
--- a/third_party/llvm-project/libcxx/include/__format/buffer.h
+++ b/third_party/llvm-project/libcxx/include/__format/buffer.h
@@ -27,10 +27,11 @@
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/wrap_iter.h>
+#include <__memory/addressof.h>
+#include <__type_traits/add_pointer.h>
#include <__utility/move.h>
#include <cstddef>
#include <string_view>
-#include <type_traits>
#include <vector>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -42,7 +43,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __format {
@@ -564,7 +565,7 @@
} // namespace __format
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/concepts.h b/third_party/llvm-project/libcxx/include/__format/concepts.h
index fe4a7b9..62552f8 100644
--- a/third_party/llvm-project/libcxx/include/__format/concepts.h
+++ b/third_party/llvm-project/libcxx/include/__format/concepts.h
@@ -18,7 +18,6 @@
#include <__type_traits/is_specialization.h>
#include <__utility/pair.h>
#include <tuple>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -26,7 +25,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
/// The character type specializations of \ref formatter.
template <class _CharT>
@@ -56,7 +55,7 @@
{ __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>;
};
-# if _LIBCPP_STD_VER > 20
+# if _LIBCPP_STD_VER >= 23
template <class _Tp, class _CharT>
concept formattable = __formattable<_Tp, _CharT>;
@@ -66,12 +65,11 @@
// TODO FMT Add a test to validate we fail when using that concept after P2165
// has been implemented.
template <class _Tp>
-concept __fmt_pair_like = __is_specialization_v<_Tp, pair> ||
- // Use a requires since tuple_size_v may fail to instantiate,
- (__is_specialization_v<_Tp, tuple> && requires { tuple_size_v<_Tp> == 2; });
+concept __fmt_pair_like =
+ __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
-# endif //_LIBCPP_STD_VER > 20
-#endif //_LIBCPP_STD_VER > 17
+# endif //_LIBCPP_STD_VER >= 23
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/container_adaptor.h b/third_party/llvm-project/libcxx/include/__format/container_adaptor.h
index 62b6981..5b95f60 100644
--- a/third_party/llvm-project/libcxx/include/__format/container_adaptor.h
+++ b/third_party/llvm-project/libcxx/include/__format/container_adaptor.h
@@ -19,12 +19,16 @@
#include <__format/concepts.h>
#include <__format/formatter.h>
#include <__format/range_default_formatter.h>
+#include <__ranges/all.h>
+#include <__ranges/ref_view.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/maybe_const.h>
#include <queue>
#include <stack>
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
// [container.adaptors.format] only specifies the library should provide the
// formatter specializations, not which header should provide them.
@@ -33,10 +37,11 @@
// adaptor headers. To use the format functions users already include <format>.
template <class _Adaptor, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor {
+struct _LIBCPP_TEMPLATE_VIS __formatter_container_adaptor {
private:
- using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>;
- formatter<typename _Adaptor::container_type, _CharT> __underlying_;
+ 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>;
+ formatter<ranges::ref_view<__maybe_const_container>, _CharT> __underlying_;
public:
template <class _ParseContext>
@@ -52,18 +57,18 @@
};
template <class _CharT, class _Tp, formattable<_CharT> _Container>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<queue<_Tp, _Container>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<queue<_Tp, _Container>, _CharT>
: public __formatter_container_adaptor<queue<_Tp, _Container>, _CharT> {};
template <class _CharT, class _Tp, class _Container, class _Compare>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>
: public __formatter_container_adaptor<priority_queue<_Tp, _Container, _Compare>, _CharT> {};
template <class _CharT, class _Tp, formattable<_CharT> _Container>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<stack<_Tp, _Container>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<stack<_Tp, _Container>, _CharT>
: public __formatter_container_adaptor<stack<_Tp, _Container>, _CharT> {};
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/enable_insertable.h b/third_party/llvm-project/libcxx/include/__format/enable_insertable.h
index 71b4252..86ef94a 100644
--- a/third_party/llvm-project/libcxx/include/__format/enable_insertable.h
+++ b/third_party/llvm-project/libcxx/include/__format/enable_insertable.h
@@ -18,7 +18,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __format {
@@ -28,7 +28,7 @@
} // namespace __format
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/escaped_output_table.h b/third_party/llvm-project/libcxx/include/__format/escaped_output_table.h
index bd2994b..222847e 100644
--- a/third_party/llvm-project/libcxx/include/__format/escaped_output_table.h
+++ b/third_party/llvm-project/libcxx/include/__format/escaped_output_table.h
@@ -72,7 +72,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
namespace __escaped_output_table {
@@ -1031,7 +1031,7 @@
} // namespace __escaped_output_table
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/extended_grapheme_cluster_table.h b/third_party/llvm-project/libcxx/include/__format/extended_grapheme_cluster_table.h
index 1ffcfeb..bd6d39f 100644
--- a/third_party/llvm-project/libcxx/include/__format/extended_grapheme_cluster_table.h
+++ b/third_party/llvm-project/libcxx/include/__format/extended_grapheme_cluster_table.h
@@ -73,7 +73,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __extended_grapheme_custer_property_boundary {
@@ -1654,7 +1654,7 @@
} // namespace __extended_grapheme_custer_property_boundary
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_arg.h b/third_party/llvm-project/libcxx/include/__format/format_arg.h
index 771a03f..7e37dd4 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_arg.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_arg.h
@@ -18,6 +18,7 @@
#include <__format/format_parse_context.h>
#include <__functional/invoke.h>
#include <__memory/addressof.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
#include <__utility/unreachable.h>
#include <__variant/monostate.h>
@@ -30,7 +31,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __format {
/// The type stored in @ref basic_format_arg.
@@ -94,7 +95,7 @@
// This function is not user obervable, so it can directly use the non-standard
// types of the "variant". See __arg_t for more details.
template <class _Visitor, class _Context>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
+_LIBCPP_HIDE_FROM_ABI decltype(auto)
__visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
switch (__arg.__type_) {
case __format::__arg_t::__none:
@@ -224,7 +225,7 @@
};
template <class _Context>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg {
+class _LIBCPP_TEMPLATE_VIS basic_format_arg {
public:
class _LIBCPP_TEMPLATE_VIS handle;
@@ -276,7 +277,7 @@
// 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>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto)
+_LIBCPP_HIDE_FROM_ABI decltype(auto)
visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
switch (__arg.__type_) {
# ifndef _LIBCPP_HAS_NO_INT128
@@ -295,7 +296,7 @@
}
}
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_arg_store.h b/third_party/llvm-project/libcxx/include/__format/format_arg_store.h
index 6f4f4c3..b9a36e5 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_arg_store.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_arg_store.h
@@ -19,15 +19,16 @@
#include <__config>
#include <__format/concepts.h>
#include <__format/format_arg.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/extent.h>
+#include <__type_traits/is_same.h>
#include <__utility/forward.h>
-#include <cstring>
#include <string>
#include <string_view>
-#include <type_traits>
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __format {
@@ -142,21 +143,24 @@
//
// Note this version can't be constrained avoiding ambiguous overloads.
// That means it can be instantiated by disabled formatters. To solve this, a
-// constrained version for not formattable formatters is added. That overload
-// is marked as deleted to fail creating a storage type for disabled formatters.
+// constrained version for not formattable formatters is added.
template <class _Context, class _Tp>
consteval __arg_t __determine_arg_t() {
return __arg_t::__handle;
}
+// The overload for not formattable types allows triggering the static
+// assertion below.
template <class _Context, class _Tp>
requires(!__formattable<_Tp, typename _Context::char_type>)
-consteval __arg_t __determine_arg_t() = delete;
+consteval __arg_t __determine_arg_t() {
+ return __arg_t::__none;
+}
template <class _Context, class _Tp>
_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __value) noexcept {
constexpr __arg_t __arg = __determine_arg_t<_Context, remove_cvref_t<_Tp>>();
- static_assert(__arg != __arg_t::__none);
+ static_assert(__arg != __arg_t::__none, "the supplied type is not formattable");
// Not all types can be used to directly initialize the
// __basic_format_arg_value. First handle all types needing adjustment, the
@@ -247,7 +251,7 @@
_Storage __storage;
};
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_args.h b/third_party/llvm-project/libcxx/include/__format/format_args.h
index 8b8fbde..c2e7c96 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_args.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_args.h
@@ -24,10 +24,10 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <class _Context>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_args {
+class _LIBCPP_TEMPLATE_VIS basic_format_args {
public:
_LIBCPP_HIDE_FROM_ABI basic_format_args() noexcept = default;
@@ -71,9 +71,11 @@
const basic_format_arg<_Context>* __args_;
};
};
-_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_args);
-#endif //_LIBCPP_STD_VER > 17
+template <class _Context, class... _Args>
+basic_format_args(__format_arg_store<_Context, _Args...>) -> basic_format_args<_Context>;
+
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_context.h b/third_party/llvm-project/libcxx/include/__format/format_context.h
index 85e00eb..521131d 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_context.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_context.h
@@ -37,11 +37,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <class _OutIt, class _CharT>
requires output_iterator<_OutIt, const _CharT&>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context;
+class _LIBCPP_TEMPLATE_VIS basic_format_context;
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
/**
@@ -80,7 +80,6 @@
class
// clang-format off
_LIBCPP_TEMPLATE_VIS
- _LIBCPP_AVAILABILITY_FORMAT
_LIBCPP_PREFERRED_NAME(format_context)
_LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context))
// clang-format on
@@ -162,7 +161,7 @@
// Here the width of an element in input is determined dynamically.
// Note when the top-level element has no width the retargeting is not needed.
template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT
+class _LIBCPP_TEMPLATE_VIS
basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> {
public:
using iterator = typename __format::__retarget_buffer<_CharT>::__iterator;
@@ -216,7 +215,7 @@
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_error.h b/third_party/llvm-project/libcxx/include/__format/format_error.h
index 002d1a4..5f9b7da 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_error.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_error.h
@@ -20,7 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error {
public:
@@ -40,7 +40,7 @@
_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void
__throw_format_error(const char* __s) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
throw format_error(__s);
#else
(void)__s;
@@ -48,7 +48,7 @@
#endif
}
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_functions.h b/third_party/llvm-project/libcxx/include/__format/format_functions.h
index 185148c..60b40cb 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_functions.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_functions.h
@@ -38,7 +38,9 @@
#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/readable_traits.h> // iter_value_t
#include <__variant/monostate.h>
#include <array>
#include <string>
@@ -54,7 +56,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
// TODO FMT Evaluate which templates should be external templates. This
// improves the efficiency of the header. However since the header is still
@@ -147,41 +149,44 @@
size_t __size_;
};
-_LIBCPP_HIDE_FROM_ABI
-constexpr void __compile_time_validate_integral(__arg_t __type) {
- switch (__type) {
- case __arg_t::__int:
- case __arg_t::__long_long:
- case __arg_t::__i128:
- case __arg_t::__unsigned:
- case __arg_t::__unsigned_long_long:
- case __arg_t::__u128:
- return;
-
- default:
- std::__throw_format_error("Argument isn't an integral type");
- }
-}
-
+// [format.string.std]/8
+// If { arg-idopt } is used in a width or precision, the value of the
+// corresponding formatting argument is used in its place. If the
+// corresponding formatting argument is not of standard signed or unsigned
+// integer type, or its value is negative for precision or non-positive for
+// width, an exception of type format_error is thrown.
+//
// _HasPrecision does the formatter have a precision?
template <class _CharT, class _Tp, bool _HasPrecision = false>
-_LIBCPP_HIDE_FROM_ABI constexpr void
-__compile_time_validate_argument(basic_format_parse_context<_CharT>& __parse_ctx,
- __compile_time_basic_format_context<_CharT>& __ctx) {
+_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_validate_argument(
+ basic_format_parse_context<_CharT>& __parse_ctx, __compile_time_basic_format_context<_CharT>& __ctx) {
+ auto __validate_type = [](__arg_t __type) {
+ // LWG3720 originally allowed "signed or unsigned integer types", however
+ // the final version explicitly changed it to "*standard* signed or unsigned
+ // integer types". It's trivial to use 128-bit integrals in libc++'s
+ // implementation, but other implementations may not implement it.
+ // (Using a width or precision, that does not fit in 64-bits, sounds very
+ // unlikely in real world code.)
+ switch (__type) {
+ case __arg_t::__int:
+ case __arg_t::__long_long:
+ case __arg_t::__unsigned:
+ case __arg_t::__unsigned_long_long:
+ return;
+
+ default:
+ std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type");
+ }
+ };
+
formatter<_Tp, _CharT> __formatter;
__parse_ctx.advance_to(__formatter.parse(__parse_ctx));
- // [format.string.std]/7
- // ... If the corresponding formatting argument is not of integral type, or
- // its value is negative for precision or non-positive for width, an
- // exception of type format_error is thrown.
- //
- // Validate whether the arguments are integrals.
if (__formatter.__parser_.__width_as_arg_)
- __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__width_));
+ __validate_type(__ctx.arg(__formatter.__parser_.__width_));
if constexpr (_HasPrecision)
if (__formatter.__parser_.__precision_as_arg_)
- __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__precision_));
+ __validate_type(__ctx.arg(__formatter.__parser_.__precision_));
}
// This function is not user facing, so it can directly use the non-standard types of the "variant".
@@ -236,21 +241,22 @@
std::__throw_format_error("Invalid argument");
}
-template <class _CharT, class _ParseCtx, class _Ctx>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__handle_replacement_field(const _CharT* __begin, const _CharT* __end,
+template <contiguous_iterator _Iterator, class _ParseCtx, class _Ctx>
+_LIBCPP_HIDE_FROM_ABI constexpr _Iterator
+__handle_replacement_field(_Iterator __begin, _Iterator __end,
_ParseCtx& __parse_ctx, _Ctx& __ctx) {
+ using _CharT = iter_value_t<_Iterator>;
__format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
- bool __parse = *__r.__ptr == _CharT(':');
- switch (*__r.__ptr) {
+ bool __parse = *__r.__last == _CharT(':');
+ switch (*__r.__last) {
case _CharT(':'):
// The arg-id has a format-specifier, advance the input to the format-spec.
- __parse_ctx.advance_to(__r.__ptr + 1);
+ __parse_ctx.advance_to(__r.__last + 1);
break;
case _CharT('}'):
// The arg-id has no format-specifier.
- __parse_ctx.advance_to(__r.__ptr);
+ __parse_ctx.advance_to(__r.__last);
break;
default:
std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'");
@@ -258,10 +264,12 @@
if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
__arg_t __type = __ctx.arg(__r.__value);
- if (__type == __arg_t::__handle)
+ if (__type == __arg_t::__none)
+ std::__throw_format_error("Argument index out of bounds");
+ else if (__type == __arg_t::__handle)
__ctx.__handle(__r.__value).__parse(__parse_ctx);
- else
- __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
+ else if (__parse)
+ __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
} else
_VSTD::__visit_format_arg(
[&](auto __arg) {
@@ -291,8 +299,8 @@
using _CharT = typename _ParseCtx::char_type;
static_assert(same_as<typename _Ctx::char_type, _CharT>);
- const _CharT* __begin = __parse_ctx.begin();
- const _CharT* __end = __parse_ctx.end();
+ auto __begin = __parse_ctx.begin();
+ auto __end = __parse_ctx.end();
typename _Ctx::iterator __out_it = __ctx.out();
while (__begin != __end) {
switch (*__begin) {
@@ -339,7 +347,7 @@
_Context{__types_.data(), __handles_.data(), sizeof...(_Args)});
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT constexpr basic_string_view<_CharT> get() const noexcept {
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept {
return __str_;
}
@@ -404,21 +412,21 @@
// https://reviews.llvm.org/D110499#inline-1180704
// TODO FMT Evaluate whether we want to file a Clang bug report regarding this.
template <output_iterator<const char&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) {
return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) {
return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args);
}
#endif
template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(),
_VSTD::make_format_args(__args...));
@@ -426,14 +434,17 @@
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(),
_VSTD::make_wformat_args(__args...));
}
#endif
-_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
+// 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>
+_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
vformat(string_view __fmt, format_args __args) {
string __res;
_VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
@@ -441,7 +452,10 @@
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
+// 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>
+_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
vformat(wstring_view __fmt, wformat_args __args) {
wstring __res;
_VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args);
@@ -450,14 +464,14 @@
#endif
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(format_string<_Args...> __fmt,
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(format_string<_Args...> __fmt,
_Args&&... __args) {
return _VSTD::vformat(__fmt.get(), _VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
format(wformat_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat(__fmt.get(), _VSTD::make_wformat_args(__args...));
}
@@ -474,14 +488,14 @@
}
template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt>
format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_format_args(__args...));
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+_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) {
return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_wformat_args(__args...));
@@ -497,14 +511,14 @@
}
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
formatted_size(format_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)});
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)});
}
@@ -531,7 +545,7 @@
}
template <output_iterator<const char&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(
_OutIt __out_it, locale __loc, string_view __fmt, format_args __args) {
return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
__args);
@@ -539,7 +553,7 @@
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to(
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(
_OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) {
return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt,
__args);
@@ -547,7 +561,7 @@
#endif
template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(),
_VSTD::make_format_args(__args...));
@@ -555,14 +569,17 @@
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt
format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(),
_VSTD::make_wformat_args(__args...));
}
#endif
-_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string
+// 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>
+_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string
vformat(locale __loc, string_view __fmt, format_args __args) {
string __res;
_VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
@@ -571,7 +588,10 @@
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
+// 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>
+_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
vformat(locale __loc, wstring_view __fmt, wformat_args __args) {
wstring __res;
_VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt,
@@ -581,7 +601,7 @@
#endif
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc,
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(locale __loc,
format_string<_Args...> __fmt,
_Args&&... __args) {
return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(),
@@ -590,7 +610,7 @@
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring
format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(),
_VSTD::make_wformat_args(__args...));
@@ -609,7 +629,7 @@
}
template <output_iterator<const char&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+_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, format_string<_Args...> __fmt,
_Args&&... __args) {
return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(),
@@ -618,7 +638,7 @@
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <output_iterator<const wchar_t&> _OutIt, class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt>
+_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) {
return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(),
@@ -636,14 +656,14 @@
}
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)});
}
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <class... _Args>
-_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
+_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t
formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) {
return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)});
}
@@ -652,7 +672,7 @@
#endif // _LIBCPP_HAS_NO_LOCALIZATION
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_fwd.h b/third_party/llvm-project/libcxx/include/__format/format_fwd.h
index f7c72e2..120b2fc 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_fwd.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_fwd.h
@@ -20,19 +20,19 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <class _Context>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg;
+class _LIBCPP_TEMPLATE_VIS basic_format_arg;
template <class _OutIt, class _CharT>
requires output_iterator<_OutIt, const _CharT&>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context;
+class _LIBCPP_TEMPLATE_VIS basic_format_context;
template <class _Tp, class _CharT = char>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter;
+struct _LIBCPP_TEMPLATE_VIS formatter;
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_parse_context.h b/third_party/llvm-project/libcxx/include/__format/format_parse_context.h
index 30e3a7d..79f53f7 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_parse_context.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_parse_context.h
@@ -12,6 +12,7 @@
#include <__config>
#include <__format/format_error.h>
+#include <__type_traits/is_constant_evaluated.h>
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -20,10 +21,10 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context {
+class _LIBCPP_TEMPLATE_VIS basic_format_parse_context {
public:
using char_type = _CharT;
using const_iterator = typename basic_string_view<_CharT>::const_iterator;
@@ -58,6 +59,18 @@
if (__indexing_ == __unknown)
__indexing_ = __automatic;
+
+ // Throws an exception to make the expression a non core constant
+ // expression as required by:
+ // [format.parse.ctx]/8
+ // Remarks: Let cur-arg-id be the value of next_arg_id_ prior to this
+ // call. Call expressions where cur-arg-id >= num_args_ is true are not
+ // core constant expressions (7.7 [expr.const]).
+ // Note: the Throws clause [format.parse.ctx]/9 doesn't specify the
+ // behavior when id >= num_args_.
+ if (is_constant_evaluated() && __next_arg_id_ >= __num_args_)
+ std::__throw_format_error("Argument index outside the valid range");
+
return __next_arg_id_++;
}
_LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) {
@@ -93,7 +106,7 @@
using wformat_parse_context = basic_format_parse_context<wchar_t>;
#endif
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_string.h b/third_party/llvm-project/libcxx/include/__format/format_string.h
index d9caf86..bec3fe1 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_string.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_string.h
@@ -13,6 +13,8 @@
#include <__assert>
#include <__config>
#include <__format/format_error.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
#include <cstddef>
#include <cstdint>
@@ -22,22 +24,22 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __format {
-template <class _CharT>
+template <contiguous_iterator _Iterator>
struct _LIBCPP_TEMPLATE_VIS __parse_number_result {
- const _CharT* __ptr;
+ _Iterator __last;
uint32_t __value;
};
-template <class _CharT>
-__parse_number_result(const _CharT*, uint32_t) -> __parse_number_result<_CharT>;
+template <contiguous_iterator _Iterator>
+__parse_number_result(_Iterator, uint32_t) -> __parse_number_result<_Iterator>;
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_number(const _CharT* __begin, const _CharT* __end);
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_number(_Iterator __begin, _Iterator __end);
/**
* The maximum value of a numeric argument.
@@ -53,16 +55,16 @@
inline constexpr uint32_t __number_max = INT32_MAX;
namespace __detail {
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_zero(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_zero(_Iterator __begin, _Iterator, auto& __parse_ctx) {
__parse_ctx.check_arg_id(0);
return {++__begin, 0}; // can never be larger than the maximum.
}
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_automatic(_Iterator __begin, _Iterator, auto& __parse_ctx) {
size_t __value = __parse_ctx.next_arg_id();
_LIBCPP_ASSERT(__value <= __number_max,
"Compilers don't support this number of arguments");
@@ -70,10 +72,10 @@
return {__begin, uint32_t(__value)};
}
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
- __parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end);
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_manual(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
+ __parse_number_result<_Iterator> __r = __format::__parse_number(__begin, __end);
__parse_ctx.check_arg_id(__r.__value);
return __r;
}
@@ -86,9 +88,10 @@
* The number is used for the 31-bit values @em width and @em precision. This
* allows a maximum value of 2147483647.
*/
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_number(const _CharT* __begin, const _CharT* __end_input) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_number(_Iterator __begin, _Iterator __end_input) {
+ using _CharT = iter_value_t<_Iterator>;
static_assert(__format::__number_max == INT32_MAX,
"The algorithm is implemented based on this value.");
/*
@@ -98,7 +101,7 @@
* - Does the value exceed width of an uint32_t? (Switching to uint64_t would
* have the same issue, but with a higher maximum.)
*/
- const _CharT* __end = __end_input - __begin > 9 ? __begin + 9 : __end_input;
+ _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input;
uint32_t __value = *__begin - _CharT('0');
while (++__begin != __end) {
if (*__begin < _CharT('0') || *__begin > _CharT('9'))
@@ -134,9 +137,10 @@
* The parser will return a pointer beyond the last consumed character. This
* should be the closing '}' of the arg-id.
*/
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
+ using _CharT = iter_value_t<_Iterator>;
switch (*__begin) {
case _CharT('0'):
return __detail::__parse_zero(__begin, __end, __parse_ctx);
@@ -156,7 +160,7 @@
} // namespace __format
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/format_to_n_result.h b/third_party/llvm-project/libcxx/include/__format/format_to_n_result.h
index f1ed9a0..6f30546 100644
--- a/third_party/llvm-project/libcxx/include/__format/format_to_n_result.h
+++ b/third_party/llvm-project/libcxx/include/__format/format_to_n_result.h
@@ -19,7 +19,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <class _OutIt>
struct _LIBCPP_TEMPLATE_VIS format_to_n_result {
@@ -28,7 +28,7 @@
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result);
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter.h b/third_party/llvm-project/libcxx/include/__format/formatter.h
index 900a09a..172b2d5 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter.h
@@ -20,7 +20,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
/// The default formatter template.
///
@@ -32,13 +32,13 @@
/// - is_copy_assignable<F>, and
/// - is_move_assignable<F>.
template <class _Tp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter {
+struct _LIBCPP_TEMPLATE_VIS formatter {
formatter() = delete;
formatter(const formatter&) = delete;
formatter& operator=(const formatter&) = delete;
};
-# if _LIBCPP_STD_VER > 20
+# if _LIBCPP_STD_VER >= 23
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) {
@@ -46,8 +46,8 @@
__formatter.set_debug_format();
}
-# endif // _LIBCPP_STD_VER > 20
-#endif // _LIBCPP_STD_VER > 17
+# endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_bool.h b/third_party/llvm-project/libcxx/include/__format/formatter_bool.h
index 0d005a1..1fb7575 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_bool.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_bool.h
@@ -33,10 +33,10 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT> {
+struct _LIBCPP_TEMPLATE_VIS formatter<bool, _CharT> {
public:
_LIBCPP_HIDE_FROM_ABI constexpr auto
parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
@@ -71,7 +71,7 @@
__format_spec::__parser<_CharT> __parser_;
};
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_char.h b/third_party/llvm-project/libcxx/include/__format/formatter_char.h
index 8a92e74..7d63c04 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_char.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_char.h
@@ -28,10 +28,10 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_char {
+struct _LIBCPP_TEMPLATE_VIS __formatter_char {
public:
_LIBCPP_HIDE_FROM_ABI constexpr auto
parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
@@ -44,7 +44,7 @@
if (__parser_.__type_ == __format_spec::__type::__default || __parser_.__type_ == __format_spec::__type::__char)
return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
-# if _LIBCPP_STD_VER > 20
+# if _LIBCPP_STD_VER >= 23
if (__parser_.__type_ == __format_spec::__type::__debug)
return __formatter::__format_escaped_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
# endif
@@ -66,7 +66,7 @@
return format(static_cast<wchar_t>(__value), __ctx);
}
-# if _LIBCPP_STD_VER > 20
+# if _LIBCPP_STD_VER >= 23
_LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; }
# endif
@@ -74,19 +74,19 @@
};
template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, char> : public __formatter_char<char> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<char, char> : public __formatter_char<char> {};
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, wchar_t> : public __formatter_char<wchar_t> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<char, wchar_t> : public __formatter_char<wchar_t> {};
template <>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {
+struct _LIBCPP_TEMPLATE_VIS formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {
};
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_floating_point.h b/third_party/llvm-project/libcxx/include/__format/formatter_floating_point.h
index a544b53..12c7e58 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_floating_point.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_floating_point.h
@@ -16,6 +16,9 @@
#include <__algorithm/min.h>
#include <__algorithm/rotate.h>
#include <__algorithm/transform.h>
+#include <__charconv/chars_format.h>
+#include <__charconv/to_chars_floating_point.h>
+#include <__charconv/to_chars_result.h>
#include <__concepts/arithmetic.h>
#include <__concepts/same_as.h>
#include <__config>
@@ -26,9 +29,12 @@
#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
#include <__memory/allocator.h>
+#include <__system_error/errc.h>
+#include <__type_traits/conditional.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
-#include <charconv>
+#include <cmath>
+#include <cstddef>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
# include <locale>
@@ -43,7 +49,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __formatter {
@@ -404,7 +410,6 @@
// In fixed mode the algorithm truncates trailing spaces and possibly the
// radix point. There's no good guess for the position of the radix point
// therefore scan the output after the first digit.
-
__result.__radix_point = _VSTD::find(__first, __result.__last, '.');
}
}
@@ -665,7 +670,7 @@
if (__result.__exponent == __result.__last)
// if P > X >= -4, the conversion is with style f or F and precision P - 1 - X.
// By including the radix point it calculates P - (1 + X)
- __p -= __result.__radix_point - __buffer.begin();
+ __p -= __result.__radix_point - __result.__integral;
else
// otherwise, the conversion is with style e or E and precision P - 1.
--__p;
@@ -739,16 +744,16 @@
};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<float, _CharT>
: public __formatter_floating_point<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<double, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<double, _CharT>
: public __formatter_floating_point<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long double, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<long double, _CharT>
: public __formatter_floating_point<_CharT> {};
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_integer.h b/third_party/llvm-project/libcxx/include/__format/formatter_integer.h
index b4be9f9..0e14410 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_integer.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_integer.h
@@ -19,8 +19,8 @@
#include <__format/formatter_integral.h>
#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
+#include <__type_traits/is_same.h>
#include <__type_traits/make_32_64_or_128_bit.h>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -28,10 +28,10 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <__fmt_char_type _CharT>
- struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_integer {
+ struct _LIBCPP_TEMPLATE_VIS __formatter_integer {
public:
_LIBCPP_HIDE_FROM_ABI constexpr auto
@@ -60,47 +60,47 @@
// Signed integral types.
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<signed char, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<signed char, _CharT>
: public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<short, _CharT> : public __formatter_integer<_CharT> {
+struct _LIBCPP_TEMPLATE_VIS formatter<short, _CharT> : public __formatter_integer<_CharT> {
};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<int, _CharT> : public __formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<int, _CharT> : public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long, _CharT> : public __formatter_integer<_CharT> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<long, _CharT> : public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long long, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<long long, _CharT>
: public __formatter_integer<_CharT> {};
# ifndef _LIBCPP_HAS_NO_INT128
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT>
: public __formatter_integer<_CharT> {};
# endif
// Unsigned integral types.
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned char, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned char, _CharT>
: public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned short, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned short, _CharT>
: public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned, _CharT>
: public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long, _CharT>
: public __formatter_integer<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long long, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long long, _CharT>
: public __formatter_integer<_CharT> {};
# ifndef _LIBCPP_HAS_NO_INT128
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT>
: public __formatter_integer<_CharT> {};
# endif
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_integral.h b/third_party/llvm-project/libcxx/include/__format/formatter_integral.h
index fe3a063..80d2457 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_integral.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_integral.h
@@ -10,6 +10,9 @@
#ifndef _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H
#define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H
+#include <__charconv/to_chars_integral.h>
+#include <__charconv/to_chars_result.h>
+#include <__charconv/traits.h>
#include <__concepts/arithmetic.h>
#include <__concepts/same_as.h>
#include <__config>
@@ -17,11 +20,13 @@
#include <__format/format_error.h>
#include <__format/formatter_output.h>
#include <__format/parser_std_format_spec.h>
+#include <__system_error/errc.h>
+#include <__type_traits/make_unsigned.h>
#include <__utility/unreachable.h>
#include <array>
-#include <charconv>
#include <limits>
#include <string>
+#include <string_view>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
# include <locale>
@@ -36,7 +41,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __formatter {
@@ -354,7 +359,7 @@
} // namespace __formatter
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_output.h b/third_party/llvm-project/libcxx/include/__format/formatter_output.h
index 4676925..f751d8a 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_output.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_output.h
@@ -12,7 +12,10 @@
#include <__algorithm/ranges_copy.h>
#include <__algorithm/ranges_fill_n.h>
+#include <__algorithm/ranges_for_each.h>
#include <__algorithm/ranges_transform.h>
+#include <__charconv/to_chars_integral.h>
+#include <__charconv/to_chars_result.h>
#include <__chrono/statically_widen.h>
#include <__concepts/same_as.h>
#include <__config>
@@ -23,10 +26,12 @@
#include <__format/parser_std_format_spec.h>
#include <__format/unicode.h>
#include <__iterator/back_insert_iterator.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
+#include <__system_error/errc.h>
#include <__type_traits/make_unsigned.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
-#include <charconv>
#include <cstddef>
#include <string>
#include <string_view>
@@ -37,7 +42,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __formatter {
@@ -261,11 +266,11 @@
return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
}
-template <class _CharT, class _ParserCharT>
+template <contiguous_iterator _Iterator, class _ParserCharT>
_LIBCPP_HIDE_FROM_ABI auto
-__write(const _CharT* __first,
- const _CharT* __last,
- output_iterator<const _CharT&> auto __out_it,
+__write(_Iterator __first,
+ _Iterator __last,
+ output_iterator<const iter_value_t<_Iterator>&> auto __out_it,
__format_spec::__parsed_specifications<_ParserCharT> __specs,
ptrdiff_t __size) -> decltype(__out_it) {
_LIBCPP_ASSERT(__first <= __last, "Not a valid range");
@@ -275,11 +280,11 @@
/// \overload
///
/// Calls the function above where \a __size = \a __last - \a __first.
-template <class _CharT, class _ParserCharT>
+template <contiguous_iterator _Iterator, class _ParserCharT>
_LIBCPP_HIDE_FROM_ABI auto
-__write(const _CharT* __first,
- const _CharT* __last,
- output_iterator<const _CharT&> auto __out_it,
+__write(_Iterator __first,
+ _Iterator __last,
+ output_iterator<const iter_value_t<_Iterator>&> auto __out_it,
__format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) {
_LIBCPP_ASSERT(__first <= __last, "Not a valid range");
return __formatter::__write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first);
@@ -359,7 +364,7 @@
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __precision) {
- __format_spec::__column_width_result<_CharT> __result =
+ __format_spec::__column_width_result __result =
__format_spec::__estimate_column_width(__str, __precision, __format_spec::__column_width_rounding::__down);
__str = basic_string_view<_CharT>{__str.begin(), __result.__last_};
return __result.__width_;
@@ -382,7 +387,7 @@
return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size);
}
-# if _LIBCPP_STD_VER > 20
+# if _LIBCPP_STD_VER >= 23
struct __nul_terminator {};
@@ -501,36 +506,17 @@
__unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()};
while (!__view.__at_end()) {
- const _CharT* __first = __view.__position();
- typename __unicode::__consume_p2286_result __result = __view.__consume_p2286();
- if (__result.__ill_formed_size == 0) {
- if (!__formatter::__is_escaped_sequence_written(__str, __result.__value, __mark))
+ auto __first = __view.__position();
+ typename __unicode::__consume_result __result = __view.__consume();
+ if (__result.__status == __unicode::__consume_result::__ok) {
+ if (!__formatter::__is_escaped_sequence_written(__str, __result.__code_point, __mark))
// 2.2.1.3 - Add the character
ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str));
-
} else {
// 2.2.3 sequence of ill-formed code units
- // The number of code-units in __result.__value depends on the character type being used.
- if constexpr (sizeof(_CharT) == 1) {
- _LIBCPP_ASSERT(__result.__ill_formed_size == 1 || __result.__ill_formed_size == 4,
- "illegal number of invalid code units.");
- if (__result.__ill_formed_size == 1) // ill-formed, one code unit
- __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xff);
- else { // out of valid range, four code units
- // The code point was properly encoded, decode the value.
- __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value >> 18 | 0xf0);
- __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 12 & 0x3f) | 0x80);
- __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 6 & 0x3f) | 0x80);
- __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value & 0x3f) | 0x80);
- }
- } else if constexpr (sizeof(_CharT) == 2) {
- _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-16 at most one invalid code unit");
- __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xffff);
- } else {
- static_assert(sizeof(_CharT) == 4, "unsupported character width");
- _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-32 one code unit is one code point");
- __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value);
- }
+ ranges::for_each(__first, __view.__position(), [&](_CharT __value) {
+ __formatter::__write_escape_ill_formed_code_unit(__str, __formatter::__to_char32(__value));
+ });
}
}
}
@@ -559,11 +545,11 @@
return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs);
}
-# endif // _LIBCPP_STD_VER > 20
+# endif // _LIBCPP_STD_VER >= 23
} // namespace __formatter
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_pointer.h b/third_party/llvm-project/libcxx/include/__format/formatter_pointer.h
index 31b49e1..48d8372 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_pointer.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_pointer.h
@@ -27,13 +27,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS __formatter_pointer {
public:
- constexpr __formatter_pointer() { __parser_.__alignment_ = __format_spec::__alignment::__right; }
-
_LIBCPP_HIDE_FROM_ABI constexpr auto
parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) {
auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_pointer);
@@ -48,7 +46,7 @@
return __formatter::__format_integer(reinterpret_cast<uintptr_t>(__ptr), __ctx, __specs);
}
- __format_spec::__parser<_CharT> __parser_;
+ __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right};
};
// [format.formatter.spec]/2.4
@@ -57,16 +55,16 @@
// - template<> struct formatter<void*, charT>;
// - template<> struct formatter<const void*, charT>;
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<nullptr_t, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<nullptr_t, _CharT>
: public __formatter_pointer<_CharT> {};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<void*, _CharT> : public __formatter_pointer<_CharT> {
+struct _LIBCPP_TEMPLATE_VIS formatter<void*, _CharT> : public __formatter_pointer<_CharT> {
};
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const void*, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<const void*, _CharT>
: public __formatter_pointer<_CharT> {};
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_string.h b/third_party/llvm-project/libcxx/include/__format/formatter_string.h
index 606fb79..c14518b 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_string.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_string.h
@@ -27,7 +27,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS __formatter_string {
@@ -40,7 +40,7 @@
}
_LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str, auto& __ctx) const -> decltype(__ctx.out()) {
-# if _LIBCPP_STD_VER > 20
+# if _LIBCPP_STD_VER >= 23
if (__parser_.__type_ == __format_spec::__type::__debug)
return __formatter::__format_escaped_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
# endif
@@ -48,7 +48,7 @@
return __formatter::__write_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx));
}
-# if _LIBCPP_STD_VER > 20
+# if _LIBCPP_STD_VER >= 23
_LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; }
# endif
@@ -57,7 +57,7 @@
// Formatter const char*.
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<const _CharT*, _CharT>
: public __formatter_string<_CharT> {
using _Base = __formatter_string<_CharT>;
@@ -66,7 +66,7 @@
"prevented an invalid pointer.");
__format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx);
-# if _LIBCPP_STD_VER > 20
+# 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
@@ -95,7 +95,7 @@
// Formatter char*.
template <__fmt_char_type _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT>
: public formatter<const _CharT*, _CharT> {
using _Base = formatter<const _CharT*, _CharT>;
@@ -106,7 +106,7 @@
// Formatter char[].
template <__fmt_char_type _CharT, size_t _Size>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT[_Size], _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT>
: public __formatter_string<_CharT> {
using _Base = __formatter_string<_CharT>;
@@ -115,20 +115,9 @@
}
};
-// Formatter const char[].
-template <__fmt_char_type _CharT, size_t _Size>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT[_Size], _CharT>
- : public __formatter_string<_CharT> {
- using _Base = __formatter_string<_CharT>;
-
- _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) {
- return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx);
- }
-};
-
// Formatter std::string.
template <__fmt_char_type _CharT, class _Traits, class _Allocator>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT>
: public __formatter_string<_CharT> {
using _Base = __formatter_string<_CharT>;
@@ -141,7 +130,7 @@
// Formatter std::string_view.
template <__fmt_char_type _CharT, class _Traits>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string_view<_CharT, _Traits>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT>
: public __formatter_string<_CharT> {
using _Base = __formatter_string<_CharT>;
@@ -152,7 +141,7 @@
}
};
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/formatter_tuple.h b/third_party/llvm-project/libcxx/include/__format/formatter_tuple.h
index 82f5ada..9d6367b 100644
--- a/third_party/llvm-project/libcxx/include/__format/formatter_tuple.h
+++ b/third_party/llvm-project/libcxx/include/__format/formatter_tuple.h
@@ -14,6 +14,7 @@
#include <__availability>
#include <__chrono/statically_widen.h>
#include <__config>
+#include <__format/buffer.h>
#include <__format/concepts.h>
#include <__format/format_args.h>
#include <__format/format_context.h>
@@ -35,50 +36,55 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
template <__fmt_char_type _CharT, class _Tuple, formattable<_CharT>... _Args>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple {
- _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+struct _LIBCPP_TEMPLATE_VIS __formatter_tuple {
+ _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
__separator_ = __separator;
}
_LIBCPP_HIDE_FROM_ABI constexpr void
- set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+ set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
__opening_bracket_ = __opening_bracket;
__closing_bracket_ = __closing_bracket;
}
template <class _ParseContext>
_LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
- const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_tuple);
+ auto __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_tuple);
- // [format.tuple]/7
- // ... For each element e in underlying_, if e.set_debug_format()
- // is a valid expression, calls e.set_debug_format().
- // TODO FMT this can be removed when P2733 is accepted.
- std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
- std::__set_debug_format(std::get<_Index>(__underlying_));
- });
-
- const _CharT* __end = __parse_ctx.end();
- if (__begin == __end)
- return __begin;
-
- if (*__begin == _CharT('m')) {
- if constexpr (sizeof...(_Args) == 2) {
- set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
+ auto __end = __parse_ctx.end();
+ if (__begin != __end) {
+ if (*__begin == _CharT('m')) {
+ if constexpr (sizeof...(_Args) == 2) {
+ set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
+ set_brackets({}, {});
+ ++__begin;
+ } else
+ std::__throw_format_error("The format specifier m requires a pair or a two-element tuple");
+ } else if (*__begin == _CharT('n')) {
set_brackets({}, {});
++__begin;
- } else
- std::__throw_format_error("The format specifier m requires a pair or a two-element tuple");
- } else if (*__begin == _CharT('n')) {
- set_brackets({}, {});
- ++__begin;
+ }
}
if (__begin != __end && *__begin != _CharT('}'))
std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+ __parse_ctx.advance_to(__begin);
+
+ // [format.tuple]/7
+ // ... For each element e in underlying_, if e.set_debug_format()
+ // is a valid expression, calls e.set_debug_format().
+ std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
+ auto& __formatter = std::get<_Index>(__underlying_);
+ __formatter.parse(__parse_ctx);
+ // Unlike the range_formatter we don't guard against evil parsers. Since
+ // this format-spec never has a format-spec for the underlying type
+ // adding the test would give additional overhead.
+ std::__set_debug_format(__formatter);
+ });
+
return __begin;
}
@@ -91,26 +97,25 @@
if (!__specs.__has_width())
return __format_tuple(__tuple, __ctx);
- basic_string<_CharT> __str;
-
- // Since the output is written to a different iterator a new context is
- // created. Since the underlying formatter uses the default formatting it
- // doesn't need a locale or the formatting arguments. So creating a new
- // context works.
- //
- // This solution works for this formatter, but it will not work for the
- // range_formatter. In that patch a generic solution is work in progress.
- // Once that is finished it can be used here. (The range_formatter will use
- // these features so it's easier to add it there and then port it.)
- //
- // TODO FMT Use formatting wrapping used in the range_formatter.
- basic_format_context __c = std::__format_context_create(
- back_insert_iterator{__str},
- basic_format_args<basic_format_context<back_insert_iterator<basic_string<_CharT>>, _CharT>>{});
+ // The size of the buffer needed is:
+ // - open bracket characters
+ // - close bracket character
+ // - n elements where every element may have a different size
+ // - (n -1) separators
+ // The size of the element is hard to predict, knowing the type helps but
+ // it depends on the format-spec. As an initial estimate we guess 6
+ // characters.
+ // Typically both brackets are 1 character and the separator is 2
+ // characters. Which means there will be
+ // (n - 1) * 2 + 1 + 1 = n * 2 character
+ // So estimate 8 times the range size as buffer.
+ __format::__retarget_buffer<_CharT> __buffer{8 * tuple_size_v<_Tuple>};
+ basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> __c{
+ __buffer.__make_output_iterator(), __ctx};
__format_tuple(__tuple, __c);
- return __formatter::__write_string_no_precision(basic_string_view{__str}, __ctx.out(), __specs);
+ return __formatter::__write_string_no_precision(basic_string_view{__buffer.__view()}, __ctx.out(), __specs);
}
template <class _FormatContext>
@@ -120,35 +125,7 @@
std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
if constexpr (_Index)
__ctx.advance_to(std::ranges::copy(__separator_, __ctx.out()).out);
-
- // During review Victor suggested to make the exposition only
- // __underlying_ member a local variable. Currently the Standard
- // requires nested debug-enabled formatter specializations not to
- // output escaped output. P2733 fixes that bug, once accepted the
- // code below can be used.
- // (Note when a paper allows parsing a tuple-underlying-spec the
- // exposition only member needs to be a class member. Earlier
- // revisions of P2286 proposed that, but this was not pursued,
- // due to time constrains and complexity of the matter.)
- // TODO FMT This can be updated after P2733 is accepted.
-# if 0
- // P2286 uses an exposition only member in the formatter
- // tuple<formatter<remove_cvref_t<_Args>, _CharT>...> __underlying_;
- // This was used in earlier versions of the paper since
- // __underlying_.parse(...) was called. This is no longer the case
- // so we can reduce the scope of the formatter.
- //
- // It does require the underlying's parse effect to be moved here too.
- using _Arg = tuple_element<_Index, decltype(__tuple)>;
- formatter<remove_cvref_t<_Args>, _CharT> __underlying;
-
- // [format.tuple]/7
- // ... For each element e in underlying_, if e.set_debug_format()
- // is a valid expression, calls e.set_debug_format().
- std::__set_debug_format(__underlying);
-# else
__ctx.advance_to(std::get<_Index>(__underlying_).format(std::get<_Index>(__tuple), __ctx));
-# endif
});
return std::ranges::copy(__closing_bracket_, __ctx.out()).out;
@@ -164,14 +141,14 @@
};
template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<pair<_Args...>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<pair<_Args...>, _CharT>
: public __formatter_tuple<_CharT, pair<_Args...>, _Args...> {};
template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<tuple<_Args...>, _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<tuple<_Args...>, _CharT>
: public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {};
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/parser_std_format_spec.h b/third_party/llvm-project/libcxx/include/__format/parser_std_format_spec.h
index c03cec9..620ce4f 100644
--- a/third_party/llvm-project/libcxx/include/__format/parser_std_format_spec.h
+++ b/third_party/llvm-project/libcxx/include/__format/parser_std_format_spec.h
@@ -28,11 +28,13 @@
#include <__format/format_parse_context.h>
#include <__format/format_string.h>
#include <__format/unicode.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
+#include <__type_traits/common_type.h>
+#include <__type_traits/is_trivially_copyable.h>
#include <__variant/monostate.h>
-#include <bit>
#include <cstdint>
#include <string_view>
-#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -43,13 +45,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __format_spec {
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT>
-__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result<_Iterator>
+__parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
+ using _CharT = iter_value_t<_Iterator>;
// This function is a wrapper to call the real parser. But it does the
// validation for the pre-conditions and post-conditions.
if (__begin == __end)
@@ -57,10 +60,10 @@
__format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
- if (__r.__ptr == __end || *__r.__ptr != _CharT('}'))
+ if (__r.__last == __end || *__r.__last != _CharT('}'))
std::__throw_format_error("Invalid arg-id");
- ++__r.__ptr;
+ ++__r.__last;
return __r;
}
@@ -78,22 +81,33 @@
return _VSTD::__visit_format_arg(
[](auto __arg) -> uint32_t {
using _Type = decltype(__arg);
- if constexpr (integral<_Type>) {
+ if constexpr (same_as<_Type, monostate>)
+ std::__throw_format_error("Argument index out of bounds");
+
+ // [format.string.std]/8
+ // If { arg-idopt } is used in a width or precision, the value of the
+ // corresponding formatting argument is used in its place. If the
+ // corresponding formatting argument is not of standard signed or unsigned
+ // integer type, or its value is negative for precision or non-positive for
+ // width, an exception of type format_error is thrown.
+ //
+ // When an integral is used in a format function, it is stored as one of
+ // the types checked below. Other integral types are promoted. For example,
+ // a signed char is stored as an int.
+ if constexpr (same_as<_Type, int> || same_as<_Type, unsigned int> || //
+ same_as<_Type, long long> || same_as<_Type, unsigned long long>) {
if constexpr (signed_integral<_Type>) {
if (__arg < 0)
std::__throw_format_error("A format-spec arg-id replacement shouldn't have a negative value");
}
using _CT = common_type_t<_Type, decltype(__format::__number_max)>;
- if (static_cast<_CT>(__arg) >
- static_cast<_CT>(__format::__number_max))
+ if (static_cast<_CT>(__arg) > static_cast<_CT>(__format::__number_max))
std::__throw_format_error("A format-spec arg-id replacement exceeds the maximum supported value");
return __arg;
- } else if constexpr (same_as<_Type, monostate>)
- std::__throw_format_error("Argument index out of bounds");
- else
- std::__throw_format_error("A format-spec arg-id replacement argument isn't an integral type");
+ } else
+ std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type");
},
__format_arg);
}
@@ -116,7 +130,7 @@
// formatters use the colon to mark the beginning of the
// underlying-format-spec. To avoid parsing ambiguities these formatter
// specializations prohibit the use of the colon as a fill character.
- uint8_t __allow_colon_in_fill_ : 1 {false};
+ uint8_t __use_range_fill_ : 1 {false};
};
// By not placing this constant in the formatter class it's not duplicated for
@@ -137,9 +151,10 @@
inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true};
inline constexpr __fields __fields_pointer{.__type_ = true};
-# if _LIBCPP_STD_VER > 20
-inline constexpr __fields __fields_tuple{.__type_ = false, .__allow_colon_in_fill_ = true};
-inline constexpr __fields __fields_range{.__type_ = false, .__allow_colon_in_fill_ = true};
+# if _LIBCPP_STD_VER >= 23
+inline constexpr __fields __fields_tuple{.__use_range_fill_ = true};
+inline constexpr __fields __fields_range{.__use_range_fill_ = true};
+inline constexpr __fields __fields_fill_align_width{};
# endif
enum class _LIBCPP_ENUM_VIS __alignment : uint8_t {
@@ -196,6 +211,7 @@
struct __chrono {
__alignment __alignment_ : 3;
bool __locale_specific_form_ : 1;
+ bool __hour_ : 1;
bool __weekday_name_ : 1;
bool __weekday_ : 1;
bool __day_of_year_ : 1;
@@ -268,12 +284,12 @@
_LIBCPP_HIDE_FROM_ABI constexpr auto __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields)
-> decltype(__parse_ctx.begin()) {
- const _CharT* __begin = __parse_ctx.begin();
- const _CharT* __end = __parse_ctx.end();
+ auto __begin = __parse_ctx.begin();
+ auto __end = __parse_ctx.end();
if (__begin == __end)
return __begin;
- if (__parse_fill_align(__begin, __end, __fields.__allow_colon_in_fill_) && __begin == __end)
+ if (__parse_fill_align(__begin, __end, __fields.__use_range_fill_) && __begin == __end)
return __begin;
if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end)
@@ -326,6 +342,7 @@
.__chrono_ =
__chrono{.__alignment_ = __alignment_,
.__locale_specific_form_ = __locale_specific_form_,
+ .__hour_ = __hour_,
.__weekday_name_ = __weekday_name_,
.__weekday_ = __weekday_,
.__day_of_year_ = __day_of_year_,
@@ -345,6 +362,8 @@
// These flags are only used for formatting chrono. Since the struct has
// padding space left it's added to this structure.
+ bool __hour_ : 1 {false};
+
bool __weekday_name_ : 1 {false};
bool __weekday_ : 1 {false};
@@ -353,7 +372,7 @@
bool __month_name_ : 1 {false};
- uint8_t __reserved_1_ : 3 {0};
+ uint8_t __reserved_1_ : 2 {0};
uint8_t __reserved_2_ : 6 {0};
// These two flags are only used internally and not part of the
// __parsed_specifications. Therefore put them at the end.
@@ -391,8 +410,8 @@
}
// range-fill and tuple-fill are identical
- _LIBCPP_HIDE_FROM_ABI constexpr bool
- __parse_fill_align(const _CharT*& __begin, const _CharT* __end, bool __use_range_fill) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) {
_LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause "
"undefined behavior by evaluating data not in the input");
if (__begin + 1 != __end) {
@@ -415,7 +434,8 @@
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(_Iterator& __begin) {
switch (*__begin) {
case _CharT('-'):
__sign_ = __sign::__minus;
@@ -433,7 +453,8 @@
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(_Iterator& __begin) {
if (*__begin != _CharT('#'))
return false;
@@ -442,7 +463,8 @@
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(_Iterator& __begin) {
if (*__begin != _CharT('0'))
return false;
@@ -452,7 +474,8 @@
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(_Iterator& __begin, _Iterator __end, auto& __parse_ctx) {
if (*__begin == _CharT('0'))
std::__throw_format_error("A format-spec width field shouldn't have a leading zero");
@@ -460,7 +483,7 @@
__format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
__width_as_arg_ = true;
__width_ = __r.__value;
- __begin = __r.__ptr;
+ __begin = __r.__last;
return true;
}
@@ -471,12 +494,12 @@
__width_ = __r.__value;
_LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, "
"due to validations in this function");
- __begin = __r.__ptr;
+ __begin = __r.__last;
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(const _CharT*& __begin, const _CharT* __end,
- auto& __parse_ctx) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(_Iterator& __begin, _Iterator __end, auto& __parse_ctx) {
if (*__begin != _CharT('.'))
return false;
@@ -488,7 +511,7 @@
__format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
__precision_as_arg_ = true;
__precision_ = __arg_id.__value;
- __begin = __arg_id.__ptr;
+ __begin = __arg_id.__last;
return true;
}
@@ -498,11 +521,12 @@
__format::__parse_number_result __r = __format::__parse_number(__begin, __end);
__precision_ = __r.__value;
__precision_as_arg_ = false;
- __begin = __r.__ptr;
+ __begin = __r.__last;
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(_Iterator& __begin) {
if (*__begin != _CharT('L'))
return false;
@@ -511,7 +535,8 @@
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin) {
// Determines the type. It does not validate whether the selected type is
// valid. Most formatters have optional fields that are only allowed for
// certain types. These parsers need to do validation after the type has
@@ -569,7 +594,7 @@
case 'x':
__type_ = __type::__hexadecimal_lower_case;
break;
-# if _LIBCPP_STD_VER > 20
+# if _LIBCPP_STD_VER >= 23
case '?':
__type_ = __type::__debug;
break;
@@ -734,18 +759,18 @@
}
}
-template <class _CharT>
+template <contiguous_iterator _Iterator>
struct __column_width_result {
/// The number of output columns.
size_t __width_;
/// One beyond the last code unit used in the estimation.
///
/// This limits the original output to fit in the wanted number of columns.
- const _CharT* __last_;
+ _Iterator __last_;
};
-template <class _CharT>
-__column_width_result(size_t, const _CharT*) -> __column_width_result<_CharT>;
+template <contiguous_iterator _Iterator>
+__column_width_result(size_t, _Iterator) -> __column_width_result<_Iterator>;
/// Since a column width can be two it's possible that the requested column
/// width can't be achieved. Depending on the intended usage the policy can be
@@ -812,12 +837,13 @@
return __detail::__column_width_4(__c);
}
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width_grapheme_clustering(
- const _CharT* __first, const _CharT* __last, size_t __maximum, __column_width_rounding __rounding) noexcept {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width_grapheme_clustering(
+ _Iterator __first, _Iterator __last, size_t __maximum, __column_width_rounding __rounding) noexcept {
+ using _CharT = iter_value_t<_Iterator>;
__unicode::__extended_grapheme_cluster_view<_CharT> __view{__first, __last};
- __column_width_result<_CharT> __result{0, __first};
+ __column_width_result<_Iterator> __result{0, __first};
while (__result.__last_ != __last && __result.__width_ <= __maximum) {
typename __unicode::__extended_grapheme_cluster_view<_CharT>::__cluster __cluster = __view.__consume();
int __width = __detail::__column_width(__cluster.__code_point_);
@@ -884,8 +910,8 @@
/// \param __rounding Selects the rounding method.
/// \c __down result.__width_ <= __maximum
/// \c __up result.__width_ <= __maximum + 1
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width(
+template <class _CharT, class _Iterator = typename basic_string_view<_CharT>::const_iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width(
basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding __rounding) noexcept {
// The width estimation is done in two steps:
// - Quickly process for the ASCII part. ASCII has the following properties
@@ -904,7 +930,7 @@
// need to scan one code unit beyond the requested precision. When this code
// unit is non-ASCII we omit the current code unit and let the Grapheme
// clustering algorithm do its work.
- const _CharT* __it = __str.begin();
+ auto __it = __str.begin();
if (__format_spec::__is_ascii(*__it)) {
do {
--__maximum;
@@ -932,7 +958,7 @@
}
# else // !defined(_LIBCPP_HAS_NO_UNICODE)
template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_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 {
// When Unicode isn't supported assume ASCII and every code unit is one code
// point. In ASCII the estimated column width is always one. Thus there's no
@@ -945,7 +971,7 @@
} // namespace __format_spec
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/range_default_formatter.h b/third_party/llvm-project/libcxx/include/__format/range_default_formatter.h
index 774887b..3954f98 100644
--- a/third_party/llvm-project/libcxx/include/__format/range_default_formatter.h
+++ b/third_party/llvm-project/libcxx/include/__format/range_default_formatter.h
@@ -14,6 +14,7 @@
# pragma GCC system_header
#endif
+#include <__algorithm/ranges_copy.h>
#include <__availability>
#include <__chrono/statically_widen.h>
#include <__concepts/same_as.h>
@@ -21,7 +22,10 @@
#include <__format/concepts.h>
#include <__format/formatter.h>
#include <__format/range_formatter.h>
+#include <__iterator/back_insert_iterator.h>
#include <__ranges/concepts.h>
+#include <__ranges/data.h>
+#include <__ranges/size.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/pair.h>
#include <string_view>
@@ -29,7 +33,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
template <class _Rp, class _CharT>
concept __const_formattable_range =
@@ -83,40 +87,23 @@
return range_format::sequence;
}();
-// This is a non-standard work-around to fix instantiation of
-// formatter<const _CharT[N], _CharT>
-// const _CharT[N] satisfies the ranges::input_range concept.
-// remove_cvref_t<const _CharT[N]> is _CharT[N] so it does not satisfy the
-// requirement of the above specialization. Instead it will instantiate the
-// primary template, which is ill-formed.
-//
-// An alternative solution is to remove the offending formatter.
-//
-// https://godbolt.org/z/bqjhhaexx
-//
-// The removal is proposed in LWG3833, but use the work-around until the issue
-// has been adopted.
-// TODO FMT Implement LWG3833.
-template <class _CharT, size_t N>
-inline constexpr range_format format_kind<const _CharT[N]> = range_format::disabled;
-
template <range_format _Kp, ranges::input_range _Rp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter;
+struct _LIBCPP_TEMPLATE_VIS __range_default_formatter;
// Required specializations
template <ranges::input_range _Rp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::sequence, _Rp, _CharT> {
+struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::sequence, _Rp, _CharT> {
private:
using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>;
range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_;
public:
- _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+ _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
__underlying_.set_separator(__separator);
}
_LIBCPP_HIDE_FROM_ABI constexpr void
- set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+ set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
__underlying_.set_brackets(__opening_bracket, __closing_bracket);
}
@@ -132,7 +119,7 @@
};
template <ranges::input_range _Rp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::map, _Rp, _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>>;
@@ -160,7 +147,7 @@
};
template <ranges::input_range _Rp, class _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::set, _Rp, _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>>;
@@ -185,16 +172,48 @@
template <range_format _Kp, ranges::input_range _Rp, class _CharT>
requires(_Kp == range_format::string || _Kp == range_format::debug_string)
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<_Kp, _Rp, _CharT> {
- __range_default_formatter() = delete; // TODO FMT Implement
+struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<_Kp, _Rp, _CharT> {
+private:
+ // This deviates from the Standard, there the exposition only type is
+ // formatter<basic_string<charT>, charT> underlying_;
+ // Using a string_view allows the format function to avoid a copy of the
+ // input range when it is a contigious range.
+ formatter<basic_string_view<_CharT>, _CharT> __underlying_;
+
+public:
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+ typename _ParseContext::iterator __i = __underlying_.parse(__ctx);
+ if constexpr (_Kp == range_format::debug_string)
+ __underlying_.set_debug_format();
+ return __i;
+ }
+
+ template <class _FormatContext>
+ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
+ format(conditional_t<ranges::input_range<const _Rp>, const _Rp&, _Rp&> __range, _FormatContext& __ctx) const {
+ // When the range is contiguous use a basic_string_view instead to avoid a
+ // copy of the underlying data. The basic_string_view formatter
+ // specialization is the "basic" string formatter in libc++.
+ if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>)
+ return __underlying_.format(basic_string_view<_CharT>{ranges::data(__range), ranges::size(__range)}, __ctx);
+ else {
+ // P2106's from_range has not been implemented yet. Instead use a simple
+ // copy operation.
+ // TODO FMT use basic_string's "from_range" constructor.
+ // return __underlying_.format(basic_string<_CharT>{from_range, __range}, __ctx);
+ basic_string<_CharT> __str;
+ std::ranges::copy(__range, back_insert_iterator{__str});
+ return __underlying_.format(static_cast<basic_string_view<_CharT>>(__str), __ctx);
+ }
+ }
};
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 _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT>
- : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
+struct _LIBCPP_TEMPLATE_VIS formatter<_Rp, _CharT> : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/range_formatter.h b/third_party/llvm-project/libcxx/include/__format/range_formatter.h
index 9ea61a7..0af233e 100644
--- a/third_party/llvm-project/libcxx/include/__format/range_formatter.h
+++ b/third_party/llvm-project/libcxx/include/__format/range_formatter.h
@@ -36,49 +36,78 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 20
+#if _LIBCPP_STD_VER >= 23
template <class _Tp, class _CharT = char>
requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT>
-struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter {
- _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) {
+struct _LIBCPP_TEMPLATE_VIS range_formatter {
+ _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
__separator_ = __separator;
}
_LIBCPP_HIDE_FROM_ABI constexpr void
- set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) {
+ set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
__opening_bracket_ = __opening_bracket;
__closing_bracket_ = __closing_bracket;
}
- _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() { return __underlying_; }
- _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const { return __underlying_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() noexcept { return __underlying_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const noexcept { return __underlying_; }
template <class _ParseContext>
_LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) {
- const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range);
- const _CharT* __end = __parse_ctx.end();
- if (__begin == __end)
- return __begin;
+ auto __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range);
+ auto __end = __parse_ctx.end();
+ // Note the cases where __begin == __end in this code only happens when the
+ // replacement-field has no terminating }, or when the parse is manually
+ // called with a format-spec. The former is an error and the latter means
+ // using a formatter without the format functions or print.
+ if (__begin == __end) [[unlikely]]
+ return __parse_empty_range_underlying_spec(__parse_ctx, __begin);
// The n field overrides a possible m type, therefore delay applying the
// effect of n until the type has been procesed.
bool __clear_brackets = (*__begin == _CharT('n'));
if (__clear_brackets) {
++__begin;
- if (__begin == __end) {
+ if (__begin == __end) [[unlikely]] {
// Since there is no more data, clear the brackets before returning.
set_brackets({}, {});
- return __begin;
+ return __parse_empty_range_underlying_spec(__parse_ctx, __begin);
}
}
__parse_type(__begin, __end);
if (__clear_brackets)
set_brackets({}, {});
- if (__begin == __end)
- return __begin;
+ if (__begin == __end) [[unlikely]]
+ return __parse_empty_range_underlying_spec(__parse_ctx, __begin);
bool __has_range_underlying_spec = *__begin == _CharT(':');
+ if (__has_range_underlying_spec) {
+ // range-underlying-spec:
+ // : format-spec
+ ++__begin;
+ } else if (__begin != __end && *__begin != _CharT('}'))
+ // When there is no underlaying range the current parse should have
+ // consumed the format-spec. If not, the not consumed input will be
+ // processed by the underlying. For example {:-} for a range in invalid,
+ // the sign field is not present. Without this check the underlying_ will
+ // get -} as input which my be valid.
+ std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+
+ __parse_ctx.advance_to(__begin);
+ __begin = __underlying_.parse(__parse_ctx);
+
+ // This test should not be required if __has_range_underlying_spec is false.
+ // However this test makes sure the underlying formatter left the parser in
+ // a valid state. (Note this is not a full protection against evil parsers.
+ // For example
+ // } this is test for the next argument {}
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
+ // could consume more than it should.
+ if (__begin != __end && *__begin != _CharT('}'))
+ std::__throw_format_error("The format-spec should consume the input or end with a '}'");
+
if (__parser_.__type_ != __format_spec::__type::__default) {
// [format.range.formatter]/6
// If the range-type is s or ?s, then there shall be no n option and no
@@ -96,20 +125,6 @@
} else if (!__has_range_underlying_spec)
std::__set_debug_format(__underlying_);
- if (__has_range_underlying_spec) {
- // range-underlying-spec:
- // : format-spec
- ++__begin;
- if (__begin == __end)
- return __begin;
-
- __parse_ctx.advance_to(__begin);
- __begin = __underlying_.parse(__parse_ctx);
- }
-
- if (__begin != __end && *__begin != _CharT('}'))
- std::__throw_format_error("The format-spec should consume the input or end with a '}'");
-
return __begin;
}
@@ -211,7 +226,8 @@
__format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left};
private:
- _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin, const _CharT* __end) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin, _Iterator __end) {
switch (*__begin) {
case _CharT('m'):
if constexpr (__fmt_pair_like<_Tp>) {
@@ -242,13 +258,23 @@
}
}
+ template <class _ParseContext>
+ _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator
+ __parse_empty_range_underlying_spec(_ParseContext& __parse_ctx, typename _ParseContext::iterator __begin) {
+ __parse_ctx.advance_to(__begin);
+ [[maybe_unused]] typename _ParseContext::iterator __result = __underlying_.parse(__parse_ctx);
+ _LIBCPP_ASSERT(__result == __begin,
+ "the underlying's parse function should not advance the input beyond the end of the input");
+ return __begin;
+ }
+
formatter<_Tp, _CharT> __underlying_;
basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", ");
basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "[");
basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]");
};
-#endif //_LIBCPP_STD_VER > 20
+#endif //_LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/third_party/llvm-project/libcxx/include/__format/unicode.h b/third_party/llvm-project/libcxx/include/__format/unicode.h
index 4327258..12aed50 100644
--- a/third_party/llvm-project/libcxx/include/__format/unicode.h
+++ b/third_party/llvm-project/libcxx/include/__format/unicode.h
@@ -11,11 +11,15 @@
#define _LIBCPP___FORMAT_UNICODE_H
#include <__assert>
+#include <__bit/countl.h>
+#include <__concepts/same_as.h>
#include <__config>
#include <__format/extended_grapheme_cluster_table.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
#include <__type_traits/make_unsigned.h>
#include <__utility/unreachable.h>
-#include <bit>
+#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -23,27 +27,32 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if _LIBCPP_STD_VER > 17
+#if _LIBCPP_STD_VER >= 20
namespace __unicode {
-# if _LIBCPP_STD_VER > 20
+// Helper struct for the result of a consume operation.
+//
+// The status value for a correct code point is 0. This allows a valid value to
+// be used without masking.
+// When the decoding fails it know the number of code units affected. For the
+// current use-cases that value is not needed, therefore it is not stored.
+// The escape routine needs the number of code units for both a valid and
+// invalid character and keeps track of it itself. Doing it in this result
+// unconditionally would give some overhead when the value is unneeded.
+struct __consume_result {
+ // When __status == __ok it contains the decoded code point.
+ // Else it contains the replacement character U+FFFD
+ char32_t __code_point : 31;
-/// The result of consuming a code point using P2286' semantics
-///
-/// TODO FMT Combine __consume and __consume_p2286 in one function.
-struct __consume_p2286_result {
- // A size of 0 means well formed. This to differenciate between
- // a valid code point and a code unit that's invalid like 0b11111xxx.
- int __ill_formed_size;
-
- // If well formed the consumed code point.
- // Otherwise the ill-formed code units as unsigned 8-bit values. They are
- // stored in reverse order, to make it easier to extract the values.
- char32_t __value;
+ enum : char32_t {
+ // Consumed a well-formed code point.
+ __ok = 0,
+ // Encountered invalid UTF-8
+ __error = 1
+ } __status : 1 {__ok};
};
-
-# endif // _LIBCPP_STD_VER > 20
+static_assert(sizeof(__consume_result) == sizeof(char32_t));
# ifndef _LIBCPP_HAS_NO_UNICODE
@@ -62,7 +71,39 @@
inline constexpr char32_t __replacement_character = U'\ufffd';
-_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(const char* __char, int __count) {
+// The error of a consume operation.
+//
+// This sets the code point to the replacement character. This code point does
+// not participate in the grapheme clustering, so grapheme clustering code can
+// ignore the error status and always use the code point.
+inline constexpr __consume_result __consume_result_error{__replacement_character, __consume_result::__error};
+
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __is_high_surrogate(char32_t __value) {
+ return __value >= 0xd800 && __value <= 0xdbff;
+}
+
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __is_low_surrogate(char32_t __value) {
+ return __value >= 0xdc00 && __value <= 0xdfff;
+}
+
+// https://www.unicode.org/glossary/#surrogate_code_point
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_surrogate(char32_t __value) {
+ return __value >= 0xd800 && __value <= 0xdfff;
+}
+
+// https://www.unicode.org/glossary/#code_point
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_code_point(char32_t __value) {
+ return __value <= 0x10ffff;
+}
+
+// https://www.unicode.org/glossary/#unicode_scalar_value
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_scalar_value(char32_t __value) {
+ return __unicode::__is_code_point(__value) && !__unicode::__is_surrogate(__value);
+}
+
+template <contiguous_iterator _Iterator>
+ requires same_as<iter_value_t<_Iterator>, char>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(_Iterator __char, int __count) {
do {
if ((*__char & 0b1000'0000) != 0b1000'0000)
return false;
@@ -82,68 +123,38 @@
/// UTF-8 specialization.
template <>
class __code_point_view<char> {
+ using _Iterator = basic_string_view<char>::const_iterator;
+
public:
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const char* __first, const char* __last)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
: __first_(__first), __last_(__last) {}
_LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
- _LIBCPP_HIDE_FROM_ABI constexpr const char* __position() const noexcept { return __first_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
- _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
- _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
-
- // Based on the number of leading 1 bits the number of code units in the
- // code point can be determined. See
- // https://en.wikipedia.org/wiki/UTF-8#Encoding
- switch (_VSTD::countl_one(static_cast<unsigned char>(*__first_))) {
- case 0:
- return *__first_++;
-
- case 2:
- if (__last_ - __first_ < 2 || !__unicode::__is_continuation(__first_ + 1, 1)) [[unlikely]]
- break;
- else {
- char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- return __value;
- }
-
- case 3:
- if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]]
- break;
- else {
- char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- return __value;
- }
-
- case 4:
- if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]]
- break;
- else {
- char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- return __value;
- }
- }
- // An invalid number of leading ones can be garbage or a code unit in the
- // middle of a code point. By consuming one code unit the parser may get
- // "in sync" after a few code units.
- ++__first_;
- return __replacement_character;
- }
-
-# if _LIBCPP_STD_VER > 20
- _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
+ // https://www.unicode.org/versions/latest/ch03.pdf#G7404
+ // Based on Table 3-7, Well-Formed UTF-8 Byte Sequences
+ //
+ // Code Points First Byte Second Byte Third Byte Fourth Byte Remarks
+ // U+0000..U+007F 00..7F U+0000..U+007F 1 code unit range
+ // C0..C1 80..BF invalid overlong encoding
+ // U+0080..U+07FF C2..DF 80..BF U+0080..U+07FF 2 code unit range
+ // E0 80..9F 80..BF invalid overlong encoding
+ // U+0800..U+0FFF E0 A0..BF 80..BF U+0800..U+FFFF 3 code unit range
+ // U+1000..U+CFFF E1..EC 80..BF 80..BF
+ // U+D000..U+D7FF ED 80..9F 80..BF
+ // U+D800..U+DFFF ED A0..BF 80..BF invalid encoding of surrogate code point
+ // U+E000..U+FFFF EE..EF 80..BF 80..BF
+ // F0 80..8F 80..BF 80..BF invalid overlong encoding
+ // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF U+10000..U+10FFFF 4 code unit range
+ // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
+ // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
+ // F4 90..BF 80..BF 80..BF U+110000.. invalid code point range
+ //
+ // Unlike other parsers, these invalid entries are tested after decoding.
+ // - The parser always needs to consume these code units
+ // - The code is optimized for well-formed UTF-8
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
_LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
// Based on the number of leading 1 bits the number of code units in the
@@ -151,64 +162,77 @@
// https://en.wikipedia.org/wiki/UTF-8#Encoding
switch (std::countl_one(static_cast<unsigned char>(*__first_))) {
case 0:
- return {0, static_cast<unsigned char>(*__first_++)};
+ return {static_cast<unsigned char>(*__first_++)};
- case 2:
- if (__last_ - __first_ < 2) [[unlikely]]
+ case 2: {
+ if (__last_ - __first_ < 2 || !__unicode::__is_continuation(__first_ + 1, 1)) [[unlikely]]
break;
- if (__unicode::__is_continuation(__first_ + 1, 1)) {
- char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- return {0, __value};
- }
- break;
+ char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f;
+ __value <<= 6;
+ __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- case 3:
- if (__last_ - __first_ < 3) [[unlikely]]
+ // These values should be encoded in 1 UTF-8 code unit.
+ if (__value < 0x0080) [[unlikely]]
+ return __consume_result_error;
+
+ return {__value};
+ }
+
+ case 3: {
+ if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]]
break;
- if (__unicode::__is_continuation(__first_ + 1, 2)) {
- char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- return {0, __value};
- }
- break;
+ char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f;
+ __value <<= 6;
+ __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
+ __value <<= 6;
+ __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- case 4:
- if (__last_ - __first_ < 4) [[unlikely]]
+ // These values should be encoded in 1 or 2 UTF-8 code units.
+ if (__value < 0x0800) [[unlikely]]
+ return __consume_result_error;
+
+ // A surrogate value is always encoded in 3 UTF-8 code units.
+ if (__unicode::__is_surrogate(__value)) [[unlikely]]
+ return __consume_result_error;
+
+ return {__value};
+ }
+
+ case 4: {
+ if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]]
break;
- if (__unicode::__is_continuation(__first_ + 1, 3)) {
- char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- __value <<= 6;
- __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
+ char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07;
+ __value <<= 6;
+ __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
+ __value <<= 6;
+ __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
+ __value <<= 6;
+ __value |= static_cast<unsigned char>(*__first_++) & 0x3f;
- if (__value > 0x10FFFF) // Outside the valid Unicode range?
- return {4, __value};
+ // These values should be encoded in 1, 2, or 3 UTF-8 code units.
+ if (__value < 0x10000) [[unlikely]]
+ return __consume_result_error;
- return {0, __value};
- }
- break;
+ // A value too large is always encoded in 4 UTF-8 code units.
+ if (!__unicode::__is_code_point(__value)) [[unlikely]]
+ return __consume_result_error;
+
+ return {__value};
+ }
}
// An invalid number of leading ones can be garbage or a code unit in the
// middle of a code point. By consuming one code unit the parser may get
// "in sync" after a few code units.
- return {1, static_cast<unsigned char>(*__first_++)};
+ ++__first_;
+ return __consume_result_error;
}
-# endif // _LIBCPP_STD_VER > 20
private:
- const char* __first_;
- const char* __last_;
+ _Iterator __first_;
+ _Iterator __last_;
};
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -225,75 +249,48 @@
/// - 4 UTF-32 (for example Linux)
template <>
class __code_point_view<wchar_t> {
+ using _Iterator = 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");
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const wchar_t* __first, const wchar_t* __last)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
: __first_(__first), __last_(__last) {}
- _LIBCPP_HIDE_FROM_ABI constexpr const wchar_t* __position() const noexcept { return __first_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
_LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
- _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
_LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
+ char32_t __value = static_cast<char32_t>(*__first_++);
if constexpr (sizeof(wchar_t) == 2) {
- char32_t __result = *__first_++;
- // Is the code unit part of a surrogate pair? See
- // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
- if (__result >= 0xd800 && __result <= 0xDfff) {
- // Malformed Unicode.
- if (__first_ == __last_) [[unlikely]]
- return __replacement_character;
+ if (__unicode::__is_low_surrogate(__value)) [[unlikely]]
+ return __consume_result_error;
- __result -= 0xd800;
- __result <<= 10;
- __result += *__first_++ - 0xdc00;
- __result += 0x10000;
+ if (__unicode::__is_high_surrogate(__value)) {
+ if (__first_ == __last_ || !__unicode::__is_low_surrogate(static_cast<char32_t>(*__first_))) [[unlikely]]
+ return __consume_result_error;
+
+ __value -= 0xd800;
+ __value <<= 10;
+ __value += static_cast<char32_t>(*__first_++) - 0xdc00;
+ __value += 0x10000;
+
+ if (!__unicode::__is_code_point(__value)) [[unlikely]]
+ return __consume_result_error;
}
- return __result;
-
- } else if constexpr (sizeof(wchar_t) == 4) {
- char32_t __result = *__first_++;
- if (__result > 0x10FFFF) [[unlikely]]
- return __replacement_character;
- return __result;
} else {
- __libcpp_unreachable();
- }
- }
-
-# if _LIBCPP_STD_VER > 20
- _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
- _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
-
- char32_t __result = *__first_++;
- if constexpr (sizeof(wchar_t) == 2) {
- // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
- if (__is_surrogate_pair_high(__result)) {
- // Malformed Unicode.
- if (__first_ == __last_ || !__is_surrogate_pair_low(*(__first_ + 1))) [[unlikely]]
- return {1, __result};
-
- __result -= 0xd800;
- __result <<= 10;
- __result += *__first_++ - 0xdc00;
- __result += 0x10000;
- } else if (__is_surrogate_pair_low(__result))
- // A code point shouldn't start with the low surrogate pair
- return {1, __result};
- } else {
- if (__result > 0x10FFFF) [[unlikely]]
- return {1, __result};
+ if (!__unicode::__is_scalar_value(__value)) [[unlikely]]
+ return __consume_result_error;
}
- return {0, __result};
+ return {__value};
}
-# endif // _LIBCPP_STD_VER > 20
private:
- const wchar_t* __first_;
- const wchar_t* __last_;
+ _Iterator __first_;
+ _Iterator __last_;
};
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
@@ -384,10 +381,12 @@
/// Therefore only this code point is extracted.
template <class _CharT>
class __extended_grapheme_cluster_view {
+ using _Iterator = typename basic_string_view<_CharT>::const_iterator;
+
public:
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(const _CharT* __first, const _CharT* __last)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(_Iterator __first, _Iterator __last)
: __code_point_view_(__first, __last),
- __next_code_point_(__code_point_view_.__consume()),
+ __next_code_point_(__code_point_view_.__consume().__code_point),
__next_prop_(__extended_grapheme_custer_property_boundary::__get_property(__next_code_point_)) {}
struct __cluster {
@@ -401,13 +400,14 @@
///
/// It's expected the caller has the start position and thus can determine
/// the code unit range of the extended grapheme cluster.
- const _CharT* __last_;
+ _Iterator __last_;
};
_LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() {
_LIBCPP_ASSERT(
__next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot,
"can't move beyond the end of input");
+
char32_t __code_point = __next_code_point_;
if (!__code_point_view_.__at_end())
return {__code_point, __get_break()};
@@ -422,17 +422,17 @@
char32_t __next_code_point_;
__extended_grapheme_custer_property_boundary::__property __next_prop_;
- _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __get_break() {
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __get_break() {
bool __ri_break_allowed = true;
bool __has_extened_pictographic = false;
while (true) {
- const _CharT* __result = __code_point_view_.__position();
+ _Iterator __result = __code_point_view_.__position();
__extended_grapheme_custer_property_boundary::__property __prev = __next_prop_;
if (__code_point_view_.__at_end()) {
__next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot;
return __result;
}
- __next_code_point_ = __code_point_view_.__consume();
+ __next_code_point_ = __code_point_view_.__consume().__code_point;
__next_prop_ = __extended_grapheme_custer_property_boundary::__get_property(__next_code_point_);
__has_extened_pictographic |=
@@ -444,8 +444,8 @@
}
};
-template <class _CharT>
-__extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>;
+template <contiguous_iterator _Iterator>
+__extended_grapheme_cluster_view(_Iterator, _Iterator) -> __extended_grapheme_cluster_view<iter_value_t<_Iterator>>;
# else // _LIBCPP_HAS_NO_UNICODE
@@ -453,36 +453,30 @@
// This makes it easier to write code agnostic of the _LIBCPP_HAS_NO_UNICODE define.
template <class _CharT>
class __code_point_view {
+ using _Iterator = typename basic_string_view<_CharT>::const_iterator;
+
public:
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const _CharT* __first, const _CharT* __last)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
: __first_(__first), __last_(__last) {}
_LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
- _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __position() const noexcept { return __first_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
- _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept {
_LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
- return *__first_++;
+ return {static_cast<char32_t>(*__first_++)};
}
-# if _LIBCPP_STD_VER > 20
- _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept {
- _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
-
- return {0, std::make_unsigned_t<_CharT>(*__first_++)};
- }
-# endif // _LIBCPP_STD_VER > 20
-
private:
- const _CharT* __first_;
- const _CharT* __last_;
+ _Iterator __first_;
+ _Iterator __last_;
};
# endif // _LIBCPP_HAS_NO_UNICODE
} // namespace __unicode
-#endif //_LIBCPP_STD_VER > 17
+#endif //_LIBCPP_STD_VER >= 20
_LIBCPP_END_NAMESPACE_STD