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 Nov 20, 2020
1 parent 19c683d commit dc7a7f4
Show file tree
Hide file tree
Showing 12 changed files with 2,059 additions and 526 deletions.
707 changes: 391 additions & 316 deletions stl/inc/vector

Large diffs are not rendered by default.

521 changes: 323 additions & 198 deletions stl/inc/xmemory

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct _Get_rebind_alias<_Ty, _Other, void_t<typename _Ty::template rebind<_Othe

// FUNCTION TEMPLATE _Voidify_iter
template <class _Iter>
_NODISCARD void* _Voidify_iter(_Iter _It) noexcept {
_NODISCARD _CONSTEXPR20_DYNALLOC void* _Voidify_iter(_Iter _It) noexcept {
#if _HAS_IF_CONSTEXPR
if constexpr (is_pointer_v<_Iter>) {
return const_cast<void*>(static_cast<const volatile void*>(_It));
Expand All @@ -134,13 +134,14 @@ _NODISCARD void* _Voidify_iter(_Iter _It) noexcept {

// 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...>) {
_CONSTEXPR20_DYNALLOC 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)...);
}

// FUNCTION TEMPLATE _Default_construct_in_place
template <class _Ty>
void _Default_construct_in_place(_Ty& _Obj) noexcept(is_nothrow_default_constructible_v<_Ty>) {
_CONSTEXPR20_DYNALLOC void _Default_construct_in_place(_Ty& _Obj) noexcept(is_nothrow_default_constructible_v<_Ty>) {
::new (_Voidify_iter(_STD addressof(_Obj))) _Ty;
}

Expand Down
9 changes: 7 additions & 2 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 @@ -546,11 +547,11 @@
#endif // ^^^ inline (not constexpr) in C++17 and earlier ^^^

// Functions that became constexpr in C++20 via P0784R7
#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc)
#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && defined(__clang__)
#define _CONSTEXPR20_DYNALLOC constexpr
#else
#define _CONSTEXPR20_DYNALLOC inline
#endif
#endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && defined(__clang__)

// P0607R0 Inline Variables For The STL
#if _HAS_CXX17
Expand Down Expand Up @@ -1184,6 +1185,10 @@
#define __cpp_lib_constexpr_tuple 201811L
#define __cpp_lib_constexpr_utility 201811L

#if defined(__cpp_constexpr_dynamic_alloc) && defined(__clang__)
#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
13 changes: 6 additions & 7 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -493,15 +493,14 @@ std/utilities/variant/variant.variant/variant.ctor/conv.pass.cpp FAIL
std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp FAIL

# C++20 P0784R7 "More constexpr containers"
std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp FAIL
std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp FAIL
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 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 FAIL
std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp FAIL
std/utilities/memory/default.allocator/allocator.globals/eq.pass.cpp FAIL
std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp:1 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 FAIL
std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp FAIL
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 dc7a7f4

Please sign in to comment.