[libc++] Suppress -Wctad-maybe-unsupported on types w/o deduction guides

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 patch adds a dummy deduction guide to those types to suppress
-Wctad-maybe-unsupported (which gets emitted in user code).

This is a re-application of the original patch by Eric Fiselier in
fcd549a7d8 which had been reverted due to reasons lost at this point.
I also added the macro to a few more types. Reviving this patch was
prompted by the discussion on https://llvm.org/D133425.

Differential Revision: https://reviews.llvm.org/D133535
This commit is contained in:
Louis Dionne 2022-09-08 17:36:11 -04:00
parent c0a76c2c71
commit c2df707666
73 changed files with 765 additions and 73 deletions

View File

@ -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

View File

@ -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 <class _Tag = void> \
_ClassName(typename _Tag::__allow_ctad) -> _ClassName<_Tag>
#else
# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
#endif
#endif // __cplusplus
#endif // _LIBCPP___CONFIG

View File

@ -71,6 +71,7 @@ private:
const basic_format_arg<_Context>* __args_;
};
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_args);
#endif //_LIBCPP_STD_VER > 17

View File

@ -50,8 +50,8 @@ __format_context_create(
_OutIt __out_it,
basic_format_args<basic_format_context<_OutIt, _CharT>> __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 <class _OutIt, class _CharT>
@ -59,7 +59,7 @@ _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT>
__format_context_create(
_OutIt __out_it,
basic_format_args<basic_format_context<_OutIt, _CharT>> __args) {
return _VSTD::basic_format_context(_VSTD::move(__out_it), __args);
return _VSTD::basic_format_context<_OutIt, _CharT>(_VSTD::move(__out_it), __args);
}
#endif

View File

@ -239,7 +239,7 @@ template <class _CharT, class _ParseCtx, class _Ctx>
_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<basic_format_context<_FormatOutIt, _CharT>> __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 <class _CharT>
_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<basic_format_context<_FormatOutIt, _CharT>> __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 <class _CharT>
_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();
}

View File

@ -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

View File

@ -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;

View File

@ -328,6 +328,9 @@ private:
}
};
template <class _CharT>
__extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>;
} // namespace __unicode
# endif // _LIBCPP_HAS_NO_UNICODE

View File

@ -223,6 +223,7 @@ private:
}
}
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_searcher);
template <class _RandomAccessIterator1,
class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::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

View File

@ -48,6 +48,7 @@ private:
_ForwardIterator __last_;
_BinaryPredicate __pred_;
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher);
#endif // _LIBCPP_STD_VER > 14

View File

@ -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<void>
@ -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 <>

View File

@ -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 <class _Container>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20

View File

@ -288,6 +288,7 @@ public:
return ranges::iter_swap(__x.__current_, __y.__current_);
}
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(counted_iterator);
template<input_iterator _Iter>
requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>>

View File

@ -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 <class _Container>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20

View File

@ -222,6 +222,7 @@ private:
_Iter __current_;
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator);
template <class _Iter1, class _Iter2>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17

View File

@ -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 _Mutex>
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 <class _Mutex>
void

View File

@ -68,6 +68,7 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr auto data() const requires contiguous_range<const _Rp>
{ return ranges::data(__r_); }
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(owning_view);
template<class _Tp>
inline constexpr bool enable_borrowed_range<owning_view<_Tp>> = enable_borrowed_range<_Tp>;

View File

@ -41,6 +41,7 @@ template <class _Fn>
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 <class _Tp>
concept _RangeAdaptorClosure = derived_from<remove_cvref_t<_Tp>, __range_adaptor_closure<remove_cvref_t<_Tp>>>;

View File

@ -85,6 +85,7 @@ private:
_Rollback __rollback_;
bool __completed_;
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__transaction);
template <class _Rollback>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __transaction<_Rollback> __make_transaction(_Rollback __rollback) {

View File

@ -542,6 +542,7 @@ private:
_MutexTuple __t_;
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock);
#endif // _LIBCPP_STD_VER > 14
#endif // !_LIBCPP_HAS_NO_THREADS

