Skip to content

Implement constexpr std::vector #1407

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 53 commits into from
Feb 17, 2021
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
b03c708
Prepare the constexpr machinery needed for string and vector
miscco Dec 21, 2020
0d8082a
Properly initialize
miscco Jan 11, 2021
a3add31
Merge branch 'master' into constexpr_machinery
miscco Jan 18, 2021
0ca2b48
Use _CONSTEXPR20_CONTAINER
miscco Jan 18, 2021
4135658
Address review comments
miscco Jan 21, 2021
9b9c2bc
Merge branch 'master' into constexpr_machinery
miscco Jan 22, 2021
3000309
Unblock __cpp_lib_constexpr_dynamic_alloc for all compilers that supp…
miscco Jan 22, 2021
593de17
Unskip some tests
miscco Jan 22, 2021
5e56275
Consistently use __cpp_lib_constexpr_dynamic_alloc
miscco Jan 22, 2021
ed8c2dc
Properly guard ranges in tests
miscco Jan 22, 2021
5d393af
Disable portions of P0784 test for EDG due to bugs
mnatsuhara Jan 27, 2021
b3140a4
Try to apply workaround
miscco Jan 29, 2021
d6f948d
[P10042R2] Implement constexpr vector
miscco Jan 29, 2021
c369090
Properly unlock everytime
miscco Jan 29, 2021
c0d079b
Another forgotten proxy validation
miscco Jan 29, 2021
1c9b289
Negation is hard
miscco Jan 29, 2021
2a0b677
Merge branch 'main' into gh1407
mnatsuhara Feb 4, 2021
fd7c402
Disable portions of P1004R2_constexpr_vector test for EDG and C1XX bugs
mnatsuhara Feb 4, 2021
649724f
update test functions with new _CONSTEXPR20_CONTAINER macro
mnatsuhara Feb 4, 2021
6a93a12
#if out appropriate regions of vector bool test for EDG/cl bugs
mnatsuhara Feb 5, 2021
634acd5
add workaround for DevCom-1331017
mnatsuhara Feb 5, 2021
3edeeaa
Missed updating a few comments with bug numbers in vector bool tests
mnatsuhara Feb 5, 2021
5a32d99
address some review comments
mnatsuhara Feb 5, 2021
aa3da7b
add more workarounds for VSO-1269037, VSO-1331017
mnatsuhara Feb 5, 2021
eaf17a4
xfail/skip libcxx tests triggered by VSO-1275530
mnatsuhara Feb 5, 2021
e2d23ea
update transition comments with new bug number
mnatsuhara Feb 6, 2021
06a7772
fix formatting in expected_results/skipped_tests
mnatsuhara Feb 6, 2021
ac012b6
add missing test coverage
mnatsuhara Feb 6, 2021
e11cd62
Fix regex _Orphan_me* call
mnatsuhara Feb 8, 2021
ad545c0
remove defined(_MSVC_INTERNAL_TESTING) until tests are passing intern…
mnatsuhara Feb 8, 2021
25dba61
Fix up tests with recent changes to constexpr containers status, new bug
mnatsuhara Feb 8, 2021
525847c
update #endif comment to match
mnatsuhara Feb 8, 2021
95fc807
Test addition: Feature-test macro.
StephanTLavavej Feb 10, 2021
9351220
<vector> cleanups: Add noexcept consistently, detach comment.
StephanTLavavej Feb 11, 2021
359de1d
<xmemory> cleanups: Remove unnecessary parentheses, add newline.
StephanTLavavej Feb 11, 2021
9ce6e16
<regex>, <xmemory>: Undo incorrect/unnecessary orphaning changes.
StephanTLavavej Feb 10, 2021
c8e6341
<vector>: Guard _Check_all_orphaned identically to its usage.
StephanTLavavej Feb 11, 2021
4f334f0
<vector>: hash for vector<bool> can't be constexpr, and doesn't need …
StephanTLavavej Feb 11, 2021
c712259
Test cleanup: Drop std qualification.
StephanTLavavej Feb 11, 2021
664957b
Test cleanup: Include headers.
StephanTLavavej Feb 11, 2021
0d7537b
Test cleanup: Remove unnecessary semicolons.
StephanTLavavej Feb 11, 2021
8929334
Test cleanup: Remove constexpr for deleted functions.
StephanTLavavej Feb 11, 2021
a3f5a8d
Test cleanup: This test is always C++20.
StephanTLavavej Feb 11, 2021
a5e8e46
Test cleanup: Don't need to define op!= in C++20.
StephanTLavavej Feb 11, 2021
8df8d70
Test cleanup: Change 4 to sizeof(int).
StephanTLavavej Feb 11, 2021
102aa91
Test cleanup: Fix comment typos.
StephanTLavavej Feb 11, 2021
b967b7d
Test addition: Verify default_constructed.empty().
StephanTLavavej Feb 11, 2021
6e3d24e
Test cleanup: Comment moved-from assumptions.
StephanTLavavej Feb 11, 2021
8d9dd5b
Test addition: Test the less-than etc. operators.
StephanTLavavej Feb 11, 2021
da10679
Test cleanup: Remove iterator arrow test for vector<bool>.
StephanTLavavej Feb 11, 2021
c06ac4c
Test change: Make soccc_allocator always equal, to meet the allocator…
StephanTLavavej Feb 11, 2021
2a6e8c9
fix silly typo
mnatsuhara Feb 16, 2021
9946f95
Silence Clang warning. MSVC_INTERNAL_TESTING is non-ugly.
StephanTLavavej Feb 17, 2021
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
787 changes: 447 additions & 340 deletions stl/inc/vector

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -1212,8 +1212,8 @@ private:

