Skip to content

Commit 22903da

Browse files
committed
[libc++] Implement std::inplace_vector<T, N>
1 parent b6603e1 commit 22903da

File tree

93 files changed

+7227
-16
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+7227
-16
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ Status
440440
---------------------------------------------------------- -----------------
441441
``__cpp_lib_hazard_pointer`` *unimplemented*
442442
---------------------------------------------------------- -----------------
443-
``__cpp_lib_inplace_vector`` *unimplemented*
443+
``__cpp_lib_inplace_vector`` ``202406L``
444444
---------------------------------------------------------- -----------------
445445
``__cpp_lib_is_virtual_base_of`` *unimplemented*
446446
---------------------------------------------------------- -----------------

libcxx/docs/Status/Cxx2cPapers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
"`P3168R2 <https://wg21.link/P3168R2>`__","Give ``std::optional`` Range Support","2024-06 (St. Louis)","","","|ranges|"
7070
"`P3217R0 <https://wg21.link/P3217R0>`__","Adjoints to 'Enabling list-initialization for algorithms': find_last","2024-06 (St. Louis)","","",""
7171
"`P2985R0 <https://wg21.link/P2985R0>`__","A type trait for detecting virtual base classes","2024-06 (St. Louis)","","",""
72-
"`P0843R14 <https://wg21.link/P0843R14>`__","``inplace_vector``","2024-06 (St. Louis)","","",""
72+
"`P0843R14 <https://wg21.link/P0843R14>`__","``inplace_vector``","2024-06 (St. Louis)","|Complete|","20.0",""
7373
"`P3235R3 <https://wg21.link/P3235R3>`__","``std::print`` more types faster with less memory","2024-06 (St. Louis)","","","|format| |DR|"
7474
"`P2968R2 <https://wg21.link/P2968R2>`__","Make ``std::ignore`` a first-class object","2024-06 (St. Louis)","|Complete|","19.0",""
7575
"`P2075R6 <https://wg21.link/P2075R6>`__","Philox as an extension of the C++ RNG engines","2024-06 (St. Louis)","","",""

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,7 @@ set(files
947947
functional
948948
future
949949
initializer_list
950+
inplace_vector
950951
inttypes.h
951952
iomanip
952953
ios

libcxx/include/__configuration/abi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@
134134
//
135135
// Supported containers:
136136
// - `span`;
137-
// - `string_view`.
137+
// - `string_view`;
138+
// - `inplace_vector`.
138139
// #define _LIBCPP_ABI_BOUNDED_ITERATORS
139140

140141
// Changes the iterator type of `basic_string` to a bounded iterator that keeps track of whether it's within the bounds

libcxx/include/__iterator/wrap_iter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ class __wrap_iter {
107107
friend class _LIBCPP_TEMPLATE_VIS span;
108108
template <class _Tp, size_t _Size>
109109
friend struct array;
110+
#if _LIBCPP_STD_VER >= 26
111+
template <class _Tp, size_t _Capacity>
112+
friend class inplace_vector;
113+
#endif
110114
};
111115

112116
template <class _Iter1>

libcxx/include/inplace_vector

Lines changed: 1077 additions & 0 deletions
Large diffs are not rendered by default.

libcxx/include/module.modulemap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ module std_initializer_list [system] {
103103
header "initializer_list"
104104
export *
105105
}
106+
module std_inplace_vector [system] {
107+
header "inplace_vector"
108+
export *
109+
}
106110
module std_iomanip [system] {
107111
header "iomanip"
108112
export *

libcxx/include/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ __cpp_lib_void_t 201411L <type_traits>
530530
// # define __cpp_lib_function_ref 202306L
531531
// # define __cpp_lib_generate_random 202403L
532532
// # define __cpp_lib_hazard_pointer 202306L
533-
// # define __cpp_lib_inplace_vector 202406L
533+
# define __cpp_lib_inplace_vector 202406L
534534
// # define __cpp_lib_is_virtual_base_of 202406L
535535
// # define __cpp_lib_is_within_lifetime 202306L
536536
// # define __cpp_lib_linalg 202311L
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
9+
10+
// <vector>
11+
12+
// reference operator[](size_type __i);
13+
// const_reference operator[](size_type __i) const;
14+
//
15+
// reference at(size_type __i);
16+
// const_reference at(size_type __i) const;
17+
//
18+
// reference front();
19+
// const_reference front() const;
20+
//
21+
// reference back();
22+
// const_reference back() const;
23+
// libc++ marks these as 'noexcept' (except 'at')
24+
25+
#include <vector>
26+
#include <cassert>
27+
#include <stdexcept>
28+
29+
#include "min_allocator.h"
30+
#include "test_macros.h"
31+
32+
template <class C>
33+
TEST_CONSTEXPR_CXX20 C make(int size, int start) {
34+
C c;
35+
for (int i = 0; i < size; ++i)
36+
c.push_back(start + i);
37+
return c;
38+
}
39+
40+
template <class Vector>
41+
TEST_CONSTEXPR_CXX20 void test_get_basic(Vector& c, int start_value) {
42+
const int n = static_cast<int>(c.size());
43+
for (int i = 0; i < n; ++i)
44+
assert(c[i] == start_value + i);
45+
for (int i = 0; i < n; ++i)
46+
assert(c.at(i) == start_value + i);
47+
48+
#ifndef TEST_HAS_NO_EXCEPTIONS
49+
if !consteval {
50+
try {
51+
TEST_IGNORE_NODISCARD c.at(n);
52+
assert(false);
53+
} catch (const std::out_of_range&) {
54+
}
55+
}
56+
#endif
57+
58+
assert(c.front() == start_value);
59+
assert(c.back() == start_value + n - 1);
60+
}
61+
62+
template <class Vector>
63+
TEST_CONSTEXPR_CXX20 void test_get() {
64+
int start_value = 35;
65+
Vector c = make<Vector>(10, start_value);
66+
const Vector& cc = c;
67+
test_get_basic(c, start_value);
68+
test_get_basic(cc, start_value);
69+
}
70+
71+
template <class Vector>
72+
TEST_CONSTEXPR_CXX20 void test_set() {
73+
int start_value = 35;
74+
const int n = 10;
75+
Vector c = make<Vector>(n, start_value);
76+
77+
for (int i = 0; i < n; ++i) {
78+
assert(c[i] == start_value + i);
79+
c[i] = start_value + i + 1;
80+
assert(c[i] == start_value + i + 1);
81+
}
82+
for (int i = 0; i < n; ++i) {
83+
assert(c.at(i) == start_value + i + 1);
84+
c.at(i) = start_value + i + 2;
85+
assert(c.at(i) == start_value + i + 2);
86+
}
87+
88+
assert(c.front() == start_value + 2);
89+
c.front() = start_value + 3;
90+
assert(c.front() == start_value + 3);
91+
92+
assert(c.back() == start_value + n + 1);
93+
c.back() = start_value + n + 2;
94+
assert(c.back() == start_value + n + 2);
95+
}
96+
97+
template <class Vector>
98+
TEST_CONSTEXPR_CXX20 void test() {
99+
test_get<Vector>();
100+
test_set<Vector>();
101+
102+
Vector c;
103+
const Vector& cc = c;
104+
ASSERT_SAME_TYPE(typename Vector::reference, decltype(c[0]));
105+
ASSERT_SAME_TYPE(typename Vector::const_reference, decltype(cc[0]));
106+
107+
ASSERT_SAME_TYPE(typename Vector::reference, decltype(c.at(0)));
108+
ASSERT_SAME_TYPE(typename Vector::const_reference, decltype(cc.at(0)));
109+
110+
ASSERT_SAME_TYPE(typename Vector::reference, decltype(c.front()));
111+
ASSERT_SAME_TYPE(typename Vector::const_reference, decltype(cc.front()));
112+
113+
ASSERT_SAME_TYPE(typename Vector::reference, decltype(c.back()));
114+
ASSERT_SAME_TYPE(typename Vector::const_reference, decltype(cc.back()));
115+
}
116+
117+
TEST_CONSTEXPR_CXX20 bool tests() {
118+
test<std::vector<int> >();
119+
#if TEST_STD_VER >= 11
120+
test<std::vector<int, min_allocator<int> > >();
121+
test<std::vector<int, safe_allocator<int> > >();
122+
#endif
123+
return true;
124+
}
125+
126+
int main(int, char**) {
127+
tests();
128+
#if TEST_STD_VER > 17
129+
static_assert(tests());
130+
#endif
131+
return 0;
132+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// <vector>
10+
11+
// bool operator==(const vector& lhs, const vector& rhs);
12+
// bool operator!=(const vector& lhs, const vector& rhs);
13+
// bool operator< (const vector& lhs, const vector& rhs);
14+
// bool operator<=(const vector& lhs, const vector& rhs);
15+
// bool operator> (const vector& lhs, const vector& rhs);
16+
// bool operator>=(const vector& lhs, const vector& rhs);
17+
18+
#include <vector>
19+
#include <cassert>
20+
21+
#include "test_comparisons.h"
22+
23+
TEST_CONSTEXPR_CXX20 bool test() {
24+
{
25+
const std::vector<int> c1, c2;
26+
assert(testComparisons(c1, c2, true, false));
27+
}
28+
{
29+
const std::vector<int> c1(1, 1), c2(1, 2);
30+
assert(testComparisons(c1, c2, false, true));
31+
}
32+
{
33+
const std::vector<int> c1, c2(1, 2);
34+
assert(testComparisons(c1, c2, false, true));
35+
}
36+
{
37+
int items1[3] = {1, 2, 1};
38+
int items2[3] = {1, 2, 2};
39+
const std::vector<int> c1(items1, items1 + 3);
40+
const std::vector<int> c2(items2, items2 + 3);
41+
assert(testComparisons(c1, c2, false, true));
42+
}
43+
{
44+
int items1[3] = {3, 2, 3};
45+
int items2[3] = {3, 1, 3};
46+
const std::vector<int> c1(items1, items1 + 3);
47+
const std::vector<int> c2(items2, items2 + 3);
48+
49+
assert(testComparisons(c1, c2, false, false));
50+
}
51+
{
52+
int items1[2] = {1, 2};
53+
int items2[3] = {1, 2, 0};
54+
const std::vector<int> c1(items1, items1 + 2);
55+
const std::vector<int> c2(items2, items2 + 3);
56+
assert(testComparisons(c1, c2, false, true));
57+
}
58+
{
59+
int items1[3] = {1, 2, 0};
60+
const std::vector<int> c1(items1, items1 + 3);
61+
const std::vector<int> c2(1, 3);
62+
assert(testComparisons(c1, c2, false, true));
63+
}
64+
{
65+
const std::vector<LessAndEqComp> c1, c2;
66+
assert(testComparisons(c1, c2, true, false));
67+
}
68+
{
69+
const std::vector<LessAndEqComp> c1(1, LessAndEqComp(1));
70+
const std::vector<LessAndEqComp> c2(1, LessAndEqComp(1));
71+
assert(testComparisons(c1, c2, true, false));
72+
}
73+
{
74+
const std::vector<LessAndEqComp> c1(1, LessAndEqComp(1));
75+
const std::vector<LessAndEqComp> c2(1, LessAndEqComp(2));
76+
assert(testComparisons(c1, c2, false, true));
77+
}
78+
{
79+
const std::vector<LessAndEqComp> c1;
80+
const std::vector<LessAndEqComp> c2(1, LessAndEqComp(2));
81+
assert(testComparisons(c1, c2, false, true));
82+
}
83+
{
84+
LessAndEqComp items1[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(2)};
85+
LessAndEqComp items2[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(1)};
86+
const std::vector<LessAndEqComp> c1(items1, items1 + 3);
87+
const std::vector<LessAndEqComp> c2(items2, items2 + 3);
88+
assert(testComparisons(c1, c2, false, false));
89+
}
90+
{
91+
LessAndEqComp items1[3] = {LessAndEqComp(3), LessAndEqComp(3), LessAndEqComp(3)};
92+
LessAndEqComp items2[3] = {LessAndEqComp(3), LessAndEqComp(2), LessAndEqComp(3)};
93+
const std::vector<LessAndEqComp> c1(items1, items1 + 3);
94+
const std::vector<LessAndEqComp> c2(items2, items2 + 3);
95+
assert(testComparisons(c1, c2, false, false));
96+
}
97+
{
98+
LessAndEqComp items1[2] = {LessAndEqComp(1), LessAndEqComp(2)};
99+
LessAndEqComp items2[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(0)};
100+
const std::vector<LessAndEqComp> c1(items1, items1 + 2);
101+
const std::vector<LessAndEqComp> c2(items2, items2 + 3);
102+
assert(testComparisons(c1, c2, false, true));
103+
}
104+
{
105+
LessAndEqComp items1[3] = {LessAndEqComp(1), LessAndEqComp(2), LessAndEqComp(0)};
106+
const std::vector<LessAndEqComp> c1(items1, items1 + 3);
107+
const std::vector<LessAndEqComp> c2(1, LessAndEqComp(3));
108+
assert(testComparisons(c1, c2, false, true));
109+
}
110+
{
111+
assert((std::vector<int>() == std::vector<int>()));
112+
assert(!(std::vector<int>() != std::vector<int>()));
113+
assert(!(std::vector<int>() < std::vector<int>()));
114+
assert((std::vector<int>() <= std::vector<int>()));
115+
assert(!(std::vector<int>() > std::vector<int>()));
116+
assert((std::vector<int>() >= std::vector<int>()));
117+
}
118+
119+
return true;
120+
}
121+
122+
int main(int, char**) {
123+
test();
124+
#if TEST_STD_VER > 17
125+
static_assert(test());
126+
#endif
127+
128+
return 0;
129+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
9+
10+
// <inplace_vector>
11+
12+
// class inplace_vector
13+
14+
// constexpr auto operator<=>(const inplace_vector& x,
15+
// const inplace_vector& y);
16+
17+
// FIXME: check if the auto is valid
18+
19+
#include <cassert>
20+
#include <inplace_vector>
21+
22+
#include "test_container_comparisons.h"
23+
24+
template <typename T>
25+
using inplace_vector_size_10 = std::inplace_vector<T, 10>;
26+
27+
// TODO: test inplace_vector<T, 0> still has a valid definition
28+
// TODO: modify so that the checks work in constexpr
29+
30+
int main(int, char**) {
31+
assert(test_sequence_container_spaceship<inplace_vector_size_10>());
32+
// static_assert(test_sequence_container_spaceship<inplace_vector_size_10>());
33+
return 0;
34+
}

0 commit comments

Comments
 (0)