Skip to content

Commit c07440b

Browse files
authored
[libc++] constexpr flat_multiset (llvm#161016)
Fixes llvm#128676
1 parent 8484584 commit c07440b

File tree

69 files changed

+1317
-497
lines changed

Some content is hidden

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

69 files changed

+1317
-497
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ Status
426426
---------------------------------------------------------- -----------------
427427
``__cpp_lib_constexpr_algorithms`` ``202306L``
428428
---------------------------------------------------------- -----------------
429+
``__cpp_lib_constexpr_flat_map`` ``202502L``
430+
---------------------------------------------------------- -----------------
431+
``__cpp_lib_constexpr_flat_set`` ``202502L``
432+
---------------------------------------------------------- -----------------
429433
``__cpp_lib_constexpr_forward_list`` ``202502L``
430434
---------------------------------------------------------- -----------------
431435
``__cpp_lib_constexpr_list`` ``202502L``

libcxx/include/__flat_set/flat_multiset.h

Lines changed: 164 additions & 108 deletions
Large diffs are not rendered by default.

libcxx/include/version

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ __cpp_lib_constexpr_charconv 202207L <charconv>
7171
__cpp_lib_constexpr_cmath 202202L <cmath> <cstdlib>
7272
__cpp_lib_constexpr_complex 201711L <complex>
7373
__cpp_lib_constexpr_dynamic_alloc 201907L <memory>
74+
__cpp_lib_constexpr_flat_map 202502L <flat_map>
75+
__cpp_lib_constexpr_flat_set 202502L <flat_set>
7476
__cpp_lib_constexpr_forward_list 202502L <forward_list>
7577
__cpp_lib_constexpr_functional 201907L <functional>
7678
__cpp_lib_constexpr_iterator 201811L <iterator>
@@ -552,6 +554,8 @@ __cpp_lib_void_t 201411L <type_traits>
552554
# define __cpp_lib_bitset 202306L
553555
# undef __cpp_lib_constexpr_algorithms
554556
# define __cpp_lib_constexpr_algorithms 202306L
557+
# define __cpp_lib_constexpr_flat_map 202502L
558+
# define __cpp_lib_constexpr_flat_set 202502L
555559
# define __cpp_lib_constexpr_forward_list 202502L
556560
# define __cpp_lib_constexpr_list 202502L
557561
# if !defined(_LIBCPP_ABI_VCRUNTIME)

libcxx/test/libcxx/containers/container.adaptors/flat.multiset/insert.temporary.pass.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "../flat_helpers.h"
2222
#include "test_macros.h"
2323

24-
bool test() {
24+
constexpr bool test() {
2525
using M = std::flat_multiset<TrackCopyMove>;
2626
{
2727
M m;
@@ -43,6 +43,9 @@ bool test() {
4343

4444
int main(int, char**) {
4545
test();
46+
#if TEST_STD_VER >= 26
47+
static_assert(test());
48+
#endif
4649

4750
return 0;
4851
}

libcxx/test/libcxx/containers/container.adaptors/flat.multiset/insert_range.pass.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,36 @@
2020
#include <cassert>
2121
#include <flat_set>
2222
#include <ranges>
23-
#include <sstream>
2423
#include <vector>
2524

2625
#include "../flat_helpers.h"
26+
#include "test_iterators.h"
2727
#include "test_macros.h"
2828

29-
void test() {
29+
constexpr bool test() {
3030
NotQuiteSequenceContainer<int> v;
3131
std::flat_multiset s(v);
32-
std::istringstream ints("0 1 1 0");
33-
auto r = std::ranges::subrange(std::istream_iterator<int>(ints), std::istream_iterator<int>()) |
34-
std::views::transform([](int i) { return i * i; });
32+
33+
int ar[] = {0, 1, 1, 0};
34+
using Iter = cpp20_input_iterator<const int*>;
35+
using Sent = sentinel_wrapper<Iter>;
36+
using R = std::ranges::subrange<Iter, Sent>;
37+
auto r = R(Iter(ar), Sent(Iter(ar + 4)));
38+
3539
static_assert(
3640
![](auto& t) { return requires { t.insert_range(t.end(), r); }; }(v),
3741
"This test is to test the case where the underlying container does not provide insert_range");
3842
s.insert_range(r);
3943
assert(std::ranges::equal(s, std::vector<int>{0, 0, 1, 1}));
44+
45+
return true;
4046
}
4147

4248
int main(int, char**) {
4349
test();
50+
#if TEST_STD_VER >= 26
51+
static_assert(test());
52+
#endif
4453

4554
return 0;
4655
}

libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/empty.pass.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "min_allocator.h"
2525

2626
template <class KeyContainer>
27-
void test_one() {
27+
constexpr void test_one() {
2828
using Key = typename KeyContainer::value_type;
2929
using M = std::flat_multiset<Key, std::less<int>, KeyContainer>;
3030
M m;
@@ -38,15 +38,23 @@ void test_one() {
3838
assert(m.empty());
3939
}
4040

41-
void test() {
41+
constexpr bool test() {
4242
test_one<std::vector<int>>();
43-
test_one<std::deque<int>>();
43+
#ifndef __cpp_lib_constexpr_deque
44+
if (!TEST_IS_CONSTANT_EVALUATED)
45+
#endif
46+
test_one<std::deque<int>>();
4447
test_one<MinSequenceContainer<int>>();
4548
test_one<std::vector<int, min_allocator<int>>>();
49+
50+
return true;
4651
}
4752

4853
int main(int, char**) {
4954
test();
55+
#if TEST_STD_VER >= 26
56+
static_assert(test());
57+
#endif
5058

5159
return 0;
5260
}

libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/max_size.pass.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "test_allocator.h"
2525
#include "test_macros.h"
2626

27-
void test() {
27+
constexpr bool test() {
2828
{
2929
using A1 = limited_allocator<int, 10>;
3030
using C = std::flat_multiset<int, std::less<int>, std::vector<int, A1>>;
@@ -59,10 +59,15 @@ void test() {
5959
assert(c.max_size() <= max_dist);
6060
assert(c.max_size() <= alloc_max_size(std::allocator<char>()));
6161
}
62+
63+
return true;
6264
}
6365

6466
int main(int, char**) {
6567
test();
68+
#if TEST_STD_VER >= 26
69+
static_assert(test());
70+
#endif
6671

6772
return 0;
6873
}

libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/size.pass.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
//===----------------------------------------------------------------------===//
88

99
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=200000000
11+
// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=800000000
1012

1113
// <flat_set>
1214

@@ -23,7 +25,7 @@
2325
#include "min_allocator.h"
2426

2527
template <class KeyContainer>
26-
void test_one() {
28+
constexpr void test_one() {
2729
using M = std::flat_multiset<int, std::less<int>, KeyContainer>;
2830
using S = typename M::size_type;
2931
{
@@ -46,7 +48,7 @@ void test_one() {
4648
}
4749
{
4850
M m;
49-
S s = 500000;
51+
S s = 5000;
5052
for (std::size_t i = 0u; i < s; ++i) {
5153
m.emplace(i);
5254
m.emplace(i);
@@ -57,15 +59,23 @@ void test_one() {
5759
}
5860
}
5961

60-
void test() {
62+
constexpr bool test() {
6163
test_one<std::vector<int>>();
62-
test_one<std::deque<int>>();
64+
#ifndef __cpp_lib_constexpr_deque
65+
if (!TEST_IS_CONSTANT_EVALUATED)
66+
#endif
67+
test_one<std::deque<int>>();
6368
test_one<MinSequenceContainer<int>>();
6469
test_one<std::vector<int, min_allocator<int>>>();
70+
71+
return true;
6572
}
6673

6774
int main(int, char**) {
6875
test();
76+
#if TEST_STD_VER >= 26
77+
static_assert(test());
78+
#endif
6979

7080
return 0;
7181
}

libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/alloc.pass.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// explicit flat_multiset(const Allocator& a);
1515

1616
#include <cassert>
17+
#include <deque>
1718
#include <flat_set>
1819
#include <functional>
1920
#include <vector>
@@ -22,42 +23,56 @@
2223
#include "test_allocator.h"
2324
#include "../../../test_compare.h"
2425

25-
void test() {
26+
template <template <class...> class KeyContainer>
27+
constexpr void test() {
2628
{
2729
// The constructors in this subclause shall not participate in overload
2830
// resolution unless uses_allocator_v<container_type, Alloc> is true
2931

3032
using C = test_less<int>;
3133
using A1 = test_allocator<int>;
3234
using A2 = other_allocator<int>;
33-
using V1 = std::vector<int, A1>;
34-
using V2 = std::vector<int, A2>;
35+
using V1 = KeyContainer<int, A1>;
36+
using V2 = KeyContainer<int, A2>;
3537
using M1 = std::flat_multiset<int, C, V1>;
3638
using M2 = std::flat_multiset<int, C, V2>;
3739
static_assert(std::is_constructible_v<M1, const A1&>);
3840
static_assert(std::is_constructible_v<M2, const A2&>);
3941
static_assert(!std::is_constructible_v<M1, const A2&>);
4042
static_assert(!std::is_constructible_v<M2, const A1&>);
4143
}
42-
{
43-
// explicit
44-
using M = std::flat_multiset<int, std::less<int>, std::vector<int, test_allocator<int>>>;
45-
46-
static_assert(std::is_constructible_v<M, test_allocator<int>>);
47-
static_assert(!std::is_convertible_v<test_allocator<int>, M>);
48-
}
4944
{
5045
using A = test_allocator<short>;
51-
using M = std::flat_multiset<int, std::less<int>, std::vector<int, test_allocator<int>>>;
46+
using M = std::flat_multiset<int, std::less<int>, KeyContainer<int, test_allocator<int>>>;
5247
M m(A(0, 5));
5348
assert(m.empty());
5449
assert(m.begin() == m.end());
5550
assert(std::move(m).extract().get_allocator().get_id() == 5);
5651
}
52+
{
53+
// explicit
54+
using M = std::flat_multiset<int, std::less<int>, KeyContainer<int, test_allocator<int>>>;
55+
56+
static_assert(std::is_constructible_v<M, test_allocator<int>>);
57+
static_assert(!std::is_convertible_v<test_allocator<int>, M>);
58+
}
59+
}
60+
61+
constexpr bool test() {
62+
test<std::vector>();
63+
#ifndef __cpp_lib_constexpr_deque
64+
if (!TEST_IS_CONSTANT_EVALUATED)
65+
#endif
66+
test<std::deque>();
67+
68+
return true;
5769
}
5870

5971
int main(int, char**) {
6072
test();
73+
#if TEST_STD_VER >= 26
74+
static_assert(test());
75+
#endif
6176

6277
return 0;
6378
}

libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/assign_initializer_list.pass.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "test_allocator.h"
2727

2828
template <class KeyContainer>
29-
void test() {
29+
constexpr void test() {
3030
using Key = typename KeyContainer::value_type;
3131
using M = std::flat_multiset<Key, std::less<Key>, KeyContainer>;
3232
{
@@ -53,16 +53,24 @@ void test() {
5353
}
5454
}
5555

56-
void test() {
56+
constexpr bool test() {
5757
test<std::vector<int>>();
5858
test<std::vector<double>>();
59-
test<std::deque<int>>();
59+
#ifndef __cpp_lib_constexpr_deque
60+
if (!TEST_IS_CONSTANT_EVALUATED)
61+
#endif
62+
test<std::deque<int>>();
6063
test<MinSequenceContainer<int>>();
6164
test<std::vector<int, min_allocator<int>>>();
65+
66+
return true;
6267
}
6368

6469
int main(int, char**) {
6570
test();
71+
#if TEST_STD_VER >= 26
72+
static_assert(test());
73+
#endif
6674

6775
return 0;
6876
}

0 commit comments

Comments
 (0)