// MEMBER FUNCTIONS FOR _Container_base12
_CONSTEXPR20_CONTAINER void _Container_base12::_Orphan_all_unlocked() noexcept {
for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
(*_Pnext)->_Myproxy = nullptr;
for (auto& _Pnext = _Myproxy->_Myfirstiter; _Pnext; _Pnext = _Pnext->_Mynextiter) { // TRANSITION, VSO-1269037
_Pnext->_Myproxy = nullptr;
}
_Myproxy->_Myfirstiter = nullptr;
}
Expand Down
7 changes: 6 additions & 1 deletion stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
// P0919R3 Heterogeneous Lookup For Unordered Containers
// P0966R1 string::reserve() Should Not Shrink
// P1001R2 execution::unseq
// P1004R2 constexpr std::vector
// P1006R1 constexpr For pointer_traits<T*>::pointer_to()
// P1007R3 assume_aligned()
// P1020R1 Smart Pointer Creation With Default Initialization
Expand Down Expand Up @@ -1202,6 +1203,10 @@
#define __cpp_lib_constexpr_tuple 201811L
#define __cpp_lib_constexpr_utility 201811L

#if defined(__cpp_constexpr_dynamic_alloc) && !defined(__clang__) // TRANSITION, LLVM-48606
#define __cpp_lib_constexpr_vector 201907L
#endif // defined(__cpp_constexpr_dynamic_alloc) && !defined(__clang__)

#ifdef __cpp_impl_coroutine // TRANSITION, Clang coroutine support
#define __cpp_lib_coroutine 201902L
#endif // __cpp_impl_coroutine
Expand Down Expand Up @@ -1284,7 +1289,7 @@
#endif

// Functions that became constexpr in C++20 via P0980R1 or P1004R2
#if defined(__cpp_lib_constexpr_dynamic_alloc) && !defined(__clang__) // TRANSITION:LLVM-48606
#if defined(__cpp_lib_constexpr_dynamic_alloc) && !defined(__clang__) // TRANSITION, LLVM-48606
#define _CONSTEXPR20_CONTAINER constexpr
#else
#define _CONSTEXPR20_CONTAINER inline
Expand Down
16 changes: 13 additions & 3 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,6 @@ std/language.support/support.limits/support.limits.general/functional.version.pa
std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp FAIL
std/language.support/support.limits/support.limits.general/memory.version.pass.cpp FAIL

# C++20 P1004R2 "constexpr std::vector"
std/language.support/support.limits/support.limits.general/vector.version.pass.cpp FAIL

# C++20 P1614R2 "Adding Spaceship <=> To The Library"
std/language.support/support.limits/support.limits.general/compare.version.pass.cpp FAIL

