Skip to content

Commit

Permalink
[P1004] Implement constexpr vector
Browse files Browse the repository at this point in the history
  • Loading branch information
miscco committed Dec 21, 2020
1 parent 541f0d7 commit a0ad381
Show file tree
Hide file tree
Showing 10 changed files with 1,984 additions and 412 deletions.
1,047 changes: 637 additions & 410 deletions stl/inc/vector

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2249,7 +2249,8 @@ _NODISCARD _CONSTEXPR20 _FwdIt remove_if(_FwdIt _First, const _FwdIt _Last, _Pr

// FUNCTION TEMPLATE _Erase_remove
template <class _Container, class _Uty>
typename _Container::size_type _Erase_remove(_Container& _Cont, const _Uty& _Val) { // erase each element matching _Val
_CONSTEXPR20_DYNALLOC typename _Container::size_type _Erase_remove(_Container& _Cont, const _Uty& _Val) {
// erase each element matching _Val
auto _First = _Cont.begin();
const auto _Last = _Cont.end();
const auto _Old_size = _Cont.size();
Expand All @@ -2260,7 +2261,8 @@ typename _Container::size_type _Erase_remove(_Container& _Cont, const _Uty& _Val

// FUNCTION TEMPLATE _Erase_remove_if
template <class _Container, class _Pr>
typename _Container::size_type _Erase_remove_if(_Container& _Cont, _Pr _Pred) { // erase each element satisfying _Pred
_CONSTEXPR20_DYNALLOC typename _Container::size_type _Erase_remove_if(_Container& _Cont, _Pr _Pred) {
// erase each element satisfying _Pred
auto _First = _Cont.begin();
const auto _Last = _Cont.end();
const auto _Old_size = _Cont.size();
Expand Down
5 changes: 5 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,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 @@ -1204,6 +1205,10 @@
#define __cpp_lib_constexpr_tuple 201811L
#define __cpp_lib_constexpr_utility 201811L

#if defined(__cpp_constexpr_dynamic_alloc) && defined(__clang__) // TRANSITION, ADO1256891, ADO1256895
#define __cpp_lib_constexpr_vector 201907L
#endif // __cpp_constexpr_dynamic_alloc && __clang__

#ifdef __cpp_impl_coroutine // TRANSITION, Clang coroutine support
#define __cpp_lib_coroutine 201902L
#endif // __cpp_impl_coroutine
Expand Down
3 changes: 3 additions & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,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 @@ -368,6 +369,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
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
147 changes: 147 additions & 0 deletions tests/std/tests/P0784R7_library_machinery/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <algorithm>
#include <assert.h>
#include <memory>

#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;
}

constexpr int_wrapper_copy(int_wrapper_copy&&) = delete;
constexpr 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){};

constexpr int_wrapper_move(const int_wrapper_move&) = delete;
constexpr 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};

constexpr 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 _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && defined(__clang__)
{ // _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 // _HAS_CXX20 && 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 _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && defined(__clang__)
{ // _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 // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc)
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

0 comments on commit a0ad381

Please sign in to comment.