View File

@ -432,6 +432,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
mutex_type* mutex() const _NOEXCEPT {return __m_;}
};
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(shared_lock);
template <class _Mutex>
void

View File

@ -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 <class _CharT, class _Traits>

View File

@ -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.

View File

@ -320,7 +320,7 @@ constexpr bool test() {
// Test properties of the constructor of the unspecified-type returned by __bind_back.
{
{
MoveOnlyCallable value(true);
MoveOnlyCallable<bool> 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<RetT>::value);
}
{
CopyCallable value(true);
CopyCallable<bool> value(true);
auto ret = std::__bind_back(value, 1);
assert(ret());
assert(ret(1, 2, 3));

View File

@ -54,4 +54,7 @@ private:
decltype(base(std::declval<It>())) base_;
};
template <class It>
assignable_sentinel(const It&) -> assignable_sentinel<It>;
#endif // TEST_STD_ITERATORS_ITERATOR_PRIMITIVES_RANGE_ITER_OPS_TYPES_H

View File

@ -50,6 +50,9 @@ private:
I base_ = I{};
};
template <class I>
iterator_wrapper(I) -> iterator_wrapper<I>;
template <typename It, typename Out>
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_)};

View File

@ -43,6 +43,9 @@ private:
I base_ = I{};
};
template <class It>
unqualified_lookup_wrapper(It) -> unqualified_lookup_wrapper<It>;
enum unscoped_enum { a, b, c };
constexpr unscoped_enum iter_move(unscoped_enum& e) noexcept(false) { return e; }

View File

@ -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 <iterator>
#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<int*>);
return 0;
}

View File

@ -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
// <iterator>
// back_insert_iterator
// Make sure that the implicitly-generated CTAD works.
#include <iterator>
#include <string>
#include <vector>
#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::string>);
}
{
std::vector<int> v;
std::back_insert_iterator it(v);
std::back_insert_iterator copy(it);
ASSERT_SAME_TYPE(decltype(it), std::back_insert_iterator<std::vector<int>>);
ASSERT_SAME_TYPE(decltype(copy), std::back_insert_iterator<std::vector<int>>);
}
return 0;
}

View File

@ -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
// <iterator>
// front_insert_iterator
// Make sure that the implicitly-generated CTAD works.
#include <deque>
#include <iterator>
#include <string>
#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::string>);
}
{
std::deque<int> v;
std::front_insert_iterator it(v);
std::front_insert_iterator copy(it);
ASSERT_SAME_TYPE(decltype(it), std::front_insert_iterator<std::deque<int>>);
ASSERT_SAME_TYPE(decltype(copy), std::front_insert_iterator<std::deque<int>>);
}
return 0;
}

View File

@ -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
// <iterator>
// move_iterator
// Make sure that the implicitly-generated CTAD works.
#include <iterator>
#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<int*>);
return 0;
}

View File

@ -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<int*> rb(a + N);
std::reverse_iterator<int*> re(a + 1);
assert(a[0] == 0);
assert(a[2] == 2);

View File

@ -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 <ranges>
#include <utility>
#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<Range>);
return 0;
}

View File