Expand Down Expand Up @@ -373,6 +370,16 @@ std/utilities/utility/pairs/pairs.pair/assign_rv_pair_U_V.pass.cpp:0 FAIL
std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort.pass.cpp:0 FAIL
std/algorithms/alg.sorting/alg.sort/partial.sort/partial_sort_comp.pass.cpp:0 FAIL

# VSO-1275530 "[constexpr] Temporaries created for functions do not have a ctor called (and have a redundant dtor)."
std/numerics/numeric.ops/exclusive.scan/exclusive_scan.pass.cpp:0 FAIL
std/numerics/numeric.ops/exclusive.scan/exclusive_scan_init_op.pass.cpp:0 FAIL
std/numerics/numeric.ops/inclusive.scan/inclusive_scan.pass.cpp:0 FAIL
std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op.pass.cpp:0 FAIL
std/numerics/numeric.ops/inclusive.scan/inclusive_scan_op_init.pass.cpp:0 FAIL
std/numerics/numeric.ops/transform.exclusive.scan/transform_exclusive_scan_init_bop_uop.pass.cpp:0 FAIL
std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop.pass.cpp:0 FAIL
std/numerics/numeric.ops/transform.inclusive.scan/transform_inclusive_scan_bop_uop_init.pass.cpp:0 FAIL


# *** CLANG COMPILER BUGS ***
# LLVM-33230 "Clang on Windows should define __STDCPP_THREADS__ to be 1"
Expand All @@ -381,6 +388,9 @@ std/thread/macro.pass.cpp:1 FAIL
# LLVM-46207 Clang's tgmath.h interferes with the UCRT's tgmath.h
std/depr/depr.c.headers/tgmath_h.pass.cpp:1 FAIL

# LLVM-48606 "Clang rejects creation of struct with mutable member during constant evaluation"
std/language.support/support.limits/support.limits.general/vector.version.pass.cpp:1 FAIL


# *** CLANG ISSUES, NOT YET ANALYZED ***
# Clang doesn't enable sized deallocation by default. Should we add -fsized-deallocation or do something else?
Expand Down
16 changes: 13 additions & 3 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,6 @@ language.support\support.limits\support.limits.general\functional.version.pass.c
language.support\support.limits\support.limits.general\iterator.version.pass.cpp
language.support\support.limits\support.limits.general\memory.version.pass.cpp

# C++20 P1004R2 "constexpr std::vector"
language.support\support.limits\support.limits.general\vector.version.pass.cpp

# C++20 P1614R2 "Adding Spaceship <=> To The Library"
language.support\support.limits\support.limits.general\compare.version.pass.cpp

Expand Down Expand Up @@ -373,6 +370,16 @@ utilities\utility\pairs\pairs.pair\assign_rv_pair_U_V.pass.cpp
algorithms\alg.sorting\alg.sort\partial.sort\partial_sort.pass.cpp
algorithms\alg.sorting\alg.sort\partial.sort\partial_sort_comp.pass.cpp

# VSO-1275530 "[constexpr] Temporaries created for functions do not have a ctor called (and have a redundant dtor)."
numerics\numeric.ops\exclusive.scan\exclusive_scan.pass.cpp
numerics\numeric.ops\exclusive.scan\exclusive_scan_init_op.pass.cpp
numerics\numeric.ops\inclusive.scan\inclusive_scan.pass.cpp
numerics\numeric.ops\inclusive.scan\inclusive_scan_op.pass.cpp
numerics\numeric.ops\inclusive.scan\inclusive_scan_op_init.pass.cpp
numerics\numeric.ops\transform.exclusive.scan\transform_exclusive_scan_init_bop_uop.pass.cpp
numerics\numeric.ops\transform.inclusive.scan\transform_inclusive_scan_bop_uop.pass.cpp
numerics\numeric.ops\transform.inclusive.scan\transform_inclusive_scan_bop_uop_init.pass.cpp


# *** CLANG COMPILER BUGS ***
# LLVM-33230 "Clang on Windows should define __STDCPP_THREADS__ to be 1"
Expand All @@ -381,6 +388,9 @@ thread\macro.pass.cpp
# LLVM-46207 Clang's tgmath.h interferes with the UCRT's tgmath.h
depr\depr.c.headers\tgmath_h.pass.cpp

