C++20 isn't final quite yet, but all that remains is formalities, so let's go ahead and change all the references. I think for the next C++ standard we can just call it C++23 rather than C++2b, since the committee has been consistent about time-based releases rather than feature-based. gcc/c-family/ChangeLog 2020-05-13 Jason Merrill <jason@redhat.com> * c.opt (std=c++20): Make c++2a the alias. (std=gnu++20): Likewise. * c-common.h (cxx_dialect): Change cxx2a to cxx20. * c-opts.c: Adjust. * c-cppbuiltin.c: Adjust. * c-ubsan.c: Adjust. * c-warn.c: Adjust. gcc/cp/ChangeLog 2020-05-13 Jason Merrill <jason@redhat.com> * call.c, class.c, constexpr.c, constraint.cc, decl.c, init.c, lambda.c, lex.c, method.c, name-lookup.c, parser.c, pt.c, tree.c, typeck2.c: Change cxx2a to cxx20. libcpp/ChangeLog 2020-05-13 Jason Merrill <jason@redhat.com> * include/cpplib.h (enum c_lang): Change CXX2A to CXX20. * init.c, lex.c: Adjust.
84 lines
1.9 KiB
C
84 lines
1.9 KiB
C
// P0784R7
|
|
// { dg-do compile { target c++20 } }
|
|
|
|
namespace std
|
|
{
|
|
inline namespace _8 { }
|
|
namespace _8 {
|
|
|
|
typedef __SIZE_TYPE__ size_t;
|
|
|
|
template <typename T>
|
|
struct allocator
|
|
{
|
|
constexpr allocator () noexcept {}
|
|
|
|
constexpr T *allocate (size_t n)
|
|
{ return static_cast<T *> (::operator new (n * sizeof(T))); }
|
|
|
|
constexpr void
|
|
deallocate (T *p, size_t n)
|
|
{ ::operator delete (p); }
|
|
};
|
|
|
|
template <typename T, typename U = T &&>
|
|
U __declval (int);
|
|
template <typename T>
|
|
T __declval (long);
|
|
template <typename T>
|
|
auto declval () noexcept -> decltype (__declval<T> (0));
|
|
|
|
template <typename T>
|
|
struct remove_reference
|
|
{ typedef T type; };
|
|
template <typename T>
|
|
struct remove_reference<T &>
|
|
{ typedef T type; };
|
|
template <typename T>
|
|
struct remove_reference<T &&>
|
|
{ typedef T type; };
|
|
|
|
template <typename T>
|
|
constexpr T &&
|
|
forward (typename std::remove_reference<T>::type &t) noexcept
|
|
{ return static_cast<T&&> (t); }
|
|
|
|
template<typename T>
|
|
constexpr T &&
|
|
forward (typename std::remove_reference<T>::type &&t) noexcept
|
|
{ return static_cast<T&&> (t); }
|
|
|
|
template <typename T, typename... A>
|
|
constexpr auto
|
|
construct_at (T *l, A &&... a)
|
|
noexcept (noexcept (::new ((void *) 0) T (std::declval<A> ()...)))
|
|
-> decltype (::new ((void *) 0) T (std::declval<A> ()...))
|
|
{ return ::new ((void *) l) T (std::forward<A> (a)...); }
|
|
|
|
template <typename T>
|
|
constexpr inline void
|
|
destroy_at (T *l)
|
|
{ l->~T (); }
|
|
}
|
|
}
|
|
|
|
inline void *operator new (std::size_t, void *p) noexcept
|
|
{ return p; }
|
|
|
|
constexpr bool
|
|
foo ()
|
|
{
|
|
std::allocator<int> a;
|
|
auto p = a.allocate (2);
|
|
std::construct_at (p, 1);
|
|
std::construct_at (p + 1, 2);
|
|
if (p[0] != 1 || p[1] != 2)
|
|
throw 1;
|
|
std::destroy_at (p);
|
|
std::destroy_at (p + 1);
|
|
a.deallocate (p, 2);
|
|
return true;
|
|
}
|
|
|
|
static_assert (foo ());
|