@ -103,8 +103,8 @@ constexpr bool test() {
{
// Copyable input iterator with arrow.
ValueView<Box> children[4] = {ValueView(buffer[0]), ValueView(buffer[1]), ValueView(buffer[2]),
ValueView(buffer[3])};
using BoxView = ValueView<Box>;
ValueView<Box> children[4] = {BoxView(buffer[0]), BoxView(buffer[1]), BoxView(buffer[2]), BoxView(buffer[3])};
std::ranges::join_view jv(ValueView<ValueView<Box>>{children});
assert(jv.begin()->x == 1111);
static_assert(HasArrow<decltype(jv.begin())>);

View File

@ -37,8 +37,9 @@ constexpr bool test() {
}
{
ValueView<int> children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])};
std::ranges::join_view jv(ValueView<ValueView<int>>{children});
using IntView = ValueView<int>;
IntView children[4] = {IntView(buffer1[0]), IntView(buffer1[1]), IntView(buffer2[0]), IntView(buffer2[1])};
std::ranges::join_view jv(ValueView<IntView>{children});
auto iter = jv.begin();
for (int i = 1; i < 17; ++i) {
assert(*iter == i);
@ -152,8 +153,9 @@ constexpr bool test() {
}
{
ValueView<int> children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])};
std::ranges::join_view jv(ValueView<ValueView<int>>{children});
using IntView = ValueView<int>;
IntView children[4] = {IntView(buffer1[0]), IntView(buffer1[1]), IntView(buffer2[0]), IntView(buffer2[1])};
std::ranges::join_view jv(ValueView<IntView>{children});
auto iter = jv.begin();
for (int i = 2; i < 17; ++i) {
assert(*++iter == i);

View File

@ -75,6 +75,9 @@ struct ParentView : std::ranges::view_base {
constexpr const_sentinel end() const { return const_sentinel(const_iterator(ptr_ + size_)); }
};
template <class T>
ParentView(T*) -> ParentView<T>;
struct CopyableChild : std::ranges::view_base {
int* ptr_;
unsigned size_;

View File

@ -88,6 +88,8 @@ struct IntComparableWith {
constexpr IntComparableWith operator++(int) { auto tmp = *this; ++value_; return tmp; }
constexpr IntComparableWith operator--() { --value_; return *this; }
};
template <class T>
IntComparableWith(T) -> IntComparableWith<T>;
template<class T>
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 <class T>
IntSentinelWith(T) -> IntSentinelWith<T>;
struct NotIncrementable {
using difference_type = int;

View File

@ -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
// <string_view>
// basic_string_view
// Make sure that the implicitly-generated CTAD works.
#include <string_view>
#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<char>);
}
#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<wchar_t>);
}
#endif
return 0;
}

View File

@ -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
// <mutex>
// lock_guard
// Make sure that the implicitly-generated CTAD works.
#include <mutex>
#include "test_macros.h"
int main(int, char**) {
std::mutex mutex;
{
std::lock_guard lock(mutex);
ASSERT_SAME_TYPE(decltype(lock), std::lock_guard<std::mutex>);
}
return 0;
}

View File

@ -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
// <mutex>
// scoped_lock
// Make sure that the implicitly-generated CTAD works.
#include <mutex>
#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::mutex>);
}
{
std::scoped_lock lock(m1, m2);
ASSERT_SAME_TYPE(decltype(lock), std::scoped_lock<std::mutex, std::recursive_mutex>);
}
{
std::scoped_lock lock(m1, m2, m3);
ASSERT_SAME_TYPE(decltype(lock), std::scoped_lock<std::mutex, std::recursive_mutex, std::recursive_timed_mutex>);
}
return 0;
}

View File

@ -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_mutex>
// shared_lock
// Make sure that the implicitly-generated CTAD works.
#include <shared_mutex>
#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<std::shared_mutex>);
}
return 0;
}

View File

@ -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
// <mutex>
// unique_lock
// Make sure that the implicitly-generated CTAD works.
#include <mutex>
#include "test_macros.h"
int main(int, char**) {
std::mutex mutex;
{
std::unique_lock lock(mutex);
ASSERT_SAME_TYPE(decltype(lock), std::unique_lock<std::mutex>);
}
return 0;
}

View File

