Skip to content

Prepare the constexpr machinery needed for string and vector #1546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stl/inc/regex
Original file line number Diff line number Diff line change
Expand Up @@ -2466,7 +2466,7 @@ public:
_MyRe = nullptr;

#if _ITERATOR_DEBUG_LEVEL == 2
this->_Orphan_me();
this->_Orphan_me_v2();
#endif // _ITERATOR_DEBUG_LEVEL

return *this;
Expand Down
435 changes: 271 additions & 164 deletions stl/inc/xmemory

Large diffs are not rendered by default.

20 changes: 14 additions & 6 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,26 @@ _NODISCARD constexpr void* _Voidify_iter(_Iter _It) noexcept {

// FUNCTION TEMPLATE construct_at
#if _HAS_CXX20
template <class _Ty, class... _Types>
_CONSTEXPR20_DYNALLOC auto construct_at(_Ty* const _Location, _Types&&... _Args) noexcept(
noexcept(::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...))) // strengthened
-> decltype(::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...)) {
template <class _Ty, class... _Types,
class = void_t<decltype(::new (_STD declval<void*>()) _Ty(_STD declval<_Types>()...))>>
_CONSTEXPR20_DYNALLOC _Ty* construct_at(_Ty* const _Location, _Types&&... _Args) noexcept(
noexcept(::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...))) /* strengthened */ {
return ::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...);
}
#endif // _HAS_CXX20

