Skip to content

Commit 5c734e1

Browse files
committed
[libc++] implement std::flat_set
review review clang-format CI deduction CI CI again CI again
1 parent 689ef5f commit 5c734e1

File tree

91 files changed

+8987
-10
lines changed

Some content is hidden

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

91 files changed

+8987
-10
lines changed

libcxx/docs/ReleaseNotes/21.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Implemented Papers
3939
------------------
4040

4141
- N4258: Cleaning-up noexcept in the Library (`Github <https://github.com/llvm/llvm-project/issues/99937>`__)
42+
- P1222R4: A Standard ``flat_set`` is partially implemented and ``flat_set`` is provided (`Github <https://github.com/llvm/llvm-project/issues/105193>`__)
4243

4344
Improvements and New Features
4445
-----------------------------

libcxx/docs/Status/Cxx23Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"`P0009R18 <https://wg21.link/P0009R18>`__","mdspan: A Non-Owning Multidimensional Array Reference","2022-07 (Virtual)","|Complete|","18",""
5555
"`P0429R9 <https://wg21.link/P0429R9>`__","A Standard ``flat_map``","2022-07 (Virtual)","|Complete|","20",""
5656
"`P1169R4 <https://wg21.link/P1169R4>`__","``static operator()``","2022-07 (Virtual)","|Complete|","16",""
57-
"`P1222R4 <https://wg21.link/P1222R4>`__","A Standard ``flat_set``","2022-07 (Virtual)","","",""
57+
"`P1222R4 <https://wg21.link/P1222R4>`__","A Standard ``flat_set``","2022-07 (Virtual)","|In progress|","",""
5858
"`P1223R5 <https://wg21.link/P1223R5>`__","``ranges::find_last()``, ``ranges::find_last_if()``, and ``ranges::find_last_if_not()``","2022-07 (Virtual)","|Complete|","19",""
5959
"`P1467R9 <https://wg21.link/P1467R9>`__","Extended ``floating-point`` types and standard names","2022-07 (Virtual)","","",""
6060
"`P1642R11 <https://wg21.link/P1642R11>`__","Freestanding ``[utilities]``, ``[ranges]``, and ``[iterators]``","2022-07 (Virtual)","","",""

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ set(files
367367
__flat_map/sorted_equivalent.h
368368
__flat_map/sorted_unique.h
369369
__flat_map/utils.h
370+
__flat_set/flat_set.h
370371
__format/buffer.h
371372
__format/concepts.h
372373
__format/container_adaptor.h
@@ -986,6 +987,7 @@ set(files
986987
fenv.h
987988
filesystem
988989
flat_map
990+
flat_set
989991
float.h
990992
format
991993
forward_list

libcxx/include/__flat_set/flat_set.h

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

libcxx/include/flat_set

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP_FLAT_SET
11+
#define _LIBCPP_FLAT_SET
12+
13+
/*
14+
Header <flat_set> synopsis
15+
16+
#include <compare> // see [compare.syn]
17+
#include <initializer_list> // see [initializer.list.syn]
18+
19+
namespace std {
20+
// [flat.set], class template flat_set
21+
template<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>
22+
class flat_set;
23+
24+
struct sorted_unique_t { explicit sorted_unique_t() = default; };
25+
inline constexpr sorted_unique_t sorted_unique{};
26+
27+
template<class Key, class Compare, class KeyContainer, class Allocator>
28+
struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>;
29+
30+
// [flat.set.erasure], erasure for flat_set
31+
template<class Key, class Compare, class KeyContainer, class Predicate>
32+
typename flat_set<Key, Compare, KeyContainer>::size_type
33+
erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
34+
}
35+
*/
36+
37+
#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
38+
# include <__cxx03/__config>
39+
#else
40+
# include <__config>
41+
42+
# if _LIBCPP_STD_VER >= 23
43+
# include <__flat_map/sorted_unique.h>
44+
# include <__flat_set/flat_set.h>
45+
# endif
46+
47+
// for feature-test macros
48+
# include <version>
49+
50+
// standard required includes
51+
# include <compare>
52+
# include <initializer_list>
53+
54+
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
55+
# pragma GCC system_header
56+
# endif
57+
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
58+
59+
#endif // _LIBCPP_FLAT_SET

libcxx/include/module.modulemap

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,22 @@ module std [system] {
12631263
export *
12641264
}
12651265

1266+
module flat_set {
1267+
module flat_set {
1268+
header "__flat_set/flat_set.h"
1269+
export std.vector.vector
1270+
export std.vector.fwd
1271+
}
1272+
module sorted_unique {
1273+
header "__flat_map/sorted_unique.h"
1274+
export *
1275+
}
1276+
1277+
header "flat_set"
1278+
export std.flat_map.sorted_unique
1279+
export *
1280+
}
1281+
12661282
module format {
12671283
module buffer {
12681284
header "__format/buffer.h"

libcxx/modules/std.compat.cppm.in

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ module;
5353
# if __has_include(<debugging>)
5454
# error "please update the header information for <debugging> in headers_not_available in utils/libcxx/header_information.py"
5555
# endif // __has_include(<debugging>)
56-
# if __has_include(<flat_set>)
57-
# error "please update the header information for <flat_set> in headers_not_available in utils/libcxx/header_information.py"
58-
# endif // __has_include(<flat_set>)
5956
# if __has_include(<generator>)
6057
# error "please update the header information for <generator> in headers_not_available in utils/libcxx/header_information.py"
6158
# endif // __has_include(<generator>)

libcxx/modules/std.cppm.in

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module;
6565
#include <expected>
6666
#include <filesystem>
6767
#include <flat_map>
68+
#include <flat_set>
6869
#include <format>
6970
#include <forward_list>
7071
#if _LIBCPP_HAS_LOCALIZATION
@@ -162,9 +163,6 @@ module;
162163
# if __has_include(<debugging>)
163164
# error "please update the header information for <debugging> in headers_not_available in utils/libcxx/header_information.py"
164165
# endif // __has_include(<debugging>)
165-
# if __has_include(<flat_set>)
166-
# error "please update the header information for <flat_set> in headers_not_available in utils/libcxx/header_information.py"
167-
# endif // __has_include(<flat_set>)
168166
# if __has_include(<generator>)
169167
# error "please update the header information for <generator> in headers_not_available in utils/libcxx/header_information.py"
170168
# endif // __has_include(<generator>)

libcxx/modules/std/flat_set.inc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
//===----------------------------------------------------------------------===//
99

1010
export namespace std {
11-
#if 0
11+
#if _LIBCPP_STD_VER >= 23
1212
// [flat.set], class template flat_­set
1313
using std::flat_set;
1414

@@ -19,7 +19,9 @@ export namespace std {
1919

2020
// [flat.set.erasure], erasure for flat_­set
2121
using std::erase_if;
22+
#endif // _LIBCPP_STD_VER >= 23
2223

24+
#if 0
2325
// [flat.multiset], class template flat_­multiset
2426
using std::flat_multiset;
2527

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
//
2+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3+
// See https://llvm.org/LICENSE.txt for license information.
4+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
//
6+
//===----------------------------------------------------------------------===//
7+
8+
// REQUIRES: has-unix-headers
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
// UNSUPPORTED: libcpp-hardening-mode=none
11+
// REQUIRES: libcpp-hardening-mode=debug
12+
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
13+
14+
// <flat_set>
15+
16+
// flat_set(container_type , const key_compare& __comp = key_compare())
17+
// flat_set(const container_type& , const _Allocator& )
18+
// flat_set(const container_type& , const key_compare&, const _Allocator& )
19+
// void replace(container_type&& )
20+
//
21+
22+
#include <flat_set>
23+
#include <functional>
24+
#include <initializer_list>
25+
#include <memory>
26+
#include <utility>
27+
#include <vector>
28+
29+
#include "check_assertion.h"
30+
31+
int main(int, char**) {
32+
using M = std::flat_set<int>;
33+
34+
TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {2, 2, 3}); }()),
35+
"Either the key container is not sorted or it contains duplicates");
36+
37+
TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {4, 2, 3}); }()),
38+
"Either the key container is not sorted or it contains duplicates");
39+
40+
TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {2, 2, 3}, std::less<int>{}); }()),
41+
"Either the key container is not sorted or it contains duplicates");
42+
43+
TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_unique, {4, 2, 3}, std::less<int>{}); }()),
44+
"Either the key container is not sorted or it contains duplicates");
45+
46+
TEST_LIBCPP_ASSERT_FAILURE(
47+
([] {
48+
const std::vector keys{2, 2, 3};
49+
const std::allocator<int> alloc{};
50+
M m(std::sorted_unique, keys, alloc);
51+
}()),
52+
"Either the key container is not sorted or it contains duplicates");
53+
54+
TEST_LIBCPP_ASSERT_FAILURE(
55+
([] {
56+
const std::vector keys{4, 2, 3};
57+
const std::allocator<int> alloc{};
58+
M m(std::sorted_unique, keys, alloc);
59+
}()),
60+
"Either the key container is not sorted or it contains duplicates");
61+
62+
TEST_LIBCPP_ASSERT_FAILURE(
63+
([] {
64+
const std::vector keys{2, 2, 3};
65+
const std::allocator<int> alloc{};
66+
const std::less<int> comp{};
67+
M m(std::sorted_unique, keys, comp, alloc);
68+
}()),
69+
"Either the key container is not sorted or it contains duplicates");
70+
71+
TEST_LIBCPP_ASSERT_FAILURE(
72+
([] {
73+
const std::vector keys{4, 2, 3};
74+
const std::allocator<int> alloc{};
75+
const std::less<int> comp{};
76+
M m(std::sorted_unique, keys, comp, alloc);
77+
}()),
78+
"Either the key container is not sorted or it contains duplicates");
79+
80+
TEST_LIBCPP_ASSERT_FAILURE(
81+
([] {
82+
const std::vector<int> v{2, 2, 3};
83+
const std::less<int> comp{};
84+
M m(std::sorted_unique, v.begin(), v.end(), comp);
85+
}()),
86+
"Either the key container is not sorted or it contains duplicates");
87+
88+
TEST_LIBCPP_ASSERT_FAILURE(
89+
([] {
90+
const std::vector<int> v{4, 2, 3};
91+
const std::less<int> comp{};
92+
M m(std::sorted_unique, v.begin(), v.end(), comp);
93+
}()),
94+
"Either the key container is not sorted or it contains duplicates");
95+
96+
TEST_LIBCPP_ASSERT_FAILURE(
97+
([] {
98+
const std::vector<int> v{2, 2, 3};
99+
const std::less<int> comp{};
100+
const std::allocator<int> alloc{};
101+
M m(std::sorted_unique, v.begin(), v.end(), comp, alloc);
102+
}()),
103+
"Either the key container is not sorted or it contains duplicates");
104+
105+
TEST_LIBCPP_ASSERT_FAILURE(
106+
([] {
107+
const std::vector<int> v{4, 2, 3};
108+
const std::less<int> comp{};
109+
const std::allocator<int> alloc{};
110+
M m(std::sorted_unique, v.begin(), v.end(), comp, alloc);
111+
}()),
112+
"Either the key container is not sorted or it contains duplicates");
113+
114+
TEST_LIBCPP_ASSERT_FAILURE(
115+
([] {
116+
const std::vector<int> v{2, 2, 3};
117+
const std::allocator<int> alloc{};
118+
M m(std::sorted_unique, v.begin(), v.end(), alloc);
119+
}()),
120+
"Either the key container is not sorted or it contains duplicates");
121+
122+
TEST_LIBCPP_ASSERT_FAILURE(
123+
([] {
124+
const std::vector<int> v{4, 2, 3};
125+
const std::allocator<int> alloc{};
126+
M m(std::sorted_unique, v.begin(), v.end(), alloc);
127+
}()),
128+
"Either the key container is not sorted or it contains duplicates");
129+
130+
TEST_LIBCPP_ASSERT_FAILURE(
131+
([] {
132+
std::initializer_list<int> v{2, 2, 3};
133+
const std::less<int> comp{};
134+
M m(std::sorted_unique, v, comp);
135+
}()),
136+
"Either the key container is not sorted or it contains duplicates");
137+
138+
TEST_LIBCPP_ASSERT_FAILURE(
139+
([] {
140+
std::initializer_list<int> v{4, 2, 3};
141+
const std::less<int> comp{};
142+
M m(std::sorted_unique, v, comp);
143+
}()),
144+
"Either the key container is not sorted or it contains duplicates");
145+
146+
TEST_LIBCPP_ASSERT_FAILURE(
147+
([] {
148+
std::initializer_list<int> v{2, 2, 3};
149+
const std::less<int> comp{};
150+
const std::allocator<int> alloc{};
151+
M m(std::sorted_unique, v, comp, alloc);
152+
}()),
153+
"Either the key container is not sorted or it contains duplicates");
154+
155+
TEST_LIBCPP_ASSERT_FAILURE(
156+
([] {
157+
std::initializer_list<int> v{4, 2, 3};
158+
const std::less<int> comp{};
159+
const std::allocator<int> alloc{};
160+
M m(std::sorted_unique, v, comp, alloc);
161+
}()),
162+
"Either the key container is not sorted or it contains duplicates");
163+
164+
TEST_LIBCPP_ASSERT_FAILURE(
165+
([] {
166+
std::initializer_list<int> v{2, 2, 3};
167+
const std::allocator<int> alloc{};
168+
M m(std::sorted_unique, v, alloc);
169+
}()),
170+
"Either the key container is not sorted or it contains duplicates");
171+
172+
TEST_LIBCPP_ASSERT_FAILURE(
173+
([] {
174+
std::initializer_list<int> v{4, 2, 3};
175+
const std::allocator<int> alloc{};
176+
M m(std::sorted_unique, v, alloc);
177+
}()),
178+
"Either the key container is not sorted or it contains duplicates");
179+
TEST_LIBCPP_ASSERT_FAILURE(
180+
([] {
181+
const std::vector<int> v{2, 2, 3};
182+
M m;
183+
m.insert(std::sorted_unique, v.begin(), v.end());
184+
}()),
185+
"Either the key container is not sorted or it contains duplicates");
186+
187+
TEST_LIBCPP_ASSERT_FAILURE(
188+
([] {
189+
const std::vector<int> v{4, 2, 3};
190+
M m;
191+
m.insert(std::sorted_unique, v.begin(), v.end());
192+
}()),
193+
"Either the key container is not sorted or it contains duplicates");
194+
TEST_LIBCPP_ASSERT_FAILURE(
195+
([] {
196+
std::initializer_list<int> v{2, 2, 3};
197+
M m;
198+
m.insert(std::sorted_unique, v);
199+
}()),
200+
"Either the key container is not sorted or it contains duplicates");
201+
202+
TEST_LIBCPP_ASSERT_FAILURE(
203+
([] {
204+
std::initializer_list<int> v{4, 2, 3};
205+
M m;
206+
m.insert(std::sorted_unique, v);
207+
}()),
208+
"Either the key container is not sorted or it contains duplicates");
209+
210+
TEST_LIBCPP_ASSERT_FAILURE(
211+
([] {
212+
std::vector keys{1, 1, 3};
213+
M m;
214+
m.replace(std::move(keys));
215+
}()),
216+
"Either the key container is not sorted or it contains duplicates");
217+
TEST_LIBCPP_ASSERT_FAILURE(
218+
([] {
219+
std::vector keys{2, 1, 3};
220+
M m;
221+
m.replace(std::move(keys));
222+
}()),
223+
"Either the key container is not sorted or it contains duplicates");
224+
225+
return 0;
226+
}

0 commit comments

Comments
 (0)