@ -27,5 +27,5 @@ static_assert(!std::is_convertible<int, std::counting_semaphore<>>::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

View File

@ -24,7 +24,7 @@ void test(
std::basic_format_args<std::basic_format_context<OutIt, CharT>> args) {
{
std::basic_string<CharT> str[3];
std::basic_format_context context =
std::basic_format_context<OutIt, CharT> context =
test_format_context_create(OutIt{str[0]}, args);
context.out() = CharT('a');
context.advance_to(OutIt{str[1]});

View File

@ -28,7 +28,7 @@ void test() {
std::basic_format_args args = store;
std::basic_string<CharT> output;
const std::basic_format_context context =
const std::basic_format_context<OutIt, CharT> context =
test_format_context_create(OutIt{output}, args);
LIBCPP_ASSERT(args.__size() == 4);
ASSERT_NOEXCEPT(context.arg(0));

View File

@ -55,8 +55,7 @@ void test() {
{
std::basic_string<CharT> output;
OutIt out_it{output};
std::basic_format_context context =
test_format_context_create(out_it, args);
std::basic_format_context<OutIt, CharT> 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<CharT> output;
OutIt out_it{output};
std::basic_format_context context =
test_format_context_create(out_it, args, en_US);
std::basic_format_context<OutIt, CharT> 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<CharT> output;
OutIt out_it{output};
std::basic_format_context context =
test_format_context_create(out_it, args, fr_FR);
std::basic_format_context<OutIt, CharT> context = test_format_context_create(out_it, args, fr_FR);
LIBCPP_ASSERT(args.__size() == 4);
assert(test_basic_format_arg(context.arg(0), true));

View File

@ -39,8 +39,7 @@ void test() {
{
std::basic_string<CharT> output;
OutIt out_it{output};
std::basic_format_context context =
test_format_context_create(out_it, args, en_US);
std::basic_format_context<OutIt, CharT> 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<CharT> output;
OutIt out_it{output};
std::basic_format_context context =
test_format_context_create(out_it, args, fr_FR);
std::basic_format_context<OutIt, CharT> 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')));

View File

@ -25,8 +25,7 @@ void test(
{
std::basic_string<CharT> str;
OutIt out_it{str};
std::basic_format_context context =
test_format_context_create(out_it, args);
std::basic_format_context<OutIt, CharT> context = test_format_context_create(out_it, args);
context.out() = CharT('a');
context.out() = CharT('b');
context.out() = CharT('c');

View File

@ -44,7 +44,7 @@ void test(StringT expected, StringViewT fmt, bool arg) {
auto out = std::back_inserter(result);
using FormatCtxT = std::basic_format_context<decltype(out), CharT>;
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(arg));
formatter.format(arg, format_ctx);
assert(result == expected);

View File

@ -43,7 +43,7 @@ void test(StringT expected, StringViewT fmt, const CharT* a) {
using FormatCtxT = std::basic_format_context<decltype(out), CharT>;
auto* arg = const_cast<T>(a);
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(arg));
formatter.format(arg, format_ctx);
assert(result == expected);

View File

@ -43,7 +43,7 @@ void test(StringT expected, StringViewT fmt, ArgumentT arg) {
auto out = std::back_inserter(result);
using FormatCtxT = std::basic_format_context<decltype(out), CharT>;
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(arg));
formatter.format(arg, format_ctx);
assert(result == expected);

View File

@ -58,7 +58,7 @@ struct Tester {
// Note not too found of this hack
Str* data = reinterpret_cast<Str*>(const_cast<CharT*>(buffer.c_str()));
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(*data));
formatter.format(*data, format_ctx);
assert(result == expected);
@ -79,6 +79,9 @@ struct Tester {
}
};
template <size_t N>
Tester(const char (&)[N]) -> Tester<N>;
template <Tester t, class CharT>
void test_helper_wrapper(std::basic_string<CharT> expected, std::basic_string<CharT> fmt) {
t.test_termination_condition(expected, fmt);

View File

@ -60,7 +60,7 @@ struct Tester {
// Note not too found of this hack
Str* data = reinterpret_cast<Str*>(buffer.c_str());
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(*data));
formatter.format(*data, format_ctx);
assert(result == expected);
@ -82,6 +82,9 @@ struct Tester {
}
};
template <size_t N>
Tester(const char (&)[N]) -> Tester<N>;
template <Tester t, class CharT>
void test_helper_wrapper(std::basic_string<CharT> expected,
std::basic_string<CharT> fmt) {

View File

@ -53,7 +53,7 @@ void test(std::basic_string_view<CharT> fmt, ArithmeticT arg, std::basic_string<
auto out = std::back_inserter(result);
using FormatCtxT = std::basic_format_context<decltype(out), CharT>;
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(arg));
formatter.format(arg, format_ctx);

View File

@ -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<decltype(out), char>;
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), char>(out, std::make_format_args<FormatCtxT>(arg));
formatter.format(arg, format_ctx);
assert(result == expected);

View File

@ -49,7 +49,7 @@ void test(StringT expected, StringViewT fmt, PointerT arg) {
auto out = std::back_inserter(result);
using FormatCtxT = std::basic_format_context<decltype(out), CharT>;
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(arg));
formatter.format(arg, format_ctx);

View File

@ -51,7 +51,7 @@ void test(StringT expected, StringViewT fmt, ArithmeticT arg) {
auto out = std::back_inserter(result);
using FormatCtxT = std::basic_format_context<decltype(out), CharT>;
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(arg));
formatter.format(arg, format_ctx);
assert(result == expected);

View File

@ -51,7 +51,7 @@ void test(StringT expected, StringViewT fmt, StringT a) {
using FormatCtxT = std::basic_format_context<decltype(out), CharT>;
ArgumentT arg = a;
std::basic_format_context format_ctx = test_format_context_create<decltype(out), CharT>(
FormatCtxT format_ctx = test_format_context_create<decltype(out), CharT>(
out, std::make_format_args<FormatCtxT>(std::forward<ArgumentT>(arg)));
formatter.format(arg, format_ctx);
assert(result == expected);

View File

@ -51,7 +51,7 @@ void test(StringT expected, StringViewT fmt, ArithmeticT arg) {
auto out = std::back_inserter(result);
using FormatCtxT = std::basic_format_context<decltype(out), CharT>;
std::basic_format_context format_ctx =
FormatCtxT format_ctx =
test_format_context_create<decltype(out), CharT>(out, std::make_format_args<FormatCtxT>(arg));
formatter.format(arg, format_ctx);
assert(result == expected);

View File

@ -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<CharT> context(view);
context.advance_to(context.begin() + 1);
assert(std::to_address(context.begin()) == fmt + 1);

View File

@ -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<CharT> context(view);
assert(context.begin() == view.begin());
ASSERT_NOEXCEPT(context.begin());
}

View File

@ -40,9 +40,9 @@ constexpr void test(const CharT* fmt) {
!std::is_move_assignable_v<std::basic_format_parse_context<CharT> >);
ASSERT_NOEXCEPT(
std::basic_format_parse_context{std::basic_string_view<CharT>{}});
std::basic_format_parse_context<CharT>{std::basic_string_view<CharT>{}});
ASSERT_NOEXCEPT(
std::basic_format_parse_context{std::basic_string_view<CharT>{}, 42});
std::basic_format_parse_context<CharT>{std::basic_string_view<CharT>{}, 42});
{
std::basic_format_parse_context<CharT> 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<CharT> context(view);
assert(context.begin() == view.begin());
assert(context.end() == view.end());
}

View File

@ -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<CharT> context(view);
assert(context.end() == view.end());
ASSERT_NOEXCEPT(context.end());
}

View File

@ -317,7 +317,7 @@ constexpr bool test() {
// Test properties of the constructor of the unspecified-type returned by bind_front.
{
{
MoveOnlyCallable value(true);
MoveOnlyCallable<bool> 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<RetT>::value);
}
{
CopyCallable value(true);
CopyCallable<bool> value(true);
auto ret = std::bind_front(value, 1);
assert(ret());
assert(ret(1, 2, 3));

View File

@ -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
// <functional>
// boyer_moore_searcher
// Make sure that the implicitly-generated CTAD works.
#include <functional>
#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<char const*, std::hash<char>, std::equal_to<>>);
}
{
struct myhash : std::hash<char> { };
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<char const*, myhash, std::not_equal_to<>>);
}
{
struct myhash : std::hash<char> { };
char const* str = "hello";
std::boyer_moore_searcher searcher(str, str + 3, myhash{});
ASSERT_SAME_TYPE(decltype(searcher), std::boyer_moore_searcher<char const*, myhash, std::equal_to<>>);
}
return 0;
}

View File

@ -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
// <functional>
// boyer_moore_horspool_searcher
// Make sure that the implicitly-generated CTAD works.
#include <functional>
#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<char const*, std::hash<char>, std::equal_to<>>);
}
{
struct myhash : std::hash<char> { };
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<char const*, myhash, std::not_equal_to<>>);
}
{
struct myhash : std::hash<char> { };
char const* str = "hello";
std::boyer_moore_horspool_searcher searcher(str, str + 3, myhash{});
ASSERT_SAME_TYPE(decltype(searcher), std::boyer_moore_horspool_searcher<char const*, myhash, std::equal_to<>>);
}
return 0;
}

View File

@ -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
// <functional>
// default searcher
// Make sure that the implicitly-generated CTAD works.
#include <functional>
#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*, std::equal_to<>>);
}
{
char const* str = "hello";
std::default_searcher searcher(str, str + 3, std::not_equal_to<>());
ASSERT_SAME_TYPE(decltype(searcher), std::default_searcher<char const*, std::not_equal_to<>>);
}
return 0;
}

View File

@ -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
// <functional>
// Make sure that we can use CTAD with operations in <functional>
#include <functional>
#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;
}

View File

@ -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
// <variant>
// template <class ...Types> 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 <variant>
#include "test_macros.h"
int main(int, char**) {
// This is the motivating example from P0739R0
{
std::variant<int, double> v1(3);
std::variant v2 = v1;
ASSERT_SAME_TYPE(decltype(v2), std::variant<int, double>);
}
{
std::variant<int, double> v1(3);
std::variant v2 = std::variant(v1); // Technically valid, but intent is ambiguous!
ASSERT_SAME_TYPE(decltype(v2), std::variant<int, double>);
}
return 0;
}

View File

@ -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<int, double> v1(3);
std::variant v2 = v1;
(void)v2;
}
return 0;
}