// FUNCTION TEMPLATE _Construct_in_place
template <class _Ty, class... _Types>
void _Construct_in_place(_Ty& _Obj, _Types&&... _Args) noexcept(is_nothrow_constructible_v<_Ty, _Types...>) {
::new (_Voidify_iter(_STD addressof(_Obj))) _Ty(_STD forward<_Types>(_Args)...);
_CONSTEXPR20_DYNALLOC void _Construct_in_place(_Ty& _Obj, _Types&&... _Args) noexcept(
is_nothrow_constructible_v<_Ty, _Types...>) {
#ifdef __cpp_lib_constexpr_dynamic_alloc
if (_STD is_constant_evaluated()) {
_STD construct_at(_STD addressof(_Obj), _STD forward<_Types>(_Args)...);
} else
#endif // __cpp_lib_constexpr_dynamic_alloc
{
::new (_Voidify_iter(_STD addressof(_Obj))) _Ty(_STD forward<_Types>(_Args)...);
}
}

// FUNCTION TEMPLATE _Default_construct_in_place
Expand Down
12 changes: 9 additions & 3 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1190,10 +1190,9 @@
#define __cpp_lib_constexpr_algorithms 201806L
#define __cpp_lib_constexpr_complex 201711L

#if defined(__cpp_constexpr_dynamic_alloc) \
&& defined(__clang__) // TRANSITION, MSVC support for constexpr dynamic allocation
#ifdef __cpp_constexpr_dynamic_alloc
#define __cpp_lib_constexpr_dynamic_alloc 201907L
#endif // defined(__cpp_constexpr_dynamic_alloc) && defined(__clang__)
#endif // __cpp_constexpr_dynamic_alloc

#define __cpp_lib_constexpr_functional 201907L
#define __cpp_lib_constexpr_iterator 201811L
Expand Down Expand Up @@ -1284,6 +1283,13 @@
#define _CONSTEXPR20_DYNALLOC inline
#endif

// Functions that became constexpr in C++20 via P0980R1 or P1004R2
#if defined(__cpp_lib_constexpr_dynamic_alloc) && !defined(__clang__) // TRANSITION:LLVM-48606
#define _CONSTEXPR20_CONTAINER constexpr
#else
#define _CONSTEXPR20_CONTAINER inline
#endif

#ifdef _RTC_CONVERSION_CHECKS_ENABLED
#ifndef _ALLOW_RTCc_IN_STL
#error /RTCc rejects conformant code, so it is not supported by the C++ Standard Library. Either remove this \
Expand Down
9 changes: 0 additions & 9 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -310,18 +310,9 @@ std/language.support/support.limits/support.limits.general/format.version.pass.c
std/utilities/format/format.error/format.error.pass.cpp FAIL

# C++20 P0784R7 "More constexpr containers"
std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp:0 FAIL
std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp:0 FAIL
std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp FAIL
std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp:0 FAIL
std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp FAIL
std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp:0 FAIL
std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp:0 FAIL
std/utilities/memory/default.allocator/allocator.globals/eq.pass.cpp:0 FAIL
std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp FAIL
std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp:0 FAIL
std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp:0 FAIL
std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp:0 FAIL

# C++20 P0896R4 "<ranges>"
std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp FAIL
Expand Down
9 changes: 0 additions & 9 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -310,18 +310,9 @@ language.support\support.limits\support.limits.general\format.version.pass.cpp
utilities\format\format.error\format.error.pass.cpp

# C++20 P0784R7 "More constexpr containers"
utilities\memory\allocator.traits\allocator.traits.members\allocate.pass.cpp
utilities\memory\allocator.traits\allocator.traits.members\allocate_hint.pass.cpp
utilities\memory\allocator.traits\allocator.traits.members\construct.pass.cpp
utilities\memory\allocator.traits\allocator.traits.members\deallocate.pass.cpp
utilities\memory\allocator.traits\allocator.traits.members\destroy.pass.cpp
utilities\memory\allocator.traits\allocator.traits.members\max_size.pass.cpp
utilities\memory\allocator.traits\allocator.traits.members\select_on_container_copy_construction.pass.cpp
utilities\memory\default.allocator\allocator.globals\eq.pass.cpp
utilities\memory\specialized.algorithms\specialized.construct\construct_at.pass.cpp
utilities\memory\specialized.algorithms\specialized.destroy\destroy.pass.cpp
utilities\memory\specialized.algorithms\specialized.destroy\destroy_at.pass.cpp
utilities\memory\specialized.algorithms\specialized.destroy\destroy_n.pass.cpp

# C++20 P0896R4 "<ranges>"
language.support\support.limits\support.limits.general\algorithm.version.pass.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ void test_array(const T& val) {
}

#ifdef __cpp_lib_constexpr_dynamic_alloc
#ifndef __EDG__ // TRANSITION, VSO-1269976
template <class T>
struct storage_for {
union {
Expand All @@ -244,9 +245,11 @@ constexpr void test_compiletime() {
assert(s.object == 42);
destroy_at(&s.object);

#ifdef __cpp_lib_concepts
ranges::construct_at(&s.object, 1729);
assert(s.object == 1729);
ranges::destroy_at(&s.object);
#endif // __cpp_lib_concepts
}

struct nontrivial {
Expand All @@ -262,12 +265,15 @@ constexpr void test_compiletime() {
assert(s.object.x == 42);
destroy_at(&s.object);

#ifdef __cpp_lib_concepts
ranges::construct_at(&s.object, 1729);
assert(s.object.x == 1729);
ranges::destroy_at(&s.object);
#endif // __cpp_lib_concepts
}
}
static_assert((test_compiletime(), true));
#endif // __EDG__

template <class T>
struct A {
Expand All @@ -286,6 +292,7 @@ struct nontrivial_A {
};

constexpr void test_compiletime_destroy_variants() {
#ifndef __EDG__ // TRANSITION, VSO-1270011
{
allocator<A<int>> alloc{};
A<int>* a = alloc.allocate(10);
Expand All @@ -304,6 +311,7 @@ constexpr void test_compiletime_destroy_variants() {
destroy(a, a + 10);
alloc.deallocate(a, 10);
}
#endif // __EDG__
#ifdef __cpp_lib_concepts
{
allocator<A<int>> alloc{};
Expand Down Expand Up @@ -385,6 +393,7 @@ constexpr void test_compiletime_destroy_variants() {
}
static_assert((test_compiletime_destroy_variants(), true));

#ifndef __EDG__ // TRANSITION, VSO-1269976
template <class T, bool Construct = false, bool Destroy = false>
struct Alloc {
using value_type = T;
Expand Down Expand Up @@ -498,6 +507,7 @@ constexpr void test_compiletime_allocator_traits() {
}
}
static_assert((test_compiletime_allocator_traits(), true));
#endif // __EDG__

constexpr void test_compiletime_allocator() {
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,7 @@ STATIC_ASSERT(__cpp_lib_constexpr_complex == 201711L);
#endif
#endif

#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) \
&& defined(__clang__) // TRANSITION, MSVC support for constexpr dynamic allocation
#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc)
#ifndef __cpp_lib_constexpr_dynamic_alloc
#error __cpp_lib_constexpr_dynamic_alloc is not defined
#elif __cpp_lib_constexpr_dynamic_alloc != 201907L
Expand Down