diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1203,11 +1203,15 @@ // explicit deduction guides to do so. This macro is used to mark them as such, which suppresses the // '-Wctad-maybe-unsupported' compiler warning when CTAD is used in user code with these classes. #if _LIBCPP_STD_VER >= 17 -# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \ - template \ - _ClassName(typename _Tag::__allow_ctad) -> _ClassName<_Tag> +# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \ + template \ + _ClassName(typename _Tag::__allow_ctad)->_ClassName<_Tag> +# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE2(_ClassName) \ + template \ + _ClassName(typename _Tag::__allow_ctad, typename _Tag::__allow_ctad)->_ClassName<_Tag, _Tag> #else # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "") +# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE2(_ClassName) static_assert(true, "") #endif #endif // __cplusplus diff --git a/libcxx/include/__format/format_context.h b/libcxx/include/__format/format_context.h --- a/libcxx/include/__format/format_context.h +++ b/libcxx/include/__format/format_context.h @@ -50,8 +50,7 @@ _OutIt __out_it, basic_format_args> __args, optional<_VSTD::locale>&& __loc = nullopt) { - return _VSTD::basic_format_context<_OutIt, _CharT>(_VSTD::move(__out_it), __args, - _VSTD::move(__loc)); + return _VSTD::basic_format_context(_VSTD::move(__out_it), __args, _VSTD::move(__loc)); } #else template @@ -59,7 +58,7 @@ __format_context_create( _OutIt __out_it, basic_format_args> __args) { - return _VSTD::basic_format_context<_OutIt, _CharT>(_VSTD::move(__out_it), __args); + return _VSTD::basic_format_context(_VSTD::move(__out_it), __args); } #endif @@ -143,6 +142,7 @@ : __out_it_(_VSTD::move(__out_it)), __args_(__args) {} #endif }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE2(basic_format_context); #endif //_LIBCPP_STD_VER > 17 diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h --- a/libcxx/include/__format/format_functions.h +++ b/libcxx/include/__format/format_functions.h @@ -239,8 +239,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __handle_replacement_field(const _CharT* __begin, const _CharT* __end, _ParseCtx& __parse_ctx, _Ctx& __ctx) { - __format::__parse_number_result<_CharT> __r = - __format::__parse_arg_id(__begin, __end, __parse_ctx); + __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); bool __parse = *__r.__ptr == _CharT(':'); switch (*__r.__ptr) { @@ -392,15 +391,12 @@ _OutIt __out_it, basic_string_view<_CharT> __fmt, basic_format_args> __args) { if constexpr (same_as<_OutIt, _FormatOutIt>) - return _VSTD::__format::__vformat_to( - basic_format_parse_context<_CharT>{__fmt, __args.__size()}, - _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); + return _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); else { __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; - _VSTD::__format::__vformat_to( - basic_format_parse_context<_CharT>{__fmt, __args.__size()}, - _VSTD::__format_context_create(__buffer.__make_output_iterator(), - __args)); + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); return _VSTD::move(__buffer).__out_it(); } } @@ -473,7 +469,7 @@ basic_string_view<_CharT> __fmt, basic_format_args<_Context> __args) { __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; - _VSTD::__format::__vformat_to(basic_format_parse_context<_CharT>{__fmt, __args.__size()}, + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); return _VSTD::move(__buffer).__result(); } @@ -496,7 +492,7 @@ template _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) { __format::__formatted_size_buffer<_CharT> __buffer; - _VSTD::__format::__vformat_to(basic_format_parse_context<_CharT>{__fmt, __args.__size()}, + _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); return _VSTD::move(__buffer).__result(); } @@ -524,15 +520,13 @@ basic_format_args> __args) { if constexpr (same_as<_OutIt, _FormatOutIt>) return _VSTD::__format::__vformat_to( - basic_format_parse_context<_CharT>{__fmt, __args.__size()}, - _VSTD::__format_context_create(_VSTD::move(__out_it), __args, - _VSTD::move(__loc))); + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(_VSTD::move(__out_it), __args, _VSTD::move(__loc))); else { __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; _VSTD::__format::__vformat_to( - basic_format_parse_context<_CharT>{__fmt, __args.__size()}, - _VSTD::__format_context_create(__buffer.__make_output_iterator(), - __args, _VSTD::move(__loc))); + basic_format_parse_context{__fmt, __args.__size()}, + _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); return _VSTD::move(__buffer).__out_it(); } } @@ -610,7 +604,7 @@ basic_format_args<_Context> __args) { __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; _VSTD::__format::__vformat_to( - basic_format_parse_context<_CharT>{__fmt, __args.__size()}, + basic_format_parse_context{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); return _VSTD::move(__buffer).__result(); } @@ -637,7 +631,7 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) { __format::__formatted_size_buffer<_CharT> __buffer; _VSTD::__format::__vformat_to( - basic_format_parse_context<_CharT>{__fmt, __args.__size()}, + basic_format_parse_context{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); return _VSTD::move(__buffer).__result(); } diff --git a/libcxx/include/__format/format_parse_context.h b/libcxx/include/__format/format_parse_context.h --- a/libcxx/include/__format/format_parse_context.h +++ b/libcxx/include/__format/format_parse_context.h @@ -88,6 +88,7 @@ size_t __next_arg_id_; size_t __num_args_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_parse_context); using format_parse_context = basic_format_parse_context; #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS diff --git a/libcxx/include/__format/format_string.h b/libcxx/include/__format/format_string.h --- a/libcxx/include/__format/format_string.h +++ b/libcxx/include/__format/format_string.h @@ -32,6 +32,9 @@ uint32_t __value; }; +template +__parse_number_result(const _CharT*, uint32_t) -> __parse_number_result<_CharT>; + template _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> __parse_number(const _CharT* __begin, const _CharT* __end); diff --git a/libcxx/include/__format/parser_std_format_spec.h b/libcxx/include/__format/parser_std_format_spec.h --- a/libcxx/include/__format/parser_std_format_spec.h +++ b/libcxx/include/__format/parser_std_format_spec.h @@ -54,8 +54,7 @@ if (__begin == __end) __throw_format_error("End of input while parsing format-spec arg-id"); - __format::__parse_number_result<_CharT> __r = - __format::__parse_arg_id(__begin, __end, __parse_ctx); + __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); if (__r.__ptr == __end || *__r.__ptr != _CharT('}')) __throw_format_error("Invalid arg-id"); @@ -422,7 +421,7 @@ __throw_format_error("A format-spec width field shouldn't have a leading zero"); if (*__begin == _CharT('{')) { - __format::__parse_number_result<_CharT> __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); + __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); __width_as_arg_ = true; __width_ = __r.__value; __begin = __r.__ptr; @@ -432,7 +431,7 @@ if (*__begin < _CharT('0') || *__begin > _CharT('9')) return false; - __format::__parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end); + __format::__parse_number_result __r = __format::__parse_number(__begin, __end); __width_ = __r.__value; _LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, " "due to validations in this function"); @@ -450,7 +449,7 @@ __throw_format_error("End of input while parsing format-spec precision"); if (*__begin == _CharT('{')) { - __format::__parse_number_result<_CharT> __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); + __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; @@ -460,7 +459,7 @@ if (*__begin < _CharT('0') || *__begin > _CharT('9')) __throw_format_error("The format-spec precision field doesn't contain a value or arg-id"); - __format::__parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end); + __format::__parse_number_result __r = __format::__parse_number(__begin, __end); __precision_ = __r.__value; __precision_as_arg_ = false; __begin = __r.__ptr; @@ -702,6 +701,9 @@ const _CharT* __last_; }; +template +__column_width_result(size_t, const _CharT*) -> __column_width_result<_CharT>; + /// 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 /// selected. @@ -879,7 +881,7 @@ } ptrdiff_t __ascii_size = __it - __str.begin(); - __column_width_result<_CharT> __result = + __column_width_result __result = __detail::__estimate_column_width_grapheme_clustering(__it, __str.end(), __maximum, __rounding); __result.__width_ += __ascii_size; diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/advance_to.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/advance_to.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/advance_to.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/advance_to.pass.cpp @@ -24,8 +24,7 @@ std::basic_format_args> args) { { std::basic_string str[3]; - std::basic_format_context context = - test_format_context_create(OutIt{str[0]}, args); + std::basic_format_context context = test_format_context_create(OutIt{str[0]}, args); context.out() = CharT('a'); context.advance_to(OutIt{str[1]}); context.out() = CharT('b'); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/arg.pass.cpp @@ -28,8 +28,7 @@ std::basic_format_args args = store; std::basic_string output; - const std::basic_format_context context = - test_format_context_create(OutIt{output}, args); + const std::basic_format_context context = test_format_context_create(OutIt{output}, args); LIBCPP_ASSERT(args.__size() == 4); ASSERT_NOEXCEPT(context.arg(0)); for (size_t i = 0, e = args.__size(); i != e; ++i) { diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/ctor.pass.cpp @@ -55,7 +55,7 @@ { std::basic_string output; OutIt out_it{output}; - std::basic_format_context context = test_format_context_create(out_it, args); + std::basic_format_context context = test_format_context_create(out_it, args); LIBCPP_ASSERT(args.__size() == 4); assert(test_basic_format_arg(context.arg(0), true)); @@ -79,7 +79,7 @@ { std::basic_string output; OutIt out_it{output}; - std::basic_format_context context = test_format_context_create(out_it, args, en_US); + std::basic_format_context context = test_format_context_create(out_it, args, en_US); LIBCPP_ASSERT(args.__size() == 4); assert(test_basic_format_arg(context.arg(0), true)); @@ -99,7 +99,7 @@ { std::basic_string output; OutIt out_it{output}; - std::basic_format_context context = test_format_context_create(out_it, args, fr_FR); + std::basic_format_context context = test_format_context_create(out_it, args, fr_FR); LIBCPP_ASSERT(args.__size() == 4); assert(test_basic_format_arg(context.arg(0), true)); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/locale.pass.cpp @@ -39,7 +39,7 @@ { std::basic_string output; OutIt out_it{output}; - std::basic_format_context context = test_format_context_create(out_it, args, en_US); + std::basic_format_context context = test_format_context_create(out_it, args, en_US); assert(args.__size() == 4); assert(test_basic_format_arg(context.arg(0), true)); assert(test_basic_format_arg(context.arg(1), CharT('a'))); @@ -58,7 +58,7 @@ { std::basic_string output; OutIt out_it{output}; - std::basic_format_context context = test_format_context_create(out_it, args, fr_FR); + std::basic_format_context context = test_format_context_create(out_it, args, fr_FR); assert(args.__size() == 4); assert(test_basic_format_arg(context.arg(0), true)); assert(test_basic_format_arg(context.arg(1), CharT('a'))); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/out.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/out.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/out.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.context/format.context/out.pass.cpp @@ -25,7 +25,7 @@ { std::basic_string str; OutIt out_it{str}; - std::basic_format_context context = test_format_context_create(out_it, args); + std::basic_format_context context = test_format_context_create(out_it, args); context.out() = CharT('a'); context.out() = CharT('b'); context.out() = CharT('c'); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/advance_to.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/advance_to.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/advance_to.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/advance_to.pass.cpp @@ -35,7 +35,7 @@ } { std::basic_string_view view{fmt}; - std::basic_format_parse_context context(view); + std::basic_format_parse_context context(view); context.advance_to(context.begin() + 1); assert(std::to_address(context.begin()) == fmt + 1); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/begin.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/begin.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/begin.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/begin.pass.cpp @@ -28,7 +28,7 @@ } { std::basic_string_view view{fmt}; - std::basic_format_parse_context context(view); + std::basic_format_parse_context context(view); assert(context.begin() == view.begin()); ASSERT_NOEXCEPT(context.begin()); } diff --git a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/ctor.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/ctor.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/ctor.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/ctor.pass.cpp @@ -39,10 +39,8 @@ static_assert( !std::is_move_assignable_v >); - ASSERT_NOEXCEPT( - std::basic_format_parse_context{std::basic_string_view{}}); - ASSERT_NOEXCEPT( - std::basic_format_parse_context{std::basic_string_view{}, 42}); + ASSERT_NOEXCEPT(std::basic_format_parse_context{std::basic_string_view{}}); + ASSERT_NOEXCEPT(std::basic_format_parse_context{std::basic_string_view{}, 42}); { std::basic_format_parse_context context(fmt); @@ -51,7 +49,7 @@ } { std::basic_string_view view{fmt}; - std::basic_format_parse_context context(view); + std::basic_format_parse_context context(view); assert(context.begin() == view.begin()); assert(context.end() == view.end()); } diff --git a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/end.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/end.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/end.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/end.pass.cpp @@ -28,7 +28,7 @@ } { std::basic_string_view view{fmt}; - std::basic_format_parse_context context(view); + std::basic_format_parse_context context(view); assert(context.end() == view.end()); ASSERT_NOEXCEPT(context.end()); }