View File

@ -18,7 +18,7 @@
constexpr bool returns_true() { return true; }
template <class Ret = bool>
template <class Ret>
struct MoveOnlyCallable {
MoveOnlyCallable(MoveOnlyCallable const&) = delete;
constexpr MoveOnlyCallable(MoveOnlyCallable&& other)
@ -32,7 +32,7 @@ struct MoveOnlyCallable {
Ret value;
};
template <class Ret = bool>
template <class Ret>
struct CopyCallable {
constexpr CopyCallable(CopyCallable const& other)
: value(other.value) {}
@ -48,7 +48,7 @@ struct CopyCallable {
};
template <class Ret = bool>
template <class Ret>
struct ConstCallable {
constexpr ConstCallable(ConstCallable const& other)
: value(other.value) {}
@ -65,7 +65,7 @@ struct ConstCallable {
template <class Ret = bool>
template <class Ret>
struct NoExceptCallable {
constexpr NoExceptCallable(NoExceptCallable const& other)
: value(other.value) {}

View File

@ -53,6 +53,11 @@ public:
template <class T>
void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
cpp17_output_iterator(It) -> cpp17_output_iterator<It>;
#endif
#if TEST_STD_VER > 17
static_assert(std::output_iterator<cpp17_output_iterator<int*>, int>);
#endif
@ -94,6 +99,11 @@ public:
template <class T>
void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
cpp17_input_iterator(It) -> cpp17_input_iterator<It>;
#endif
#if TEST_STD_VER > 17
static_assert(std::input_iterator<cpp17_input_iterator<int*>>);
#endif
@ -133,6 +143,10 @@ public:
template <class T>
void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
forward_iterator(It) -> forward_iterator<It>;
#endif
template <class It>
class bidirectional_iterator
@ -171,6 +185,10 @@ public:
template <class T>
void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
bidirectional_iterator(It) -> bidirectional_iterator<It>;
#endif
template <class It>
class random_access_iterator
@ -221,6 +239,10 @@ public:
template <class T>
void operator,(T const &) = delete;
};
#if TEST_STD_VER > 14
template <class It>
random_access_iterator(It) -> random_access_iterator<It>;
#endif
#if TEST_STD_VER > 17
@ -310,6 +332,8 @@ public:
template <class T>
void operator,(T const&) = delete;
};
template <class It>
cpp20_random_access_iterator(It) -> cpp20_random_access_iterator<It>;
static_assert(std::random_access_iterator<cpp20_random_access_iterator<int*>>);
@ -368,6 +392,8 @@ public:
template <class T>
void operator,(T const &) = delete;
};
template <class It>
contiguous_iterator(It) -> contiguous_iterator<It>;
template <class It>
class three_way_contiguous_iterator
@ -418,6 +444,8 @@ public:
template <class T>
void operator,(T const &) = delete;
};
template <class It>
three_way_contiguous_iterator(It) -> three_way_contiguous_iterator<It>;
#endif // TEST_STD_VER > 17
template <class Iter> // ADL base() for everything else (including pointers)
@ -627,6 +655,9 @@ public:
template <class T>
void operator,(T const &) = delete;
};
template <class It>
cpp20_input_iterator(It) -> cpp20_input_iterator<It>;
static_assert(std::input_iterator<cpp20_input_iterator<int*>>);
template<std::input_or_output_iterator>
@ -660,6 +691,8 @@ public:
template <class T>
void operator,(T const&) = delete;
};
template <class It>
cpp20_output_iterator(It) -> cpp20_output_iterator<It>;
static_assert(std::output_iterator<cpp20_output_iterator<int*>, int>);
@ -815,6 +848,8 @@ private:
difference_type stride_count_ = 0;
difference_type stride_displacement_ = 0;
};
template <class It>
stride_counting_iterator(It) -> stride_counting_iterator<It>;
#endif // TEST_STD_VER > 17
@ -829,6 +864,8 @@ public:
private:
decltype(base(std::declval<It>())) base_;
};
template <class It>
sentinel_wrapper(It) -> sentinel_wrapper<It>;
template <class It>
class sized_sentinel {
@ -842,6 +879,8 @@ public:
private:
decltype(base(std::declval<It>())) base_;
};
template <class It>
sized_sentinel(It) -> sized_sentinel<It>;
namespace adl {
@ -1211,6 +1250,8 @@ struct ProxyIterator : ProxyIteratorBase<Base> {
return x.base_ - y.base_;
}
};
template <class Base>
ProxyIterator(Base) -> ProxyIterator<Base>;
static_assert(std::indirectly_readable<ProxyIterator<int*>>);
static_assert(std::indirectly_writable<ProxyIterator<int*>, Proxy<int>>);
@ -1229,6 +1270,8 @@ struct ProxySentinel {
return p.base_ == sent.base_;
}
};
template <class BaseSent>
ProxySentinel(BaseSent) -> ProxySentinel<BaseSent>;
template <std::ranges::input_range Base>
requires std::ranges::view<Base>

View File

@ -13,6 +13,7 @@ import re
_warningFlags = [
'-Werror',
'-Wall',
'-Wctad-maybe-unsupported',
'-Wextra',
'-Wshadow',
'-Wundef',