# LLVM-48606 "Clang rejects creation of struct with mutable member during constant evaluation"
language.support\support.limits\support.limits.general\vector.version.pass.cpp


# *** CLANG ISSUES, NOT YET ANALYZED ***
# Clang doesn't enable sized deallocation by default. Should we add -fsized-deallocation or do something else?
Expand Down
3 changes: 3 additions & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ tests\P0758R1_is_nothrow_convertible
tests\P0768R1_spaceship_cpos
tests\P0768R1_spaceship_operator
tests\P0769R2_shift_left_shift_right
tests\P0784R7_library_machinery
tests\P0784R7_library_support_for_more_constexpr_containers
tests\P0811R3_midpoint_lerp
tests\P0896R4_common_iterator
Expand Down Expand Up @@ -379,6 +380,8 @@ tests\P0898R3_identity
tests\P0912R5_coroutine
tests\P0919R3_heterogeneous_unordered_lookup
tests\P0966R1_string_reserve_should_not_shrink
tests\P1004R2_constexpr_vector
tests\P1004R2_constexpr_vector_bool
tests\P1007R3_assume_aligned
tests\P1020R1_smart_pointer_for_overwrite
tests\P1023R0_constexpr_for_array_comparisons
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ int main() {
assert(all_of(x.begin(), x.end(), is_false));
assert(all_of(y.begin(), y.end(), is_true));

#if !defined(__EDG__) || _ITERATOR_DEBUG_LEVEL != 2 // TRANSITION, VSO-1273381
swap(x[12], y[34]);

assert(all_of(x.begin(), x.begin() + 12, is_false));
Expand All @@ -26,4 +27,5 @@ int main() {
assert(all_of(y.begin(), y.begin() + 34, is_true));
assert(!y[34]);
assert(all_of(y.begin() + 35, y.end(), is_true));
#endif // !defined(__EDG__) || _ITERATOR_DEBUG_LEVEL != 2
}
4 changes: 4 additions & 0 deletions tests/std/tests/P0784R7_library_machinery/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_latest_matrix.lst
150 changes: 150 additions & 0 deletions tests/std/tests/P0784R7_library_machinery/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <algorithm>
#include <assert.h>
#include <iterator>
#include <memory>
#include <type_traits>
#include <utility>

#pragma warning(disable : 4582) // '%s': constructor is not implicitly called
#pragma warning(disable : 4583) // '%s': destructor is not implicitly called

using namespace std;

struct int_wrapper_copy {
constexpr int_wrapper_copy() = default;
constexpr int_wrapper_copy(const int v) : _val(v) {}

constexpr int_wrapper_copy(const int_wrapper_copy& other) : _val(other._val) {}
constexpr int_wrapper_copy& operator=(const int_wrapper_copy& other) {
_val = other._val;
return *this;
}

int_wrapper_copy(int_wrapper_copy&&) = delete;
int_wrapper_copy& operator=(int_wrapper_copy&&) = delete;

constexpr bool operator==(const int_wrapper_copy&) const = default;

int _val = 0;
};

struct int_wrapper_move {
constexpr int_wrapper_move() = default;
constexpr int_wrapper_move(const int v) : _val(v) {}

int_wrapper_move(const int_wrapper_move&) = delete;
int_wrapper_move& operator=(const int_wrapper_move&) = delete;

constexpr int_wrapper_move(int_wrapper_move&& other) : _val(exchange(other._val, -1)) {}
constexpr int_wrapper_move& operator=(int_wrapper_move&& other) {
_val = exchange(other._val, -1);
return *this;
}

constexpr bool operator==(const int_wrapper_move&) const = default;

int _val = 0;
};

static constexpr int_wrapper_copy expected_copy[] = {1, 2, 3, 4};
static constexpr int_wrapper_move expected_move[] = {1, 2, 3, 4};
static constexpr int_wrapper_move expected_after_move[] = {-1, -1, -1, -1};

_CONSTEXPR20_DYNALLOC bool test() {
{ // _Copy_unchecked
int_wrapper_copy input[] = {1, 2, 3, 4};
int_wrapper_copy output[4] = {5, 6, 7, 8};

const auto result = _Copy_unchecked(begin(input), end(input), begin(output));
static_assert(is_same_v<remove_const_t<decltype(result)>, int_wrapper_copy*>);
assert(result == end(output));
assert(equal(begin(expected_copy), end(expected_copy), begin(output), end(output)));
}

{ // _Copy_backward_unchecked
int_wrapper_copy input[] = {1, 2, 3, 4};
int_wrapper_copy output[4] = {5, 6, 7, 8};

const auto result = _Copy_backward_unchecked(begin(input), end(input), end(output));
static_assert(is_same_v<remove_const_t<decltype(result)>, int_wrapper_copy*>);
assert(result == begin(output));
assert(equal(begin(expected_copy), end(expected_copy), begin(output), end(output)));
}

#if defined(__cpp_constexpr_dynamic_alloc)
{ // _Uninitialized_copy_unchecked
int_wrapper_copy input[] = {1, 2, 3, 4};
int_wrapper_copy output[4];

const auto result = _Uninitialized_copy_unchecked(begin(input), end(input), begin(output));
static_assert(is_same_v<remove_const_t<decltype(result)>, int_wrapper_copy*>);
assert(result == end(output));
assert(equal(begin(expected_copy), end(expected_copy), begin(output), end(output)));
}
#endif // defined(__cpp_constexpr_dynamic_alloc)

{ // _Move_unchecked
int_wrapper_move input[] = {1, 2, 3, 4};
int_wrapper_move output[4] = {5, 6, 7, 8};

const auto result = _Move_unchecked(begin(input), end(input), begin(output));
static_assert(is_same_v<remove_const_t<decltype(result)>, int_wrapper_move*>);
assert(result == end(output));
assert(equal(begin(expected_move), end(expected_move), begin(output), end(output)));
if (is_constant_evaluated()) {
assert(equal(begin(input), end(input), begin(expected_after_move), end(expected_after_move)));
}
}

{ // _Move_backward_unchecked
int_wrapper_move input[] = {1, 2, 3, 4};
int_wrapper_move output[4] = {5, 6, 7, 8};

const auto result = _Move_backward_unchecked(begin(input), end(input), end(output));
static_assert(is_same_v<remove_const_t<decltype(result)>, int_wrapper_move*>);
assert(result == begin(output));
assert(equal(begin(expected_move), end(expected_move), begin(output), end(output)));
if (is_constant_evaluated()) {
assert(equal(begin(input), end(input), begin(expected_after_move), end(expected_after_move)));
}
}

#ifdef __cpp_lib_concepts
{ // _Move_backward_common
int_wrapper_move input[] = {1, 2, 3, 4};
int_wrapper_move output[4] = {5, 6, 7, 8};

const auto result = ranges::_Move_backward_common(begin(input), end(input), end(output));
static_assert(is_same_v<remove_const_t<decltype(result)>, int_wrapper_move*>);
assert(result == begin(output));
assert(equal(begin(expected_move), end(expected_move), begin(output), end(output)));
if (is_constant_evaluated()) {
assert(equal(begin(input), end(input), begin(expected_after_move), end(expected_after_move)));
}
}
#endif // __cpp_lib_concepts

#if defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) // TRANSITION, DevCom-1333853
{ // _Uninitialized_move_unchecked
int_wrapper_move input[] = {1, 2, 3, 4};
int_wrapper_move output[4];

const auto result = _Uninitialized_move_unchecked(begin(input), end(input), begin(output));
static_assert(is_same_v<remove_const_t<decltype(result)>, int_wrapper_move*>);
assert(result == end(output));
assert(equal(begin(expected_move), end(expected_move), begin(output), end(output)));
if (is_constant_evaluated()) {
assert(equal(begin(input), end(input), begin(expected_after_move), end(expected_after_move)));
}
}
#endif // defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__))
return true;
}

int main() {
test();
static_assert(test());
}
4 changes: 4 additions & 0 deletions tests/std/tests/P1004R2_constexpr_vector/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_latest_matrix.lst
Loading