Skip to content

Commit 22b63c9

Browse files
committed
[libc++] constexpr flat_map
1 parent 6464066 commit 22b63c9

File tree

82 files changed

+2690
-1220
lines changed

Some content is hidden

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

82 files changed

+2690
-1220
lines changed

libcxx/include/__flat_map/flat_map.h

Lines changed: 232 additions & 156 deletions
Large diffs are not rendered by default.

libcxx/include/__flat_map/key_value_iterator.h

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct __key_value_iterator {
4646

4747
struct __arrow_proxy {
4848
__reference __ref_;
49-
_LIBCPP_HIDE_FROM_ABI __reference* operator->() { return std::addressof(__ref_); }
49+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference* operator->() { return std::addressof(__ref_); }
5050
};
5151

5252
__key_iterator __key_iter_;
@@ -69,99 +69,113 @@ struct __key_value_iterator {
6969

7070
_LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default;
7171

72-
_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i)
72+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
73+
__key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i)
7374
requires _Const && convertible_to<typename _KeyContainer::iterator, __key_iterator> &&
7475
convertible_to<typename _MappedContainer::iterator, __mapped_iterator>
7576
: __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {}
7677

77-
_LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter)
78+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
79+
__key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter)
7880
: __key_iter_(std::move(__key_iter)), __mapped_iter_(std::move(__mapped_iter)) {}
7981

80-
_LIBCPP_HIDE_FROM_ABI __reference operator*() const { return __reference(*__key_iter_, *__mapped_iter_); }
81-
_LIBCPP_HIDE_FROM_ABI __arrow_proxy operator->() const { return __arrow_proxy{**this}; }
82+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference operator*() const {
83+
return __reference(*__key_iter_, *__mapped_iter_);
84+
}
85+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __arrow_proxy operator->() const { return __arrow_proxy{**this}; }
8286

83-
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator++() {
87+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator++() {
8488
++__key_iter_;
8589
++__mapped_iter_;
8690
return *this;
8791
}
8892

89-
_LIBCPP_HIDE_FROM_ABI __key_value_iterator operator++(int) {
93+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator operator++(int) {
9094
__key_value_iterator __tmp(*this);
9195
++*this;
9296
return __tmp;
9397
}
9498

95-
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator--() {
99+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator--() {
96100
--__key_iter_;
97101
--__mapped_iter_;
98102
return *this;
99103
}
100104

101-
_LIBCPP_HIDE_FROM_ABI __key_value_iterator operator--(int) {
105+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator operator--(int) {
102106
__key_value_iterator __tmp(*this);
103107
--*this;
104108
return __tmp;
105109
}
106110

107-
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator+=(difference_type __x) {
111+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator+=(difference_type __x) {
108112
__key_iter_ += __x;
109113
__mapped_iter_ += __x;
110114
return *this;
111115
}
112116

113-
_LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator-=(difference_type __x) {
117+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator-=(difference_type __x) {
114118
__key_iter_ -= __x;
115119
__mapped_iter_ -= __x;
116120
return *this;
117121
}
118122

119-
_LIBCPP_HIDE_FROM_ABI __reference operator[](difference_type __n) const { return *(*this + __n); }
123+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference operator[](difference_type __n) const {
124+
return *(*this + __n);
125+
}
120126

121-
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
127+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool
122128
operator==(const __key_value_iterator& __x, const __key_value_iterator& __y) {
123129
return __x.__key_iter_ == __y.__key_iter_;
124130
}
125131

126-
_LIBCPP_HIDE_FROM_ABI friend bool operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) {
132+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool
133+
operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) {
127134
return __x.__key_iter_ < __y.__key_iter_;
128135
}
129136

130-
_LIBCPP_HIDE_FROM_ABI friend bool operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) {
137+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool
138+
operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) {
131139
return __y < __x;
132140
}
133141

134-
_LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
142+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool
143+
operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
135144
return !(__y < __x);
136145
}
137146

138-
_LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
147+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool
148+
operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
139149
return !(__x < __y);
140150
}
141151

142-
_LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y)
152+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend auto
153+
operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y)
143154
requires three_way_comparable<__key_iterator>
144155
{
145156
return __x.__key_iter_ <=> __y.__key_iter_;
146157
}
147158

