Skip to content

Commit 001b381

Browse files
committed
[libc++] constexpr flat_multimap
1 parent bdc0119 commit 001b381

File tree

65 files changed

+2426
-1073
lines changed

Some content is hidden

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

65 files changed

+2426
-1073
lines changed

libcxx/include/__flat_map/flat_multimap.h

Lines changed: 210 additions & 145 deletions
Large diffs are not rendered by default.

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

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

2828
template <class KeyContainer, class ValueContainer>
29-
void test() {
29+
constexpr void test() {
3030
using Key = typename KeyContainer::value_type;
3131
using Value = typename ValueContainer::value_type;
3232
using M = std::flat_multimap<Key, Value, std::less<int>, KeyContainer, ValueContainer>;
@@ -41,11 +41,23 @@ void test() {
4141
assert(m.empty());
4242
}
4343

44-
int main(int, char**) {
44+
constexpr bool test() {
4545
test<std::vector<int>, std::vector<double>>();
46-
test<std::deque<int>, std::vector<double>>();
46+
#ifndef __cpp_lib_constexpr_deque
47+
if (!TEST_IS_CONSTANT_EVALUATED)
48+
#endif
49+
test<std::deque<int>, std::vector<double>>();
4750
test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
4851
test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
4952

53+
return true;
54+
}
55+
56+
int main(int, char**) {
57+
test();
58+
#if TEST_STD_VER >= 26
59+
static_assert(test());
60+
#endif
61+
5062
return 0;
5163
}

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

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

29-
int main(int, char**) {
29+
constexpr bool test() {
3030
{
3131
using A1 = limited_allocator<int, 10>;
3232
using A2 = limited_allocator<int, 20>;
@@ -74,5 +74,15 @@ int main(int, char**) {
7474
assert(c.max_size() <= max_dist);
7575
assert(c.max_size() <= alloc_max_size(std::allocator<char>()));
7676
}
77+
78+
return true;
79+
}
80+
81+
int main(int, char**) {
82+
test();
83+
#if TEST_STD_VER >= 26
84+
static_assert(test());
85+
#endif
86+
7787
return 0;
7888
}

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "min_allocator.h"
2626

2727
template <class KeyContainer, class ValueContainer>
28-
void test() {
28+
constexpr void test() {
2929
using M = std::flat_multimap<int, char, std::less<int>, KeyContainer, ValueContainer>;
3030
{
3131
const M m = {{1, 'a'}, {1, 'b'}, {4, 'd'}, {5, 'e'}, {5, 'h'}};
@@ -47,7 +47,7 @@ void test() {
4747
}
4848
{
4949
M m;
50-
std::size_t s = 1000;
50+
std::size_t s = TEST_IS_CONSTANT_EVALUATED ? 100 : 1000;
5151
for (auto i = 0u; i < s; ++i) {
5252
m.emplace(i, 'a');
5353
}
@@ -60,11 +60,22 @@ void test() {
6060
}
6161
}
6262

63-
int main(int, char**) {
63+
constexpr bool test() {
6464
test<std::vector<int>, std::vector<char>>();
65-
test<std::deque<int>, std::vector<char>>();
65+
#ifndef __cpp_lib_constexpr_deque
66+
if (!TEST_IS_CONSTANT_EVALUATED)
67+
#endif
68+
test<std::deque<int>, std::vector<char>>();
6669
test<MinSequenceContainer<int>, MinSequenceContainer<char>>();
6770
test<std::vector<int, min_allocator<int>>, std::vector<char, min_allocator<char>>>();
71+
return true;
72+
}
73+
74+
int main(int, char**) {
75+
test();
76+
#if TEST_STD_VER >= 26
77+
static_assert(test());
78+
#endif
6879

6980
return 0;
7081
}

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

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88

99
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
1010

11-
// <flat_map>
11+
// <flat_multimap>
1212

1313
// template<class Allocator>
1414
// explicit flat_multimap(const Allocator& a);
1515

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

25-
int main(int, char**) {
26+
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
27+
constexpr void test() {
28+
using A = test_allocator<short>;
29+
using M =
30+
std::flat_multimap<int,
31+
long,
32+
std::less<int>,
33+
KeyContainer<int, test_allocator<int>>,
34+
ValueContainer<long, test_allocator<long>>>;
35+
M m(A(0, 5));
36+
assert(m.empty());
37+
assert(m.begin() == m.end());
38+
assert(m.keys().get_allocator().get_id() == 5);
39+
assert(m.values().get_allocator().get_id() == 5);
40+
}
41+
42+
constexpr bool test() {
2643
{
2744
// The constructors in this subclause shall not participate in overload
2845
// resolution unless uses_allocator_v<key_container_type, Alloc> is true
@@ -53,20 +70,23 @@ int main(int, char**) {
5370
static_assert(std::is_constructible_v<M, test_allocator<int>>);
5471
static_assert(!std::is_convertible_v<test_allocator<int>, M>);
5572
}
73+
74+
test<std::vector, std::vector>();
75+
#ifndef __cpp_lib_constexpr_deque
76+
if (!TEST_IS_CONSTANT_EVALUATED)
77+
#endif
5678
{
57-
using A = test_allocator<short>;
58-
using M =
59-
std::flat_multimap<int,
60-
long,
61-
std::less<int>,
62-
std::vector<int, test_allocator<int>>,
63-
std::vector<long, test_allocator<long>>>;
64-
M m(A(0, 5));
65-
assert(m.empty());
66-
assert(m.begin() == m.end());
67-
assert(m.keys().get_allocator().get_id() == 5);
68-
assert(m.values().get_allocator().get_id() == 5);
79+
test<std::deque, std::deque>();
6980
}
7081

82+
return true;
83+
}
84+
85+
int main(int, char**) {
86+
test();
87+
#if TEST_STD_VER >= 26
88+
static_assert(test());
89+
#endif
90+
7191
return 0;
7292
}

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

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,32 @@
2424
#include "test_macros.h"
2525
#include "min_allocator.h"
2626
#include "test_allocator.h"
27+
#include "../helpers.h"
2728

2829
template <class KeyContainer, class ValueContainer>
29-
void test() {
30+
constexpr void test() {
3031
using Key = typename KeyContainer::value_type;
3132
using Value = typename ValueContainer::value_type;
3233
using M = std::flat_multimap<Key, Value, std::less<Key>, KeyContainer, ValueContainer>;
3334
{
3435
M m = {{8, 8}, {10, 10}};
3536
assert(m.size() == 2);
36-
m = {{3, 0}, {1, 0}, {2, 0}, {2, 1}, {3, 1}, {4, 0}, {3, 2}, {5, 0}, {6, 0}, {5, 1}};
37-
std::pair<int, int> expected[] = {{1, 0}, {2, 0}, {2, 1}, {3, 0}, {3, 1}, {3, 2}, {4, 0}, {5, 0}, {5, 1}, {6, 0}};
38-
assert(std::ranges::equal(m, expected));
37+
m = {{3, 0}, {1, 0}, {2, 0}, {2, 1}, {3, 1}, {4, 0}, {3, 2}, {5, 0}, {6, 0}, {5, 1}};
38+
assert(std::ranges::equal(m.keys(), std::vector{{1, 2, 2, 3, 3, 3, 4, 5, 5, 6}}));
39+
check_possible_values(
40+
m.values(),
41+
std::vector<std::vector<Value>>{
42+
{0},
43+
{0, 1},
44+
{0, 1},
45+
{0, 1, 2},
46+
{0, 1, 2},
47+
{0, 1, 2},
48+
{0},
49+
{0, 1},
50+
{0, 1},
51+
{0},
52+
});
3953
}
4054
{
4155
M m = {{10, 1}, {8, 1}};
@@ -46,13 +60,28 @@ void test() {
4660
}
4761
}
4862

49-
int main(int, char**) {
63+
constexpr bool test() {
5064
test<std::vector<int>, std::vector<int>>();
5165
test<std::vector<int>, std::vector<double>>();
52-
test<std::deque<int>, std::vector<double>>();
66+
#ifndef __cpp_lib_constexpr_deque
67+
if (!TEST_IS_CONSTANT_EVALUATED)
68+
#endif
69+
{
70+
test<std::deque<int>, std::vector<double>>();
71+
}
72+
5373
test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
5474
test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
5575
test<std::vector<int, min_allocator<int>>, std::vector<int, min_allocator<int>>>();
5676

77+
return true;
78+
}
79+
80+
int main(int, char**) {
81+
test();
82+
#if TEST_STD_VER >= 26
83+
static_assert(test());
84+
#endif
85+
5786
return 0;
5887
}

libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/compare.pass.cpp

Lines changed: 74 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,48 +20,52 @@
2020
#include <type_traits>
2121
#include <vector>
2222

23+
#include "MinSequenceContainer.h"
24+
#include "min_allocator.h"
2325
#include "test_macros.h"
2426
#include "../../../test_compare.h"
2527
#include "test_allocator.h"
2628

27-
int main(int, char**) {
29+
// explicit flat_multimap(const key_compare& comp);
30+
template <class KeyContainer, class ValueContainer>
31+
constexpr void test_compare() {
32+
using Key = typename KeyContainer::value_type;
33+
using Value = typename ValueContainer::value_type;
2834
{
29-
// The constructors in this subclause shall not participate in overload
30-
// resolution unless uses_allocator_v<key_container_type, Alloc> is true
31-
// and uses_allocator_v<mapped_container_type, Alloc> is true.
35+
// The one-argument ctor is explicit.
36+
using C = test_less<Key>;
37+
static_assert(std::is_constructible_v<std::flat_multimap<Key, Value, C>, C>);
38+
static_assert(!std::is_convertible_v<C, std::flat_multimap<Key, Value, C>>);
3239

33-
using C = test_less<int>;
34-
using A1 = test_allocator<int>;
35-
using A2 = other_allocator<int>;
36-
using M1 = std::flat_multimap<int, int, C, std::vector<int, A1>, std::vector<int, A1>>;
37-
using M2 = std::flat_multimap<int, int, C, std::vector<int, A1>, std::vector<int, A2>>;
38-
using M3 = std::flat_multimap<int, int, C, std::vector<int, A2>, std::vector<int, A1>>;
39-
static_assert(std::is_constructible_v<M1, const C&, const A1&>);
40-
static_assert(!std::is_constructible_v<M1, const C&, const A2&>);
41-
static_assert(!std::is_constructible_v<M2, const C&, const A2&>);
42-
static_assert(!std::is_constructible_v<M3, const C&, const A2&>);
40+
static_assert(std::is_constructible_v<std::flat_multimap<Key, Value>, std::less<Key>>);
41+
static_assert(!std::is_convertible_v<std::less<Key>, std::flat_multimap<Key, Value>>);
4342
}
4443
{
45-
using C = test_less<int>;
46-
auto m = std::flat_multimap<int, char*, C>(C(3));
44+
using C = test_less<Key>;
45+
auto m = std::flat_multimap<Key, Value, C>(C(3));
4746
assert(m.empty());
4847
assert(m.begin() == m.end());
4948
assert(m.key_comp() == C(3));
5049
}
51-
{
52-
// The one-argument ctor is explicit.
53-
using C = test_less<int>;
54-
static_assert(std::is_constructible_v<std::flat_multimap<int, char*, C>, C>);
55-
static_assert(!std::is_convertible_v<C, std::flat_multimap<int, char*, C>>);
50+
}
5651

57-
static_assert(std::is_constructible_v<std::flat_multimap<int, char*>, std::less<int>>);
58-
static_assert(!std::is_convertible_v<std::less<int>, std::flat_multimap<int, char*>>);
52+
// template <class Alloc>
53+
// flat_multimap(const key_compare& comp, const Alloc& a);
54+
template <template <class...> class KeyContainer, template <class...> class ValueContainer>
55+
constexpr void test_compare_alloc() {
56+
{
57+
// If an allocator is given, it must be usable by both containers.
58+
using A = test_allocator<int>;
59+
using M = std::flat_multimap<int, int, std::less<>, KeyContainer<int>, ValueContainer<int, A>>;
60+
static_assert(std::is_constructible_v<M, std::less<>>);
61+
static_assert(!std::is_constructible_v<M, std::less<>, std::allocator<int>>);
62+
static_assert(!std::is_constructible_v<M, std::less<>, A>);
5963
}
6064
{
6165
using C = test_less<int>;
6266
using A1 = test_allocator<int>;
6367
using A2 = test_allocator<short>;
64-
auto m = std::flat_multimap<int, short, C, std::vector<int, A1>, std::vector<short, A2>>(C(4), A1(5));
68+
auto m = std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>>(C(4), A1(5));
6569
assert(m.empty());
6670
assert(m.begin() == m.end());
6771
assert(m.key_comp() == C(4));
@@ -70,24 +74,60 @@ int main(int, char**) {
7074
}
7175
{
7276
// explicit(false)
73-
using C = test_less<int>;
74-
using A1 = test_allocator<int>;
75-
using A2 = test_allocator<short>;
76-
std::flat_multimap<int, short, C, std::deque<int, A1>, std::deque<short, A2>> m = {C(4), A1(5)};
77+
using C = test_less<int>;
78+
using A1 = test_allocator<int>;
79+
using A2 = test_allocator<short>;
80+
std::flat_multimap<int, short, C, KeyContainer<int, A1>, ValueContainer<short, A2>> m = {C(4), A1(5)};
7781
assert(m.empty());
7882
assert(m.begin() == m.end());
7983
assert(m.key_comp() == C(4));
8084
assert(m.keys().get_allocator() == A1(5));
8185
assert(m.values().get_allocator() == A2(5));
8286
}
87+
}
88+
89+
constexpr bool test() {
8390
{
84-
// If an allocator is given, it must be usable by both containers.
85-
using A = test_allocator<int>;
86-
using M = std::flat_multimap<int, int, std::less<>, std::vector<int>, std::vector<int, A>>;
87-
static_assert(std::is_constructible_v<M, std::less<>>);
88-
static_assert(!std::is_constructible_v<M, std::less<>, std::allocator<int>>);
89-
static_assert(!std::is_constructible_v<M, std::less<>, A>);
91+
// The constructors in this subclause shall not participate in overload
92+
// resolution unless uses_allocator_v<key_container_type, Alloc> is true
93+
// and uses_allocator_v<mapped_container_type, Alloc> is true.
94+
95+
using C = test_less<int>;
96+
using A1 = test_allocator<int>;
97+
using A2 = other_allocator<int>;
98+
using M1 = std::flat_multimap<int, int, C, std::vector<int, A1>, std::vector<int, A1>>;
99+
using M2 = std::flat_multimap<int, int, C, std::vector<int, A1>, std::vector<int, A2>>;
100+
using M3 = std::flat_multimap<int, int, C, std::vector<int, A2>, std::vector<int, A1>>;
101+
static_assert(std::is_constructible_v<M1, const C&, const A1&>);
102+
static_assert(!std::is_constructible_v<M1, const C&, const A2&>);
103+
static_assert(!std::is_constructible_v<M2, const C&, const A2&>);
104+
static_assert(!std::is_constructible_v<M3, const C&, const A2&>);
105+
}
106+
107+
test_compare<std::vector<int>, std::vector<int>>();
108+
test_compare<std::vector<int>, std::vector<double>>();
109+
test_compare<MinSequenceContainer<int>, MinSequenceContainer<double>>();
110+
test_compare<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
111+
test_compare<std::vector<int, min_allocator<int>>, std::vector<int, min_allocator<int>>>();
112+
113+
test_compare_alloc<std::vector, std::vector>();
114+
115+
#ifndef __cpp_lib_constexpr_deque
116+
if (!TEST_IS_CONSTANT_EVALUATED)
117+
#endif
118+
{
119+
test_compare<std::deque<int>, std::vector<double>>();
120+
test_compare_alloc<std::deque, std::deque>();
90121
}
91122

123+
return true;
124+
}
125+
126+
int main(int, char**) {
127+
test();
128+
#if TEST_STD_VER >= 26
129+
static_assert(test());
130+
#endif
131+
92132
return 0;
93133
}

0 commit comments

Comments
 (0)