diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 95847fb5b629..a515615f08f6 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -584,7 +584,6 @@ function(cxx_add_warning_flags target) -Wno-user-defined-literals -Wno-covered-switch-default -Wno-suggest-override - -Wno-ctad-maybe-unsupported ) if (LIBCXX_TARGETING_CLANG_CL) target_add_compile_flags_if_supported(${target} PRIVATE diff --git a/libcxx/include/__config b/libcxx/include/__config index 460c4754f143..94c54d9e9f4a 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1199,6 +1199,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # endif # endif +// There are a handful of standard library types that are intended to support CTAD but don't need any +// 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> +#else +# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "") +#endif + #endif // __cplusplus #endif // _LIBCPP___CONFIG diff --git a/libcxx/include/__format/format_args.h b/libcxx/include/__format/format_args.h index d90dc50acbd1..8b8fbde92fe6 100644 --- a/libcxx/include/__format/format_args.h +++ b/libcxx/include/__format/format_args.h @@ -71,6 +71,7 @@ private: const basic_format_arg<_Context>* __args_; }; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_args); #endif //_LIBCPP_STD_VER > 17 diff --git a/libcxx/include/__format/format_context.h b/libcxx/include/__format/format_context.h index b9a41db05d51..a2c79d9ec065 100644 --- a/libcxx/include/__format/format_context.h +++ b/libcxx/include/__format/format_context.h @@ -50,8 +50,8 @@ __format_context_create( _OutIt __out_it, basic_format_args> __args, optional<_VSTD::locale>&& __loc = nullopt) { - return _VSTD::basic_format_context(_VSTD::move(__out_it), __args, - _VSTD::move(__loc)); + return _VSTD::basic_format_context<_OutIt, _CharT>(_VSTD::move(__out_it), __args, + _VSTD::move(__loc)); } #else template @@ -59,7 +59,7 @@ _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> __format_context_create( _OutIt __out_it, basic_format_args> __args) { - return _VSTD::basic_format_context(_VSTD::move(__out_it), __args); + return _VSTD::basic_format_context<_OutIt, _CharT>(_VSTD::move(__out_it), __args); } #endif diff --git a/libcxx/include/__format/format_functions.h b/libcxx/include/__format/format_functions.h index a197e3c79cd9..37621bc84798 100644 --- a/libcxx/include/__format/format_functions.h +++ b/libcxx/include/__format/format_functions.h @@ -239,7 +239,7 @@ template _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 __r = + __format::__parse_number_result<_CharT> __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); bool __parse = *__r.__ptr == _CharT(':'); @@ -393,12 +393,12 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt basic_format_args> __args) { if constexpr (same_as<_OutIt, _FormatOutIt>) return _VSTD::__format::__vformat_to( - basic_format_parse_context{__fmt, __args.__size()}, + basic_format_parse_context<_CharT>{__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{__fmt, __args.__size()}, + basic_format_parse_context<_CharT>{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); return _VSTD::move(__buffer).__out_it(); @@ -473,7 +473,7 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, 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{__fmt, __args.__size()}, + _VSTD::__format::__vformat_to(basic_format_parse_context<_CharT>{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); return _VSTD::move(__buffer).__result(); } @@ -496,7 +496,7 @@ format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args 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{__fmt, __args.__size()}, + _VSTD::__format::__vformat_to(basic_format_parse_context<_CharT>{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); return _VSTD::move(__buffer).__result(); } @@ -524,13 +524,13 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt basic_format_args> __args) { if constexpr (same_as<_OutIt, _FormatOutIt>) return _VSTD::__format::__vformat_to( - basic_format_parse_context{__fmt, __args.__size()}, + basic_format_parse_context<_CharT>{__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{__fmt, __args.__size()}, + basic_format_parse_context<_CharT>{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); return _VSTD::move(__buffer).__out_it(); @@ -610,7 +610,7 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, 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{__fmt, __args.__size()}, + basic_format_parse_context<_CharT>{__fmt, __args.__size()}, _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); return _VSTD::move(__buffer).__result(); } @@ -637,7 +637,7 @@ template _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{__fmt, __args.__size()}, + basic_format_parse_context<_CharT>{__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_to_n_result.h b/libcxx/include/__format/format_to_n_result.h index 25caa1c9e98d..f1ed9a0982ab 100644 --- a/libcxx/include/__format/format_to_n_result.h +++ b/libcxx/include/__format/format_to_n_result.h @@ -26,6 +26,7 @@ struct _LIBCPP_TEMPLATE_VIS format_to_n_result { _OutIt out; iter_difference_t<_OutIt> size; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result); #endif //_LIBCPP_STD_VER > 17 diff --git a/libcxx/include/__format/parser_std_format_spec.h b/libcxx/include/__format/parser_std_format_spec.h index 128f1d9c38d5..4b2cb2be03c5 100644 --- a/libcxx/include/__format/parser_std_format_spec.h +++ b/libcxx/include/__format/parser_std_format_spec.h @@ -54,7 +54,7 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { if (__begin == __end) __throw_format_error("End of input while parsing format-spec arg-id"); - __format::__parse_number_result __r = + __format::__parse_number_result<_CharT> __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); if (__r.__ptr == __end || *__r.__ptr != _CharT('}')) @@ -422,7 +422,7 @@ private: __throw_format_error("A format-spec width field shouldn't have a leading zero"); if (*__begin == _CharT('{')) { - __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); + __format::__parse_number_result<_CharT> __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); __width_as_arg_ = true; __width_ = __r.__value; __begin = __r.__ptr; @@ -432,7 +432,7 @@ private: if (*__begin < _CharT('0') || *__begin > _CharT('9')) return false; - __format::__parse_number_result __r = __format::__parse_number(__begin, __end); + __format::__parse_number_result<_CharT> __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 +450,7 @@ private: __throw_format_error("End of input while parsing format-spec precision"); if (*__begin == _CharT('{')) { - __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); + __format::__parse_number_result<_CharT> __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 +460,7 @@ private: 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 __r = __format::__parse_number(__begin, __end); + __format::__parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end); __precision_ = __r.__value; __precision_as_arg_ = false; __begin = __r.__ptr; @@ -879,7 +879,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_ } ptrdiff_t __ascii_size = __it - __str.begin(); - __column_width_result __result = + __column_width_result<_CharT> __result = __detail::__estimate_column_width_grapheme_clustering(__it, __str.end(), __maximum, __rounding); __result.__width_ += __ascii_size; diff --git a/libcxx/include/__format/unicode.h b/libcxx/include/__format/unicode.h index 3316217f4a1e..83ca01b954ec 100644 --- a/libcxx/include/__format/unicode.h +++ b/libcxx/include/__format/unicode.h @@ -328,6 +328,9 @@ private: } }; +template +__extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>; + } // namespace __unicode # endif // _LIBCPP_HAS_NO_UNICODE diff --git a/libcxx/include/__functional/boyer_moore_searcher.h b/libcxx/include/__functional/boyer_moore_searcher.h index 20e554408ff0..a6750893ee57 100644 --- a/libcxx/include/__functional/boyer_moore_searcher.h +++ b/libcxx/include/__functional/boyer_moore_searcher.h @@ -223,6 +223,7 @@ private: } } }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_searcher); template ::value_type>, @@ -303,6 +304,7 @@ private: return std::make_pair(__l, __l); } }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_horspool_searcher); _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__functional/default_searcher.h b/libcxx/include/__functional/default_searcher.h index 0e0f5afc569b..e4151e589f78 100644 --- a/libcxx/include/__functional/default_searcher.h +++ b/libcxx/include/__functional/default_searcher.h @@ -48,6 +48,7 @@ private: _ForwardIterator __last_; _BinaryPredicate __pred_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher); #endif // _LIBCPP_STD_VER > 14 diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h index 1f29094cd8f7..8a781efbdbbb 100644 --- a/libcxx/include/__functional/operations.h +++ b/libcxx/include/__functional/operations.h @@ -36,6 +36,7 @@ struct _LIBCPP_TEMPLATE_VIS plus _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x + __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus); #if _LIBCPP_STD_VER > 11 template <> @@ -64,6 +65,7 @@ struct _LIBCPP_TEMPLATE_VIS minus _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x - __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus); #if _LIBCPP_STD_VER > 11 template <> @@ -92,6 +94,7 @@ struct _LIBCPP_TEMPLATE_VIS multiplies _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x * __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies); #if _LIBCPP_STD_VER > 11 template <> @@ -120,6 +123,7 @@ struct _LIBCPP_TEMPLATE_VIS divides _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x / __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides); #if _LIBCPP_STD_VER > 11 template <> @@ -148,6 +152,7 @@ struct _LIBCPP_TEMPLATE_VIS modulus _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x % __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus); #if _LIBCPP_STD_VER > 11 template <> @@ -176,6 +181,7 @@ struct _LIBCPP_TEMPLATE_VIS negate _Tp operator()(const _Tp& __x) const {return -__x;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate); #if _LIBCPP_STD_VER > 11 template <> @@ -206,6 +212,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_and _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x & __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and); #if _LIBCPP_STD_VER > 11 template <> @@ -230,6 +237,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_not _Tp operator()(const _Tp& __x) const {return ~__x;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not); template <> struct _LIBCPP_TEMPLATE_VIS bit_not @@ -257,6 +265,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_or _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x | __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or); #if _LIBCPP_STD_VER > 11 template <> @@ -285,6 +294,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_xor _Tp operator()(const _Tp& __x, const _Tp& __y) const {return __x ^ __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor); #if _LIBCPP_STD_VER > 11 template <> @@ -315,6 +325,7 @@ struct _LIBCPP_TEMPLATE_VIS equal_to bool operator()(const _Tp& __x, const _Tp& __y) const {return __x == __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to); #if _LIBCPP_STD_VER > 11 template <> @@ -343,6 +354,7 @@ struct _LIBCPP_TEMPLATE_VIS not_equal_to bool operator()(const _Tp& __x, const _Tp& __y) const {return __x != __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to); #if _LIBCPP_STD_VER > 11 template <> @@ -371,6 +383,7 @@ struct _LIBCPP_TEMPLATE_VIS less bool operator()(const _Tp& __x, const _Tp& __y) const {return __x < __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less); #if _LIBCPP_STD_VER > 11 template <> @@ -399,6 +412,7 @@ struct _LIBCPP_TEMPLATE_VIS less_equal bool operator()(const _Tp& __x, const _Tp& __y) const {return __x <= __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal); #if _LIBCPP_STD_VER > 11 template <> @@ -427,6 +441,7 @@ struct _LIBCPP_TEMPLATE_VIS greater_equal bool operator()(const _Tp& __x, const _Tp& __y) const {return __x >= __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal); #if _LIBCPP_STD_VER > 11 template <> @@ -455,6 +470,7 @@ struct _LIBCPP_TEMPLATE_VIS greater bool operator()(const _Tp& __x, const _Tp& __y) const {return __x > __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater); #if _LIBCPP_STD_VER > 11 template <> @@ -485,6 +501,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_and bool operator()(const _Tp& __x, const _Tp& __y) const {return __x && __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and); #if _LIBCPP_STD_VER > 11 template <> @@ -513,6 +530,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_not bool operator()(const _Tp& __x) const {return !__x;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not); #if _LIBCPP_STD_VER > 11 template <> @@ -541,6 +559,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_or bool operator()(const _Tp& __x, const _Tp& __y) const {return __x || __y;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or); #if _LIBCPP_STD_VER > 11 template <> diff --git a/libcxx/include/__iterator/back_insert_iterator.h b/libcxx/include/__iterator/back_insert_iterator.h index da58b860e383..4c00a7e39796 100644 --- a/libcxx/include/__iterator/back_insert_iterator.h +++ b/libcxx/include/__iterator/back_insert_iterator.h @@ -58,6 +58,7 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Container* __get_container() const { return container; } }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(back_insert_iterator); template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 diff --git a/libcxx/include/__iterator/counted_iterator.h b/libcxx/include/__iterator/counted_iterator.h index 28b3e36bdc00..aab2c51f33a8 100644 --- a/libcxx/include/__iterator/counted_iterator.h +++ b/libcxx/include/__iterator/counted_iterator.h @@ -288,6 +288,7 @@ public: return ranges::iter_swap(__x.__current_, __y.__current_); } }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(counted_iterator); template requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>> diff --git a/libcxx/include/__iterator/front_insert_iterator.h b/libcxx/include/__iterator/front_insert_iterator.h index a104b5fc5f1c..e278359d870d 100644 --- a/libcxx/include/__iterator/front_insert_iterator.h +++ b/libcxx/include/__iterator/front_insert_iterator.h @@ -56,6 +56,7 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator++() {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator operator++(int) {return *this;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(front_insert_iterator); template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 diff --git a/libcxx/include/__iterator/move_iterator.h b/libcxx/include/__iterator/move_iterator.h index b02bd81bfc81..b4f2f9ec3d5c 100644 --- a/libcxx/include/__iterator/move_iterator.h +++ b/libcxx/include/__iterator/move_iterator.h @@ -222,6 +222,7 @@ private: _Iter __current_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base index ac0d090b7d19..82d9fa6ecbac 100644 --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -103,6 +103,7 @@ private: lock_guard(lock_guard const&) = delete; lock_guard& operator=(lock_guard const&) = delete; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard); template class _LIBCPP_TEMPLATE_VIS unique_lock @@ -195,6 +196,7 @@ public: _LIBCPP_INLINE_VISIBILITY mutex_type* mutex() const _NOEXCEPT {return __m_;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(unique_lock); template void diff --git a/libcxx/include/__ranges/owning_view.h b/libcxx/include/__ranges/owning_view.h index 22450baec579..71d8146d13a8 100644 --- a/libcxx/include/__ranges/owning_view.h +++ b/libcxx/include/__ranges/owning_view.h @@ -68,6 +68,7 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr auto data() const requires contiguous_range { return ranges::data(__r_); } }; + _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(owning_view); template inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Tp>; diff --git a/libcxx/include/__ranges/range_adaptor.h b/libcxx/include/__ranges/range_adaptor.h index edb32541c651..c287a193a57d 100644 --- a/libcxx/include/__ranges/range_adaptor.h +++ b/libcxx/include/__ranges/range_adaptor.h @@ -41,6 +41,7 @@ template struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> { constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { } }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__range_adaptor_closure_t); template concept _RangeAdaptorClosure = derived_from, __range_adaptor_closure>>; diff --git a/libcxx/include/__utility/transaction.h b/libcxx/include/__utility/transaction.h index 37f829b1fcec..dc65c349d13c 100644 --- a/libcxx/include/__utility/transaction.h +++ b/libcxx/include/__utility/transaction.h @@ -85,6 +85,7 @@ private: _Rollback __rollback_; bool __completed_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__transaction); template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __transaction<_Rollback> __make_transaction(_Rollback __rollback) { diff --git a/libcxx/include/mutex b/libcxx/include/mutex index 139a7f5b93ed..d0b53ba75d83 100644 --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -542,6 +542,7 @@ private: _MutexTuple __t_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock); #endif // _LIBCPP_STD_VER > 14 #endif // !_LIBCPP_HAS_NO_THREADS diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex index e6773651ac61..6919898f66f4 100644 --- a/libcxx/include/shared_mutex +++ b/libcxx/include/shared_mutex @@ -432,6 +432,7 @@ public: _LIBCPP_INLINE_VISIBILITY mutex_type* mutex() const _NOEXCEPT {return __m_;} }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(shared_lock); template void diff --git a/libcxx/include/string_view b/libcxx/include/string_view index c3df8c492602..2941f714fa7c 100644 --- a/libcxx/include/string_view +++ b/libcxx/include/string_view @@ -726,6 +726,7 @@ private: const value_type* __data_; size_type __size_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view); #if _LIBCPP_STD_VER > 17 template diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp index 61c643cb6e66..fc14778f3f7a 100644 --- a/libcxx/src/filesystem/operations.cpp +++ b/libcxx/src/filesystem/operations.cpp @@ -1408,6 +1408,7 @@ struct scope_exit { private: Cleanup cleanup_; }; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scope_exit); uintmax_t remove_all_impl(int parent_directory, const path& p, error_code& ec) { // First, try to open the path as a directory. diff --git a/libcxx/test/libcxx/utilities/function.objects/func.bind.partial/bind_back.pass.cpp b/libcxx/test/libcxx/utilities/function.objects/func.bind.partial/bind_back.pass.cpp index abeff44f0335..de7d78fc0f02 100644 --- a/libcxx/test/libcxx/utilities/function.objects/func.bind.partial/bind_back.pass.cpp +++ b/libcxx/test/libcxx/utilities/function.objects/func.bind.partial/bind_back.pass.cpp @@ -320,7 +320,7 @@ constexpr bool test() { // Test properties of the constructor of the unspecified-type returned by __bind_back. { { - MoveOnlyCallable value(true); + MoveOnlyCallable value(true); auto ret = std::__bind_back(std::move(value), 1); assert(ret()); assert(ret(1, 2, 3)); @@ -337,7 +337,7 @@ constexpr bool test() { static_assert(!std::is_copy_assignable::value); } { - CopyCallable value(true); + CopyCallable value(true); auto ret = std::__bind_back(value, 1); assert(ret()); assert(ret(1, 2, 3)); diff --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/types.h b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/types.h index 433731e5dd68..3ab4924e2411 100644 --- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/types.h +++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/types.h @@ -54,4 +54,7 @@ private: decltype(base(std::declval())) base_; }; +template +assignable_sentinel(const It&) -> assignable_sentinel; + #endif // TEST_STD_ITERATORS_ITERATOR_PRIMITIVES_RANGE_ITER_OPS_TYPES_H diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_move.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_move.pass.cpp index 5443a5bb5890..31ec0100e2ee 100644 --- a/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_move.pass.cpp +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_move.pass.cpp @@ -50,6 +50,9 @@ private: I base_ = I{}; }; +template +iterator_wrapper(I) -> iterator_wrapper; + template constexpr void unqualified_lookup_move(It first_, It last_, Out result_first_, Out result_last_) { auto first = ::check_unqualified_lookup::unqualified_lookup_wrapper{std::move(first_)}; diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.cust/unqualified_lookup_wrapper.h b/libcxx/test/std/iterators/iterator.requirements/iterator.cust/unqualified_lookup_wrapper.h index 7c3719aa519e..30d913ccc440 100644 --- a/libcxx/test/std/iterators/iterator.requirements/iterator.cust/unqualified_lookup_wrapper.h +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.cust/unqualified_lookup_wrapper.h @@ -43,6 +43,9 @@ private: I base_ = I{}; }; +template +unqualified_lookup_wrapper(It) -> unqualified_lookup_wrapper; + enum unscoped_enum { a, b, c }; constexpr unscoped_enum iter_move(unscoped_enum& e) noexcept(false) { return e; } diff --git a/libcxx/test/std/iterators/predef.iterators/counted.iterator/implicit_ctad.pass.cpp b/libcxx/test/std/iterators/predef.iterators/counted.iterator/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..2786dfbb7a60 --- /dev/null +++ b/libcxx/test/std/iterators/predef.iterators/counted.iterator/implicit_ctad.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// counted_iterator + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + int array[] = {1, 2, 3}; + int* p = array; + std::counted_iterator iter(p, 3); + ASSERT_SAME_TYPE(decltype(iter), std::counted_iterator); + + return 0; +} diff --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/implicit_ctad.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..10729e0029d0 --- /dev/null +++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/implicit_ctad.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// back_insert_iterator + +// Make sure that the implicitly-generated CTAD works. + +#include +#include +#include + +#include "test_macros.h" + +int main(int, char**) { + { + std::string s; + std::back_insert_iterator it(s); + ASSERT_SAME_TYPE(decltype(it), std::back_insert_iterator); + } + { + std::vector v; + std::back_insert_iterator it(v); + std::back_insert_iterator copy(it); + ASSERT_SAME_TYPE(decltype(it), std::back_insert_iterator>); + ASSERT_SAME_TYPE(decltype(copy), std::back_insert_iterator>); + } + + return 0; +} diff --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/implicit_ctad.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..f91d472e9ea2 --- /dev/null +++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/implicit_ctad.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// front_insert_iterator + +// Make sure that the implicitly-generated CTAD works. + +#include +#include +#include + +#include "test_macros.h" + +int main(int, char**) { + { + std::string s; + std::front_insert_iterator it(s); + ASSERT_SAME_TYPE(decltype(it), std::front_insert_iterator); + } + { + std::deque v; + std::front_insert_iterator it(v); + std::front_insert_iterator copy(it); + ASSERT_SAME_TYPE(decltype(it), std::front_insert_iterator>); + ASSERT_SAME_TYPE(decltype(copy), std::front_insert_iterator>); + } + + return 0; +} diff --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/implicit_ctad.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..e5744465daa9 --- /dev/null +++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/implicit_ctad.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// move_iterator + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + int* it = nullptr; + std::move_iterator move_it(it); + ASSERT_SAME_TYPE(decltype(move_it), std::move_iterator); + + return 0; +} diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/iter_swap.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/iter_swap.pass.cpp index aaad0eb51e2f..d01ee2a1b85a 100644 --- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/iter_swap.pass.cpp +++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.nonmember/iter_swap.pass.cpp @@ -31,8 +31,8 @@ constexpr bool test() { constexpr int N = 3; int a[N] = {0, 1, 2}; - std::reverse_iterator rb(a + N); - std::reverse_iterator re(a + 1); + std::reverse_iterator rb(a + N); + std::reverse_iterator re(a + 1); assert(a[0] == 0); assert(a[2] == 2); diff --git a/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/implicit_ctad.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..11b3dc76da55 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/implicit_ctad.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// owning_view + +// Make sure that the implicitly-generated CTAD works. + +#include +#include + +#include "test_macros.h" + +struct Range { + int* begin(); + int* end(); +}; + +int main(int, char**) { + Range r; + std::ranges::owning_view view{std::move(r)}; + ASSERT_SAME_TYPE(decltype(view), std::ranges::owning_view); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/arrow.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/arrow.pass.cpp index 44f67d1e9902..ddcf66bfe775 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/arrow.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/arrow.pass.cpp @@ -103,8 +103,8 @@ constexpr bool test() { { // Copyable input iterator with arrow. - ValueView children[4] = {ValueView(buffer[0]), ValueView(buffer[1]), ValueView(buffer[2]), - ValueView(buffer[3])}; + using BoxView = ValueView; + ValueView children[4] = {BoxView(buffer[0]), BoxView(buffer[1]), BoxView(buffer[2]), BoxView(buffer[3])}; std::ranges::join_view jv(ValueView>{children}); assert(jv.begin()->x == 1111); static_assert(HasArrow); diff --git a/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/increment.pass.cpp index 057f75b9e525..f46edd3562ba 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/increment.pass.cpp @@ -37,8 +37,9 @@ constexpr bool test() { } { - ValueView children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])}; - std::ranges::join_view jv(ValueView>{children}); + using IntView = ValueView; + IntView children[4] = {IntView(buffer1[0]), IntView(buffer1[1]), IntView(buffer2[0]), IntView(buffer2[1])}; + std::ranges::join_view jv(ValueView{children}); auto iter = jv.begin(); for (int i = 1; i < 17; ++i) { assert(*iter == i); @@ -152,8 +153,9 @@ constexpr bool test() { } { - ValueView children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])}; - std::ranges::join_view jv(ValueView>{children}); + using IntView = ValueView; + IntView children[4] = {IntView(buffer1[0]), IntView(buffer1[1]), IntView(buffer2[0]), IntView(buffer2[1])}; + std::ranges::join_view jv(ValueView{children}); auto iter = jv.begin(); for (int i = 2; i < 17; ++i) { assert(*++iter == i); diff --git a/libcxx/test/std/ranges/range.adaptors/range.join.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.join.view/types.h index 1b4007bce012..d33653858074 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.join.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.join.view/types.h @@ -75,6 +75,9 @@ struct ParentView : std::ranges::view_base { constexpr const_sentinel end() const { return const_sentinel(const_iterator(ptr_ + size_)); } }; +template +ParentView(T*) -> ParentView; + struct CopyableChild : std::ranges::view_base { int* ptr_; unsigned size_; diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/types.h b/libcxx/test/std/ranges/range.factories/range.iota.view/types.h index a6eb1b4d537a..b9ef3e21de51 100644 --- a/libcxx/test/std/ranges/range.factories/range.iota.view/types.h +++ b/libcxx/test/std/ranges/range.factories/range.iota.view/types.h @@ -88,6 +88,8 @@ struct IntComparableWith { constexpr IntComparableWith operator++(int) { auto tmp = *this; ++value_; return tmp; } constexpr IntComparableWith operator--() { --value_; return *this; } }; +template +IntComparableWith(T) -> IntComparableWith; template struct IntSentinelWith { @@ -123,6 +125,8 @@ struct IntSentinelWith { constexpr IntSentinelWith operator++(int) { auto tmp = *this; ++value_; return tmp; } constexpr IntSentinelWith operator--() { --value_; return *this; } }; +template +IntSentinelWith(T) -> IntSentinelWith; struct NotIncrementable { using difference_type = int; diff --git a/libcxx/test/std/strings/string.view/string.view.deduct/implicit.pass.cpp b/libcxx/test/std/strings/string.view/string.view.deduct/implicit.pass.cpp new file mode 100644 index 000000000000..c76c4a01c696 --- /dev/null +++ b/libcxx/test/std/strings/string.view/string.view.deduct/implicit.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// basic_string_view + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + { + char const* str = "hello world"; + std::basic_string_view sv(str); + ASSERT_SAME_TYPE(decltype(sv), std::basic_string_view); + } +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + { + wchar_t const* str = L"hello world"; + std::basic_string_view sv(str); + ASSERT_SAME_TYPE(decltype(sv), std::basic_string_view); + } +#endif + + return 0; +} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..b75441733482 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: no-threads +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// lock_guard + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + std::mutex mutex; + { + std::lock_guard lock(mutex); + ASSERT_SAME_TYPE(decltype(lock), std::lock_guard); + } + + return 0; +} + diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/implicit_ctad.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..7305b48c53a9 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/implicit_ctad.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: no-threads +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// scoped_lock + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + std::mutex m1; + std::recursive_mutex m2; + std::recursive_timed_mutex m3; + { + std::scoped_lock lock(m1); + ASSERT_SAME_TYPE(decltype(lock), std::scoped_lock); + } + { + std::scoped_lock lock(m1, m2); + ASSERT_SAME_TYPE(decltype(lock), std::scoped_lock); + } + { + std::scoped_lock lock(m1, m2, m3); + ASSERT_SAME_TYPE(decltype(lock), std::scoped_lock); + } + + return 0; +} + diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/implicit_ctad.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..3fa4373c7017 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/implicit_ctad.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: no-threads +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// dylib support for shared_mutex was added in macosx10.12 +// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11}} + +// + +// shared_lock + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + std::shared_mutex mutex; + { + std::shared_lock lock(mutex); + ASSERT_SAME_TYPE(decltype(lock), std::shared_lock); + } + + return 0; +} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..ffe651c6b744 --- /dev/null +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/implicit_ctad.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: no-threads +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// unique_lock + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + std::mutex mutex; + { + std::unique_lock lock(mutex); + ASSERT_SAME_TYPE(decltype(lock), std::unique_lock); + } + + return 0; +} diff --git a/libcxx/test/std/thread/thread.semaphore/ctor.compile.pass.cpp b/libcxx/test/std/thread/thread.semaphore/ctor.compile.pass.cpp index 9ffee4df0497..28ccc0124d48 100644 --- a/libcxx/test/std/thread/thread.semaphore/ctor.compile.pass.cpp +++ b/libcxx/test/std/thread/thread.semaphore/ctor.compile.pass.cpp @@ -27,5 +27,5 @@ static_assert(!std::is_convertible>::value, ""); #if TEST_STD_VER > 17 // Test constexpr-constructibility. (But not destructibility.) constinit std::binary_semaphore bs(1); -constinit std::counting_semaphore cs(1); +constinit std::counting_semaphore<> cs(1); #endif 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 index da6b5d16417c..fe2ce9d5a62a 100644 --- 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,7 +24,7 @@ void test( std::basic_format_args> args) { { std::basic_string str[3]; - std::basic_format_context context = + std::basic_format_context context = test_format_context_create(OutIt{str[0]}, args); context.out() = CharT('a'); context.advance_to(OutIt{str[1]}); 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 index 17d8908b2a23..abd9315612c0 100644 --- 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,7 +28,7 @@ void test() { std::basic_format_args args = store; std::basic_string output; - const std::basic_format_context context = + const std::basic_format_context context = test_format_context_create(OutIt{output}, args); LIBCPP_ASSERT(args.__size() == 4); ASSERT_NOEXCEPT(context.arg(0)); 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 index 0b86c342f621..f2d24503db81 100644 --- 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,8 +55,7 @@ void test() { { 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)); @@ -80,8 +79,7 @@ void test() { { 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)); @@ -101,8 +99,7 @@ void test() { { 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 index a8752bfc3043..6a9178943792 100644 --- 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,8 +39,7 @@ void test() { { 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'))); @@ -59,8 +58,7 @@ void test() { { 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 index 928f668c9f64..b7080e1aa730 100644 --- 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,8 +25,7 @@ void test( { 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.formatter.spec/formatter.bool.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.bool.pass.cpp index bb0402aae6e2..da886d37fceb 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.bool.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.bool.pass.cpp @@ -44,7 +44,7 @@ void test(StringT expected, StringViewT fmt, bool arg) { auto out = std::back_inserter(result); using FormatCtxT = std::basic_format_context; - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(arg)); formatter.format(arg, format_ctx); assert(result == expected); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.c_string.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.c_string.pass.cpp index 5b5d2a616961..dc9abd8d6348 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.c_string.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.c_string.pass.cpp @@ -43,7 +43,7 @@ void test(StringT expected, StringViewT fmt, const CharT* a) { using FormatCtxT = std::basic_format_context; auto* arg = const_cast(a); - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(arg)); formatter.format(arg, format_ctx); assert(result == expected); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char.pass.cpp index cc84948c73dc..22c78549ddbf 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char.pass.cpp @@ -43,7 +43,7 @@ void test(StringT expected, StringViewT fmt, ArgumentT arg) { auto out = std::back_inserter(result); using FormatCtxT = std::basic_format_context; - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(arg)); formatter.format(arg, format_ctx); assert(result == expected); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp index 93fb9360b5d9..9f9ad98edc75 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.char_array.pass.cpp @@ -58,7 +58,7 @@ struct Tester { // Note not too found of this hack Str* data = reinterpret_cast(const_cast(buffer.c_str())); - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(*data)); formatter.format(*data, format_ctx); assert(result == expected); @@ -79,6 +79,9 @@ struct Tester { } }; +template +Tester(const char (&)[N]) -> Tester; + template void test_helper_wrapper(std::basic_string expected, std::basic_string fmt) { t.test_termination_condition(expected, fmt); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.const_char_array.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.const_char_array.pass.cpp index 65749b7f636f..39930c347a45 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.const_char_array.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.const_char_array.pass.cpp @@ -60,7 +60,7 @@ struct Tester { // Note not too found of this hack Str* data = reinterpret_cast(buffer.c_str()); - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(*data)); formatter.format(*data, format_ctx); assert(result == expected); @@ -82,6 +82,9 @@ struct Tester { } }; +template +Tester(const char (&)[N]) -> Tester; + template void test_helper_wrapper(std::basic_string expected, std::basic_string fmt) { diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.floating_point.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.floating_point.pass.cpp index 9c4d56d102ef..123d0ac36fa3 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.floating_point.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.floating_point.pass.cpp @@ -53,7 +53,7 @@ void test(std::basic_string_view fmt, ArithmeticT arg, std::basic_string< auto out = std::back_inserter(result); using FormatCtxT = std::basic_format_context; - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(arg)); formatter.format(arg, format_ctx); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.handle.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.handle.pass.cpp index 986352ee16a2..f8ffbd2a6ff2 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.handle.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.handle.pass.cpp @@ -47,7 +47,7 @@ void test(std::string expected, std::string_view fmt, color arg) { auto out = std::back_inserter(result); using FormatCtxT = std::basic_format_context; - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(arg)); formatter.format(arg, format_ctx); assert(result == expected); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.pointer.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.pointer.pass.cpp index d91b75bb5435..316667ae6007 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.pointer.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.pointer.pass.cpp @@ -49,7 +49,7 @@ void test(StringT expected, StringViewT fmt, PointerT arg) { auto out = std::back_inserter(result); using FormatCtxT = std::basic_format_context; - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(arg)); formatter.format(arg, format_ctx); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.signed_integral.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.signed_integral.pass.cpp index 949af08e26c8..07f5be400739 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.signed_integral.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.signed_integral.pass.cpp @@ -51,7 +51,7 @@ void test(StringT expected, StringViewT fmt, ArithmeticT arg) { auto out = std::back_inserter(result); using FormatCtxT = std::basic_format_context; - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(arg)); formatter.format(arg, format_ctx); assert(result == expected); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.string.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.string.pass.cpp index 16cbac4f4b0a..aa4c9a6b4d24 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.string.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.string.pass.cpp @@ -51,7 +51,7 @@ void test(StringT expected, StringViewT fmt, StringT a) { using FormatCtxT = std::basic_format_context; ArgumentT arg = a; - std::basic_format_context format_ctx = test_format_context_create( + FormatCtxT format_ctx = test_format_context_create( out, std::make_format_args(std::forward(arg))); formatter.format(arg, format_ctx); assert(result == expected); diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.unsigned_integral.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.unsigned_integral.pass.cpp index 320b7e7d9022..11025afadb6b 100644 --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.unsigned_integral.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.unsigned_integral.pass.cpp @@ -51,7 +51,7 @@ void test(StringT expected, StringViewT fmt, ArithmeticT arg) { auto out = std::back_inserter(result); using FormatCtxT = std::basic_format_context; - std::basic_format_context format_ctx = + FormatCtxT format_ctx = test_format_context_create(out, std::make_format_args(arg)); formatter.format(arg, format_ctx); assert(result == expected); 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 index 6b4afcb6561d..66dacd44bb11 100644 --- 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 @@ constexpr void test(const CharT* fmt) { } { 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 index 63122dc50b76..85d9e20b9bc2 100644 --- 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 @@ constexpr void test(const CharT* fmt) { } { 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 index 2a06751ec547..90a102973f04 100644 --- 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 @@ -40,9 +40,9 @@ constexpr void test(const CharT* fmt) { !std::is_move_assignable_v >); ASSERT_NOEXCEPT( - std::basic_format_parse_context{std::basic_string_view{}}); + 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{std::basic_string_view{}, 42}); { std::basic_format_parse_context context(fmt); @@ -51,7 +51,7 @@ constexpr void test(const CharT* fmt) { } { 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 index e135418dc5b8..917d856741b2 100644 --- 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 @@ constexpr void test(const CharT* fmt) { } { 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()); } diff --git a/libcxx/test/std/utilities/function.objects/func.bind_front/bind_front.pass.cpp b/libcxx/test/std/utilities/function.objects/func.bind_front/bind_front.pass.cpp index d449265a2d04..6eb4e4a46e82 100644 --- a/libcxx/test/std/utilities/function.objects/func.bind_front/bind_front.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.bind_front/bind_front.pass.cpp @@ -317,7 +317,7 @@ constexpr bool test() { // Test properties of the constructor of the unspecified-type returned by bind_front. { { - MoveOnlyCallable value(true); + MoveOnlyCallable value(true); auto ret = std::bind_front(std::move(value), 1); assert(ret()); assert(ret(1, 2, 3)); @@ -334,7 +334,7 @@ constexpr bool test() { static_assert(!std::is_copy_assignable::value); } { - CopyCallable value(true); + CopyCallable value(true); auto ret = std::bind_front(value, 1); assert(ret()); assert(ret(1, 2, 3)); diff --git a/libcxx/test/std/utilities/function.objects/func.search/func.search.bm/implicit_ctad.pass.cpp b/libcxx/test/std/utilities/function.objects/func.search/func.search.bm/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..863b4a5c2569 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.search/func.search.bm/implicit_ctad.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// boyer_moore_searcher + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + { + char const* str = "hello"; + std::boyer_moore_searcher searcher(str, str + 3); + ASSERT_SAME_TYPE(decltype(searcher), std::boyer_moore_searcher, std::equal_to<>>); + } + { + struct myhash : std::hash { }; + char const* str = "hello"; + std::boyer_moore_searcher searcher(str, str + 3, myhash{}, std::not_equal_to<>()); + ASSERT_SAME_TYPE(decltype(searcher), std::boyer_moore_searcher>); + } + { + struct myhash : std::hash { }; + char const* str = "hello"; + std::boyer_moore_searcher searcher(str, str + 3, myhash{}); + ASSERT_SAME_TYPE(decltype(searcher), std::boyer_moore_searcher>); + } + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/func.search/func.search.bmh/implicit_ctad.pass.cpp b/libcxx/test/std/utilities/function.objects/func.search/func.search.bmh/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..778f6d3bd2cb --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.search/func.search.bmh/implicit_ctad.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// boyer_moore_horspool_searcher + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + { + char const* str = "hello"; + std::boyer_moore_horspool_searcher searcher(str, str + 3); + ASSERT_SAME_TYPE(decltype(searcher), std::boyer_moore_horspool_searcher, std::equal_to<>>); + } + { + struct myhash : std::hash { }; + char const* str = "hello"; + std::boyer_moore_horspool_searcher searcher(str, str + 3, myhash{}, std::not_equal_to<>()); + ASSERT_SAME_TYPE(decltype(searcher), std::boyer_moore_horspool_searcher>); + } + { + struct myhash : std::hash { }; + char const* str = "hello"; + std::boyer_moore_horspool_searcher searcher(str, str + 3, myhash{}); + ASSERT_SAME_TYPE(decltype(searcher), std::boyer_moore_horspool_searcher>); + } + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/func.search/func.search.default/implicit_ctad.pass.cpp b/libcxx/test/std/utilities/function.objects/func.search/func.search.default/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..3c9029566d92 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.search/func.search.default/implicit_ctad.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// default searcher + +// Make sure that the implicitly-generated CTAD works. + +#include + +#include "test_macros.h" + +int main(int, char**) { + { + char const* str = "hello"; + std::default_searcher searcher(str, str + 3); + ASSERT_SAME_TYPE(decltype(searcher), std::default_searcher>); + } + { + char const* str = "hello"; + std::default_searcher searcher(str, str + 3, std::not_equal_to<>()); + ASSERT_SAME_TYPE(decltype(searcher), std::default_searcher>); + } + + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/operations.implicit_ctad.pass.cpp b/libcxx/test/std/utilities/function.objects/operations.implicit_ctad.pass.cpp new file mode 100644 index 000000000000..03c46d232c38 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/operations.implicit_ctad.pass.cpp @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +// + +// Make sure that we can use CTAD with operations in + +#include + +#include "test_macros.h" + +int main(int, char**) { + { + std::plus f; + ASSERT_SAME_TYPE(decltype(f), std::plus<>); + } + { + std::minus f; + ASSERT_SAME_TYPE(decltype(f), std::minus<>); + } + { + std::multiplies f; + ASSERT_SAME_TYPE(decltype(f), std::multiplies<>); + } + { + std::divides f; + ASSERT_SAME_TYPE(decltype(f), std::divides<>); + } + { + std::modulus f; + ASSERT_SAME_TYPE(decltype(f), std::modulus<>); + } + { + std::negate f; + ASSERT_SAME_TYPE(decltype(f), std::negate<>); + } + { + std::bit_and f; + ASSERT_SAME_TYPE(decltype(f), std::bit_and<>); + } + { + std::bit_not f; + ASSERT_SAME_TYPE(decltype(f), std::bit_not<>); + } + { + std::bit_or f; + ASSERT_SAME_TYPE(decltype(f), std::bit_or<>); + } + { + std::bit_xor f; + ASSERT_SAME_TYPE(decltype(f), std::bit_xor<>); + } + { + std::equal_to f; + ASSERT_SAME_TYPE(decltype(f), std::equal_to<>); + } + { + std::not_equal_to f; + ASSERT_SAME_TYPE(decltype(f), std::not_equal_to<>); + } + { + std::less f; + ASSERT_SAME_TYPE(decltype(f), std::less<>); + } + { + std::less_equal f; + ASSERT_SAME_TYPE(decltype(f), std::less_equal<>); + } + { + std::greater_equal f; + ASSERT_SAME_TYPE(decltype(f), std::greater_equal<>); + } + { + std::greater f; + ASSERT_SAME_TYPE(decltype(f), std::greater<>); + } + { + std::logical_and f; + ASSERT_SAME_TYPE(decltype(f), std::logical_and<>); + } + { + std::logical_not f; + ASSERT_SAME_TYPE(decltype(f), std::logical_not<>); + } + { + std::logical_or f; + ASSERT_SAME_TYPE(decltype(f), std::logical_or<>); + } + + return 0; +} diff --git a/libcxx/test/std/utilities/variant/variant.variant/implicit_ctad.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/implicit_ctad.pass.cpp new file mode 100644 index 000000000000..514c1f87faad --- /dev/null +++ b/libcxx/test/std/utilities/variant/variant.variant/implicit_ctad.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// + +// template class variant; + +// Make sure that the implicitly-generated CTAD works. + +// We make sure that it is not ill-formed, however we still produce a warning for +// this one because explicit construction from a variant using CTAD is ambiguous +// (in the sense that the programer intent is not clear). +// ADDITIONAL_COMPILE_FLAGS: -Wno-ctad-maybe-unsupported + +#include + +#include "test_macros.h" + +int main(int, char**) { + // This is the motivating example from P0739R0 + { + std::variant v1(3); + std::variant v2 = v1; + ASSERT_SAME_TYPE(decltype(v2), std::variant); + } + + { + std::variant v1(3); + std::variant v2 = std::variant(v1); // Technically valid, but intent is ambiguous! + ASSERT_SAME_TYPE(decltype(v2), std::variant); + } + + return 0; +} diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp index 39a7b9bd1833..b328ba4cbe8a 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp @@ -253,11 +253,5 @@ int main(int, char**) { test_copy_ctor_valueless_by_exception(); test_copy_ctor_sfinae(); test_constexpr_copy_ctor(); - { // This is the motivating example from P0739R0 - std::variant v1(3); - std::variant v2 = v1; - (void)v2; - } - return 0; } diff --git a/libcxx/test/support/callable_types.h b/libcxx/test/support/callable_types.h index 9bc27249c7a8..1e0e5d9f1391 100644 --- a/libcxx/test/support/callable_types.h +++ b/libcxx/test/support/callable_types.h @@ -18,7 +18,7 @@ constexpr bool returns_true() { return true; } -template +template struct MoveOnlyCallable { MoveOnlyCallable(MoveOnlyCallable const&) = delete; constexpr MoveOnlyCallable(MoveOnlyCallable&& other) @@ -32,7 +32,7 @@ struct MoveOnlyCallable { Ret value; }; -template +template struct CopyCallable { constexpr CopyCallable(CopyCallable const& other) : value(other.value) {} @@ -48,7 +48,7 @@ struct CopyCallable { }; -template +template struct ConstCallable { constexpr ConstCallable(ConstCallable const& other) : value(other.value) {} @@ -65,7 +65,7 @@ struct ConstCallable { -template +template struct NoExceptCallable { constexpr NoExceptCallable(NoExceptCallable const& other) : value(other.value) {} diff --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h index d3c2e4d7b611..d5381b5de1df 100644 --- a/libcxx/test/support/test_iterators.h +++ b/libcxx/test/support/test_iterators.h @@ -53,6 +53,11 @@ public: template void operator,(T const &) = delete; }; +#if TEST_STD_VER > 14 +template +cpp17_output_iterator(It) -> cpp17_output_iterator; +#endif + #if TEST_STD_VER > 17 static_assert(std::output_iterator, int>); #endif @@ -94,6 +99,11 @@ public: template void operator,(T const &) = delete; }; +#if TEST_STD_VER > 14 +template +cpp17_input_iterator(It) -> cpp17_input_iterator; +#endif + #if TEST_STD_VER > 17 static_assert(std::input_iterator>); #endif @@ -133,6 +143,10 @@ public: template void operator,(T const &) = delete; }; +#if TEST_STD_VER > 14 +template +forward_iterator(It) -> forward_iterator; +#endif template class bidirectional_iterator @@ -171,6 +185,10 @@ public: template void operator,(T const &) = delete; }; +#if TEST_STD_VER > 14 +template +bidirectional_iterator(It) -> bidirectional_iterator; +#endif template class random_access_iterator @@ -221,6 +239,10 @@ public: template void operator,(T const &) = delete; }; +#if TEST_STD_VER > 14 +template +random_access_iterator(It) -> random_access_iterator; +#endif #if TEST_STD_VER > 17 @@ -310,6 +332,8 @@ public: template void operator,(T const&) = delete; }; +template +cpp20_random_access_iterator(It) -> cpp20_random_access_iterator; static_assert(std::random_access_iterator>); @@ -368,6 +392,8 @@ public: template void operator,(T const &) = delete; }; +template +contiguous_iterator(It) -> contiguous_iterator; template class three_way_contiguous_iterator @@ -418,6 +444,8 @@ public: template void operator,(T const &) = delete; }; +template +three_way_contiguous_iterator(It) -> three_way_contiguous_iterator; #endif // TEST_STD_VER > 17 template // ADL base() for everything else (including pointers) @@ -627,6 +655,9 @@ public: template void operator,(T const &) = delete; }; +template +cpp20_input_iterator(It) -> cpp20_input_iterator; + static_assert(std::input_iterator>); template @@ -660,6 +691,8 @@ public: template void operator,(T const&) = delete; }; +template +cpp20_output_iterator(It) -> cpp20_output_iterator; static_assert(std::output_iterator, int>); @@ -815,6 +848,8 @@ private: difference_type stride_count_ = 0; difference_type stride_displacement_ = 0; }; +template +stride_counting_iterator(It) -> stride_counting_iterator; #endif // TEST_STD_VER > 17 @@ -829,6 +864,8 @@ public: private: decltype(base(std::declval())) base_; }; +template +sentinel_wrapper(It) -> sentinel_wrapper; template class sized_sentinel { @@ -842,6 +879,8 @@ public: private: decltype(base(std::declval())) base_; }; +template +sized_sentinel(It) -> sized_sentinel; namespace adl { @@ -1211,6 +1250,8 @@ struct ProxyIterator : ProxyIteratorBase { return x.base_ - y.base_; } }; +template +ProxyIterator(Base) -> ProxyIterator; static_assert(std::indirectly_readable>); static_assert(std::indirectly_writable, Proxy>); @@ -1229,6 +1270,8 @@ struct ProxySentinel { return p.base_ == sent.base_; } }; +template +ProxySentinel(BaseSent) -> ProxySentinel; template requires std::ranges::view diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index e33aac575ba5..74a4ec24201d 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -13,6 +13,7 @@ import re _warningFlags = [ '-Werror', '-Wall', + '-Wctad-maybe-unsupported', '-Wextra', '-Wshadow', '-Wundef',