148-
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(const __key_value_iterator& __i, difference_type __n) {
159+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator
160+
operator+(const __key_value_iterator& __i, difference_type __n) {
149161
auto __tmp = __i;
150162
__tmp += __n;
151163
return __tmp;
152164
}
153165

154-
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(difference_type __n, const __key_value_iterator& __i) {
166+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator
167+
operator+(difference_type __n, const __key_value_iterator& __i) {
155168
return __i + __n;
156169
}
157170

158-
_LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator-(const __key_value_iterator& __i, difference_type __n) {
171+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator
172+
operator-(const __key_value_iterator& __i, difference_type __n) {
159173
auto __tmp = __i;
160174
__tmp -= __n;
161175
return __tmp;
162176
}
163177

164-
_LIBCPP_HIDE_FROM_ABI friend difference_type
178+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend difference_type
165179
operator-(const __key_value_iterator& __x, const __key_value_iterator& __y) {
166180
return difference_type(__x.__key_iter_ - __y.__key_iter_);
167181
}

libcxx/include/__flat_map/utils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct __flat_map_utils {
3535
// roll back the changes it made to the map. If it cannot roll back the changes, it will
3636
// clear the map.
3737
template <class _Map, class _IterK, class _IterM, class _KeyArg, class... _MArgs>
38-
_LIBCPP_HIDE_FROM_ABI static typename _Map::iterator __emplace_exact_pos(
38+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static typename _Map::iterator __emplace_exact_pos(
3939
_Map& __map, _IterK&& __it_key, _IterM&& __it_mapped, _KeyArg&& __key, _MArgs&&... __mapped_args) {
4040
auto __on_key_failed = std::__make_exception_guard([&]() noexcept {
4141
using _KeyContainer = typename _Map::key_container_type;
@@ -82,7 +82,7 @@ struct __flat_map_utils {
8282
// TODO: We could optimize this, see
8383
// https://github.com/llvm/llvm-project/issues/108624
8484
template <class _Map, class _InputIterator, class _Sentinel>
85-
_LIBCPP_HIDE_FROM_ABI static typename _Map::size_type
85+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static typename _Map::size_type
8686
__append(_Map& __map, _InputIterator __first, _Sentinel __last) {
8787
typename _Map::size_type __num_appended = 0;
8888
for (; __first != __last; ++__first) {

libcxx/test/std/containers/Emplaceable.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ class Emplaceable {
2424
public:
2525
TEST_CONSTEXPR Emplaceable() : int_(0), double_(0) {}
2626
TEST_CONSTEXPR Emplaceable(int i, double d) : int_(i), double_(d) {}
27-
TEST_CONSTEXPR_CXX14 Emplaceable(Emplaceable&& x) : int_(x.int_), double_(x.double_) {
27+
TEST_CONSTEXPR Emplaceable(Emplaceable&& x) : int_(x.int_), double_(x.double_) {
2828
x.int_ = 0;
2929
x.double_ = 0;
3030
}
31-
TEST_CONSTEXPR_CXX14 Emplaceable& operator=(Emplaceable&& x) {
31+
TEST_CONSTEXPR Emplaceable& operator=(Emplaceable&& x) {
3232
int_ = x.int_;
3333
x.int_ = 0;
3434
double_ = x.double_;

libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at.pass.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
#include <flat_map>
1919
#include <functional>
2020
#include <stdexcept>
21+
#include <type_traits>
2122
#include <vector>
2223

2324
#include "MinSequenceContainer.h"
2425
#include "min_allocator.h"
2526
#include "test_macros.h"
2627

2728
template <class KeyContainer, class ValueContainer>
28-
void test() {
29+
constexpr void test() {
2930
using P = std::pair<int, double>;
3031
P ar[] = {
3132
P(1, 1.5),
@@ -49,10 +50,12 @@ void test() {
4950
assert(m.at(4) == 4.5);
5051
assert(m.at(5) == 5.5);
5152
#ifndef TEST_HAS_NO_EXCEPTIONS
52-
try {
53-
TEST_IGNORE_NODISCARD m.at(6);
54-
assert(false);
55-
} catch (std::out_of_range&) {
53+
if (!std::is_constant_evaluated()) {
54+
try {
55+
TEST_IGNORE_NODISCARD m.at(6);
56+
assert(false);
57+
} catch (std::out_of_range&) {
58+
}
5659
}
5760
#endif
5861
assert(m.at(7) == 7.5);
@@ -70,10 +73,12 @@ void test() {
7073
assert(m.at(4) == 4.5);
7174
assert(m.at(5) == 5.5);
7275
#ifndef TEST_HAS_NO_EXCEPTIONS
73-
try {
74-
TEST_IGNORE_NODISCARD m.at(6);
75-
assert(false);
76-
} catch (std::out_of_range&) {
76+
if (!std::is_constant_evaluated()) {
77+
try {
78+
TEST_IGNORE_NODISCARD m.at(6);
79+
assert(false);
80+
} catch (std::out_of_range&) {
81+
}
7782
}
7883
#endif
7984
assert(m.at(7) == 7.5);
@@ -82,11 +87,25 @@ void test() {
8287
}
8388
}
8489

85-
int main(int, char**) {
90+
constexpr bool test() {
8691
test<std::vector<int>, std::vector<double>>();
87-
test<std::deque<int>, std::vector<double>>();
92+
#ifndef __cpp_lib_constexpr_deque
93+
if (!std::is_constant_evaluated())
94+
#endif
95+
{
96+
test<std::deque<int>, std::vector<double>>();
97+
}
8898
test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
8999
test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
90100

101+
return true;
102+
}
103+
104+
int main(int, char**) {
105+
test();
106+
#if TEST_STD_VER >= 26
107+
static_assert(test());
108+
#endif
109+
91110
return 0;
92111
}

libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static_assert(!CanAt<NonTransparentMap>);
3535
static_assert(!CanAt<const NonTransparentMap>);
3636

3737
template <class KeyContainer, class ValueContainer>
38-
void test() {
38+
constexpr void test() {
3939
using P = std::pair<int, double>;
4040
P ar[] = {
4141
P(1, 1.5),
@@ -60,10 +60,12 @@ void test() {
6060
assert(m.at(Transparent<int>{4}) == 4.5);
6161
assert(m.at(Transparent<int>{5}) == 5.5);
6262
#ifndef TEST_HAS_NO_EXCEPTIONS
63-
try {
64-
TEST_IGNORE_NODISCARD m.at(Transparent<int>{6});
65-
assert(false);
66-
} catch (std::out_of_range&) {
63+
if (!std::is_constant_evaluated()) {
64+
try {
65+
TEST_IGNORE_NODISCARD m.at(Transparent<int>{6});
66+
assert(false);
67+
} catch (std::out_of_range&) {
68+
}
6769
}
6870
#endif
6971
assert(m.at(Transparent<int>{7}) == 7.5);
@@ -81,10 +83,12 @@ void test() {
8183
assert(m.at(Transparent<int>{4}) == 4.5);
8284
assert(m.at(Transparent<int>{5}) == 5.5);
8385
#ifndef TEST_HAS_NO_EXCEPTIONS
84-
try {
85-
TEST_IGNORE_NODISCARD m.at(Transparent<int>{6});
86-
assert(false);
87-
} catch (std::out_of_range&) {
86+
if (!std::is_constant_evaluated()) {
87+
try {
88+
TEST_IGNORE_NODISCARD m.at(Transparent<int>{6});
89+
assert(false);
90+
} catch (std::out_of_range&) {
91+
}
8892
}
8993
#endif
9094
assert(m.at(Transparent<int>{7}) == 7.5);
@@ -93,9 +97,14 @@ void test() {
9397
}
9498
}
9599

96-
int main(int, char**) {
100+
constexpr bool test() {
97101
test<std::vector<int>, std::vector<double>>();
98-
test<std::deque<int>, std::vector<double>>();
102+
#ifndef __cpp_lib_constexpr_deque
103+
if (!std::is_constant_evaluated())
104+
#endif
105+
{
106+
test<std::deque<int>, std::vector<double>>();
107+
}
99108
test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
100109
test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
101110
{
@@ -114,5 +123,14 @@ int main(int, char**) {
114123
assert(x == 1);
115124
}
116125

126+
return true;
127+
}
128+
129+
int main(int, char**) {
130+
test();
131+
#if TEST_STD_VER >= 26
132+
static_assert(test());
133+
#endif
134+
117135
return 0;
118136
}

libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_key.pass.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <deque>
1717
#include <flat_map>
1818
#include <functional>
19+
#include <type_traits>
1920
#include <vector>
2021

2122
#include "MinSequenceContainer.h"
@@ -31,7 +32,7 @@ static_assert(CanIndex<std::flat_map<int, double>, const int&>);
3132
static_assert(!CanIndex<std::flat_map<int, NoDefaultCtr>, const int&>);
3233

3334
template <class KeyContainer, class ValueContainer>
34-
void test() {
35+
constexpr void test() {
3536
using P = std::pair<int, double>;
3637
P ar[] = {
3738
P(1, 1.5),
@@ -58,13 +59,18 @@ void test() {
5859
assert(m.size() == 8);
5960
}
6061

61-
int main(int, char**) {
62+
constexpr bool test() {
6263
test<std::vector<int>, std::vector<double>>();
63-
test<std::deque<int>, std::vector<double>>();
64+
#ifndef __cpp_lib_constexpr_deque
65+
if (!std::is_constant_evaluated())
66+
#endif
67+
{
68+
test<std::deque<int>, std::vector<double>>();
69+
}
6470
test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
6571
test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
6672

67-
{
73+
if (!std::is_constant_evaluated()) {
6874
auto index_func = [](auto& m, auto key_arg, auto value_arg) {
6975
using FlatMap = std::decay_t<decltype(m)>;
7076
const typename FlatMap::key_type key = key_arg;
@@ -73,5 +79,16 @@ int main(int, char**) {
7379
};
7480
test_emplace_exception_guarantee(index_func);
7581
}
82+
83+
return true;
84+
}
85+
86+
87+
int main(int, char**) {
88+
test();
89+
#if TEST_STD_VER >= 26
90+
static_assert(test());
91+
#endif
92+
7693
return 0;
7794
}

0 commit comments

Comments
 (0)