diff --git a/libcxx/docs/Status/Cxx17.rst b/libcxx/docs/Status/Cxx17.rst --- a/libcxx/docs/Status/Cxx17.rst +++ b/libcxx/docs/Status/Cxx17.rst @@ -40,7 +40,7 @@ .. note:: - .. [#note-P0433] P0433: So far, only the ````, sequence containers, container adaptors and ```` portions of P0433 have been implemented. + .. [#note-P0433] P0433: The only part not fully implemented is the requirement that certain deduction guides should not participate in overload resolution when given incorrect template arguments. .. [#note-P0607] P0607: The parts of P0607 that are not done are the ```` bits. diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv --- a/libcxx/docs/Status/Cxx20Issues.csv +++ b/libcxx/docs/Status/Cxx20Issues.csv @@ -32,7 +32,7 @@ "`2978 `__","Hash support for pmr::string and friends","Albuquerque","","" "`2979 `__","aligned_union should require complete object types","Albuquerque","|Complete|","" "`2980 `__","Cannot compare_exchange empty pointers","Albuquerque","","" -"`2981 `__","Remove redundant deduction guides from standard library","Albuquerque","","" +"`2981 `__","Remove redundant deduction guides from standard library","Albuquerque","|Nothing To Do|","" "`2982 `__","Making size_type consistent in associative container deduction guides","Albuquerque","","" "`2988 `__","Clause 32 cleanup missed one typename","Albuquerque","|Complete|","13.0" "`2993 `__","reference_wrapper conversion from T&&","Albuquerque","|Complete|","13.0" diff --git a/libcxx/include/scoped_allocator b/libcxx/include/scoped_allocator --- a/libcxx/include/scoped_allocator +++ b/libcxx/include/scoped_allocator @@ -91,6 +91,10 @@ scoped_allocator_adaptor select_on_container_copy_construction() const noexcept; }; +template + scoped_allocator_adaptor(OuterAlloc, InnerAllocs...) + -> scoped_allocator_adaptor; + template bool operator==(const scoped_allocator_adaptor& a, @@ -649,6 +653,12 @@ template friend class __scoped_allocator_storage; }; +#if _LIBCPP_STD_VER > 14 +template + scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...) + -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>; +#endif + template inline _LIBCPP_INLINE_VISIBILITY bool diff --git a/libcxx/include/utility b/libcxx/include/utility --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -95,6 +95,8 @@ is_nothrow_swappable_v); // constexpr in C++20 }; +template pair(T1, T2) -> pair; + template bool operator==(const pair&, const pair&); // constexpr in C++14 template bool operator!=(const pair&, const pair&); // constexpr in C++14, removed in C++20 template bool operator< (const pair&, const pair&); // constexpr in C++14, removed in C++20 diff --git a/libcxx/include/valarray b/libcxx/include/valarray --- a/libcxx/include/valarray +++ b/libcxx/include/valarray @@ -105,6 +105,8 @@ void resize(size_t n, value_type x = value_type()); }; +template valarray(const T(&)[cnt], size_t) -> valarray; + class slice { public: @@ -1081,6 +1083,11 @@ valarray& __assign_range(const value_type* __f, const value_type* __l); }; +#if _LIBCPP_STD_VER > 14 +template +valarray(const _Tp(&)[_Size], size_t) -> valarray<_Tp>; +#endif + _LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void valarray::resize(size_t, size_t)) template diff --git a/libcxx/test/std/numerics/numarray/template.valarray/valarray.cons/deduct.pass.cpp b/libcxx/test/std/numerics/numarray/template.valarray/valarray.cons/deduct.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/numarray/template.valarray/valarray.cons/deduct.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// 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 valarray(const T(&)[cnt], size_t) -> valarray; + +#include + +#include "test_macros.h" + +int main(int, char**) +{ + { + // From (initializer_list) + std::valarray v = {1, 2, 3, 4, 5}; + ASSERT_SAME_TYPE(decltype(v), std::valarray); + } + + { + // From (const T(&)[N], size_t) + long a[] = {1, 2, 3, 4, 5}; + std::valarray v(a, 5); + ASSERT_SAME_TYPE(decltype(v), std::valarray); + } + + { + // From (const T&, size_t) + long a[] = {1, 2, 3, 4, 5}; + std::valarray v(&a[0], 5); + // Surprising but true. + ASSERT_SAME_TYPE(decltype(v), std::valarray); + } + + { + // From (slice_array) + std::valarray v{1,2,3,4,5}; + std::valarray v2 = v[std::slice(2,3,1)]; + static_assert(std::is_same_v>); + } + + { + // From (gslice_array) + std::valarray v{1,2,3,4,5}; + std::valarray v2 = v[std::gslice(0, {5}, {1})]; + static_assert(std::is_same_v>); + } + + { + // From (mask_array) + std::valarray v = {1, 2, 3, 4, 5}; + std::valarray m = {true, false, true, false, true}; + std::valarray v2 = v[m]; + static_assert(std::is_same_v>); + } + + { + // From (indirect_array) + std::valarray v = {1, 2, 3, 4, 5}; + std::valarray i = {1, 2, 3}; + std::valarray v2 = v[i]; + static_assert(std::is_same_v>); + } + + return 0; +} diff --git a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.fail.cpp b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.fail.cpp --- a/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.fail.cpp +++ b/libcxx/test/std/strings/basic.string/string.cons/iter_alloc_deduction.fail.cpp @@ -28,7 +28,7 @@ #include "test_macros.h" -class NotAnItertor {}; +class NotAnIterator {}; template struct NotAnAllocator { typedef T value_type; }; @@ -36,7 +36,7 @@ int main(int, char**) { { // Not an iterator at all - std::basic_string s1{NotAnItertor{}, NotAnItertor{}, std::allocator{}}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}} + std::basic_string s1{NotAnIterator{}, NotAnIterator{}, std::allocator{}}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_string'}} } { // Not an input iterator std::basic_string s0; diff --git a/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp b/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp --- a/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp +++ b/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/allocs.pass.cpp @@ -8,7 +8,7 @@ // UNSUPPORTED: c++03 -// +// // template // class scoped_allocator_adaptor diff --git a/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/deduct.pass.cpp b/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/deduct.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.cnstr/deduct.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...) +// -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>; + +#include + +#include "test_macros.h" +#include "allocators.h" + +int main(int, char**) +{ + // Deduct from (const OuterAlloc&). + { + typedef A1 OuterAlloc; + OuterAlloc outer(3); + std::scoped_allocator_adaptor a(outer); + ASSERT_SAME_TYPE(decltype(a), std::scoped_allocator_adaptor); + } + + // Deduct from (OuterAlloc&&). + { + typedef A1 OuterAlloc; + std::scoped_allocator_adaptor a(OuterAlloc(3)); + ASSERT_SAME_TYPE(decltype(a), std::scoped_allocator_adaptor); + } + + // Deduct from (const OuterAlloc&, const InnerAlloc&). + { + typedef A1 OuterAlloc; + typedef A2 InnerAlloc; + OuterAlloc outer(3); + InnerAlloc inner(4); + + std::scoped_allocator_adaptor a(outer, inner); + ASSERT_SAME_TYPE(decltype(a), std::scoped_allocator_adaptor); + } + + // Deduct from (const OuterAlloc&, const InnerAlloc1&, InnerAlloc2&&). + { + typedef A1 OuterAlloc; + typedef A2 InnerAlloc1; + typedef A2 InnerAlloc2; + OuterAlloc outer(3); + InnerAlloc1 inner(4); + + std::scoped_allocator_adaptor a(outer, inner, InnerAlloc2(5)); + ASSERT_SAME_TYPE( + decltype(a), std::scoped_allocator_adaptor); + } + + return 0; +} diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.pass.cpp @@ -25,7 +25,7 @@ { // optional(T) std::optional opt(5); - static_assert(std::is_same_v>, ""); + ASSERT_SAME_TYPE(decltype(opt), std::optional); assert(static_cast(opt)); assert(*opt == 5); } @@ -33,16 +33,43 @@ { // optional(T) std::optional opt(A{}); - static_assert(std::is_same_v>, ""); + ASSERT_SAME_TYPE(decltype(opt), std::optional); assert(static_cast(opt)); } + { +// optional(const T&); + const int& source = 5; + std::optional opt(source); + ASSERT_SAME_TYPE(decltype(opt), std::optional); + assert(static_cast(opt)); + assert(*opt == 5); + } + + { +// optional(T*); + const int* source = nullptr; + std::optional opt(source); + ASSERT_SAME_TYPE(decltype(opt), std::optional); + assert(static_cast(opt)); + assert(*opt == nullptr); + } + + { +// optional(T[]); + int source[] = {1, 2, 3}; + std::optional opt(source); + ASSERT_SAME_TYPE(decltype(opt), std::optional); + assert(static_cast(opt)); + assert((*opt)[0] == 1); + } + // Test the implicit deduction guides { // optional(optional); std::optional source('A'); std::optional opt(source); - static_assert(std::is_same_v>, ""); + ASSERT_SAME_TYPE(decltype(opt), std::optional); assert(static_cast(opt) == static_cast(source)); assert(*opt == *source); }