Skip to content

Commit 2f1416b

Browse files
huixie90ldionne
andauthored
[libc++] implement std::flat_set (llvm#125241)
Co-authored-by: Louis Dionne <[email protected]>
1 parent 0b181de commit 2f1416b

File tree

96 files changed

+9420
-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.

96 files changed

+9420
-10
lines changed

libcxx/docs/ReleaseNotes/21.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Implemented Papers
4343
- P1361R2: Integration of chrono with text formatting (`Github <https://github.com/llvm/llvm-project/issues/100014>`__)
4444
- P2255R2: A type trait to detect reference binding to temporary (implemented the type traits only) (`Github <https://github.com/llvm/llvm-project/issues/105180>`__)
4545
- P2562R1: ``constexpr`` Stable Sorting (`Github <https://github.com/llvm/llvm-project/issues/105360>`__)
46+
- P1222R4: A Standard ``flat_set`` is partially implemented and ``flat_set`` is provided (`Github <https://github.com/llvm/llvm-project/issues/105193>`__)
4647

4748
Improvements and New Features
4849
-----------------------------

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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ set(files
369369
__flat_map/sorted_equivalent.h
370370
__flat_map/sorted_unique.h
371371
__flat_map/utils.h
372+
__flat_set/flat_set.h
373+
__flat_set/ra_iterator.h
372374
__format/buffer.h
373375
__format/concepts.h
374376
__format/container_adaptor.h
@@ -995,6 +997,7 @@ set(files
995997
fenv.h
996998
filesystem
997999
flat_map
1000+
flat_set
9981001
float.h
9991002
format
10001003
forward_list

libcxx/include/__flat_set/flat_set.h

Lines changed: 846 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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_RA_ITERATOR_H
11+
#define _LIBCPP___FLAT_SET_RA_ITERATOR_H
12+
13+
#include "__type_traits/is_same.h"
14+
#include <__compare/three_way_comparable.h>
15+
#include <__config>
16+
#include <__iterator/incrementable_traits.h>
17+
#include <__iterator/iterator_traits.h>
18+
#include <__type_traits/is_constructible.h>
19+
#include <__utility/move.h>
20+
21+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22+
# pragma GCC system_header
23+
#endif
24+
25+
_LIBCPP_PUSH_MACROS
26+
#include <__undef_macros>
27+
28+
#if _LIBCPP_STD_VER >= 23
29+
30+
_LIBCPP_BEGIN_NAMESPACE_STD
31+
32+
/**
33+
* __ra_iterator is a random access iterator that wraps an underlying iterator.
34+
* It also stores the underlying container type in its type so that algorithms
35+
* can optimize based on the underlying container type, and to avoid inadvertently
36+
* mixing iterators coming from different containers..
37+
*/
38+
template <class _Container, class _Iterator>
39+
struct __ra_iterator {
40+
private:
41+
_Iterator __iter_;
42+
43+
friend _Container;
44+
45+
// note: checking the concept random_access_iterator does not work for incomplete types
46+
static_assert(_IsSame<typename iterator_traits<_Iterator>::iterator_category, random_access_iterator_tag>::value,
47+
"Underlying iterator must be a random access iterator");
48+
49+
public:
50+
using iterator_concept = random_access_iterator_tag; // deliberately lower contiguous_iterator
51+
using iterator_category = random_access_iterator_tag;
52+
using value_type = iter_value_t<_Iterator>;
53+
using difference_type = iter_difference_t<_Iterator>;
54+
55+
_LIBCPP_HIDE_FROM_ABI __ra_iterator()
56+
requires is_default_constructible_v<_Iterator>
57+
= default;
58+
59+
_LIBCPP_HIDE_FROM_ABI explicit constexpr __ra_iterator(_Iterator __iter) : __iter_(std::move(__iter)) {}
60+
61+
_LIBCPP_HIDE_FROM_ABI constexpr _Iterator __base() const noexcept(noexcept(_Iterator(__iter_))) { return __iter_; }
62+
63+
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__iter_; }
64+
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator->() const
65+
requires requires { __iter_.operator->(); }
66+
{
67+
return __iter_.operator->();
68+
}
69+
70+
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator++() {
71+
++__iter_;
72+
return *this;
73+
}
74+
75+
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator operator++(int) {
76+
__ra_iterator __tmp(*this);
77+
++*this;
78+
return __tmp;
79+
}
80+
81+
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator--() {
82+
--__iter_;
83+
return *this;
84+
}
85+
86+
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator operator--(int) {
87+
__ra_iterator __tmp(*this);
88+
--*this;
89+
return __tmp;
90+
}
91+
92+
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator+=(difference_type __x) {
93+
__iter_ += __x;
94+
return *this;
95+
}
96+
97+
_LIBCPP_HIDE_FROM_ABI constexpr __ra_iterator& operator-=(difference_type __x) {
98+
__iter_ -= __x;
99+
return *this;
100+
}
101+
102+
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const { return *(*this + __n); }
103+
104+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __ra_iterator& __x, const __ra_iterator& __y) {
105+
return __x.__iter_ == __y.__iter_;
106+
}
107+
108+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __ra_iterator& __x, const __ra_iterator& __y) {
109+
return __x.__iter_ < __y.__iter_;
110+
}
111+
112+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __ra_iterator& __x, const __ra_iterator& __y) {
113+
return __y < __x;
114+
}
115+
116+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __ra_iterator& __x, const __ra_iterator& __y) {
117+
return !(__y < __x);
118+
}
119+
120+
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __ra_iterator& __x, const __ra_iterator& __y) {
121+
return !(__x < __y);
122+
}
123+
124+
_LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __ra_iterator& __x, const __ra_iterator& __y)
125+
requires three_way_comparable<_Iterator>
126+
{
127+
return __x.__iter_ <=> __y.__iter_;
128+
}
129+
130+
_LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator+(const __ra_iterator& __i, difference_type __n) {
131+
auto __tmp = __i;
132+
__tmp += __n;
133+
return __tmp;
134+
}
135+
136+
_LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator+(difference_type __n, const __ra_iterator& __i) {
137+
return __i + __n;
138+
}
139+
140+
_LIBCPP_HIDE_FROM_ABI friend constexpr __ra_iterator operator-(const __ra_iterator& __i, difference_type __n) {
141+
auto __tmp = __i;
142+
__tmp -= __n;
143+
return __tmp;
144+
}
145+
146+
_LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __ra_iterator& __x, const __ra_iterator& __y) {
147+
return __x.__iter_ - __y.__iter_;
148+
}
149+
};
150+
151+
_LIBCPP_END_NAMESPACE_STD
152+
153+
#endif // _LIBCPP_STD_VER >= 23
154+
155+
_LIBCPP_POP_MACROS
156+
157+
#endif // _LIBCPP___FLAT_SET_RA_ITERATOR_H

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: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,19 @@ module std [system] {
12961296
export *
12971297
}
12981298

1299+
module flat_set {
1300+
module flat_set {
1301+
header "__flat_set/flat_set.h"
1302+
export std.vector.vector
1303+
export std.vector.fwd
1304+
}
1305+
module ra_iterator { header "__flat_set/ra_iterator.h" }
1306+
1307+
header "flat_set"
1308+
export std.flat_map.sorted_unique
1309+
export *
1310+
}
1311+
12991312
module format {
13001313
module buffer {
13011314
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

0 commit comments

Comments
 (0)