libstdc++: Make std::construct_at support arrays (LWG 3436)
The issue was approved at the recent St. Louis meeting, requiring support for bounded arrays, but only without arguments to initialize the array elements. libstdc++-v3/ChangeLog: * include/bits/stl_construct.h (construct_at): Support array types (LWG 3436). * testsuite/20_util/specialized_algorithms/construct_at/array.cc: New test. * testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc: New test. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-opt1.C: Adjust for different diagnostics from std::construct_at by adding -fconcepts-diagnostics-depth=2.
This commit is contained in:
parent
ce89d2f317
commit
993deb3a9a
4 changed files with 78 additions and 3 deletions
|
@ -1,5 +1,6 @@
|
|||
// PR c++/110102
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-additional-options "-fconcepts-diagnostics-depth=2" { target c++20 } }
|
||||
// { dg-skip-if "requires hosted libstdc++ for list" { ! hostedlib } }
|
||||
|
||||
// { dg-error "deleted|construct_at" "" { target *-*-* } 0 }
|
||||
|
|
|
@ -90,11 +90,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
#if __cpp_constexpr_dynamic_alloc // >= C++20
|
||||
template<typename _Tp, typename... _Args>
|
||||
constexpr auto
|
||||
requires (!is_unbounded_array_v<_Tp>)
|
||||
&& requires { ::new((void*)0) _Tp(std::declval<_Args>()...); }
|
||||
constexpr _Tp*
|
||||
construct_at(_Tp* __location, _Args&&... __args)
|
||||
noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...)))
|
||||
-> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))
|
||||
{ return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); }
|
||||
{
|
||||
void* __loc = const_cast<remove_cv_t<_Tp>*>(__location);
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 3436. std::construct_at should support arrays
|
||||
if constexpr (is_array_v<_Tp>)
|
||||
{
|
||||
static_assert(sizeof...(_Args) == 0, "std::construct_at for array "
|
||||
"types must not use any arguments to initialize the "
|
||||
"array");
|
||||
return ::new(__loc) _Tp[1]();
|
||||
}
|
||||
else
|
||||
return ::new(__loc) _Tp(std::forward<_Args>(__args)...);
|
||||
}
|
||||
#endif // C++20
|
||||
#endif// C++17
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
// { dg-do compile { target c++20 } }
|
||||
|
||||
// LWG 3436. std::construct_at should support arrays
|
||||
|
||||
#include <memory>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
constexpr void
|
||||
test_array()
|
||||
{
|
||||
int arr[1] { 99 };
|
||||
std::construct_at(&arr);
|
||||
VERIFY( arr[0] == 0 );
|
||||
|
||||
union U {
|
||||
long long x;
|
||||
int arr[4];
|
||||
} u;
|
||||
u.x = -1;
|
||||
|
||||
auto p = std::construct_at(&u.arr);
|
||||
VERIFY( (*p)[0] == 0 );
|
||||
VERIFY( (*p)[1] == 0 );
|
||||
VERIFY( (*p)[2] == 0 );
|
||||
VERIFY( (*p)[3] == 0 );
|
||||
|
||||
struct NonTrivial {
|
||||
constexpr NonTrivial() : i(99) { }
|
||||
int i;
|
||||
};
|
||||
|
||||
union U2 {
|
||||
char c = 'a';
|
||||
NonTrivial arr[2];
|
||||
} u2;
|
||||
|
||||
auto p2 = std::construct_at(&u2.arr);
|
||||
VERIFY( (*p2)[0].i == 99 );
|
||||
}
|
||||
|
||||
static_assert( [] { test_array(); return true; }() );
|
|
@ -0,0 +1,19 @@
|
|||
// { dg-do compile { target c++20 } }
|
||||
|
||||
// LWG 3436. std::construct_at should support arrays
|
||||
|
||||
#include <memory>
|
||||
|
||||
void
|
||||
test_array_args()
|
||||
{
|
||||
int arr[2];
|
||||
std::construct_at(&arr, 1, 2); // { dg-error "here" }
|
||||
// { dg-error "must not use any arguments" "" { target *-*-* } 0 }
|
||||
}
|
||||
|
||||
void
|
||||
test_unbounded_array(int (*p)[])
|
||||
{
|
||||
std::construct_at(p); // { dg-error "no matching function" }
|
||||
}
|
Loading…
Add table
Reference in a new issue