Skip to content

Commit a0f80fc

Browse files
committed
[libc++] implement std::flat_set
1 parent 8035d38 commit a0f80fc

File tree

82 files changed

+8453
-0
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

+8453
-0
lines changed

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: 853 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: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,17 @@ 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+
1273+
header "flat_set"
1274+
export *
1275+
}
1276+
12661277
module format {
12671278
module buffer {
12681279
header "__format/buffer.h"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <flat_set>
12+
13+
// [[nodiscard]] bool empty() const noexcept;
14+
15+
#include <flat_set>
16+
#include <cassert>
17+
#include <deque>
18+
#include <functional>
19+
#include <utility>
20+
#include <vector>
21+
22+
#include "MinSequenceContainer.h"
23+
#include "test_macros.h"
24+
#include "min_allocator.h"
25+
26+
template <class KeyContainer>
27+
void test() {
28+
using Key = typename KeyContainer::value_type;
29+
using M = std::flat_set<Key, std::less<int>, KeyContainer>;
30+
M m;
31+
ASSERT_SAME_TYPE(decltype(m.empty()), bool);
32+
ASSERT_NOEXCEPT(m.empty());
33+
assert(m.empty());
34+
assert(std::as_const(m).empty());
35+
m = {1};
36+
assert(!m.empty());
37+
m.clear();
38+
assert(m.empty());
39+
}
40+
41+
int main(int, char**) {
42+
test<std::vector<int>>();
43+
test<std::deque<int>>();
44+
test<MinSequenceContainer<int>>();
45+
test<std::vector<int, min_allocator<int>>>();
46+
47+
return 0;
48+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <flat_set>
12+
13+
// [[nodiscard]] bool empty() const noexcept;
14+
15+
#include <flat_set>
16+
17+
void f() {
18+
std::flat_set<int> c;
19+
c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
20+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <flat_set>
12+
13+
// size_type max_size() const noexcept;
14+
15+
#include <cassert>
16+
#include <deque>
17+
#include <flat_set>
18+
#include <functional>
19+
#include <limits>
20+
#include <type_traits>
21+
#include <vector>
22+
23+
#include "MinSequenceContainer.h"
24+
#include "test_allocator.h"
25+
#include "test_macros.h"
26+
27+
int main(int, char**) {
28+
{
29+
using A1 = limited_allocator<int, 10>;
30+
using C = std::flat_set<int, std::less<int>, std::vector<int, A1>>;
31+
ASSERT_SAME_TYPE(C::difference_type, std::ptrdiff_t);
32+
ASSERT_SAME_TYPE(C::size_type, std::size_t);
33+
const C c;
34+
ASSERT_NOEXCEPT(c.max_size());
35+
ASSERT_SAME_TYPE(decltype(c.max_size()), C::size_type);
36+
assert(c.max_size() <= 10);
37+
LIBCPP_ASSERT(c.max_size() == 10);
38+
}
39+
{
40+
using A = limited_allocator<int, (size_t)-1>;
41+
using C = std::flat_set<int, std::less<int>, std::vector<int, A>>;
42+
ASSERT_SAME_TYPE(C::difference_type, std::ptrdiff_t);
43+
ASSERT_SAME_TYPE(C::size_type, std::size_t);
44+
const C::size_type max_dist = static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
45+
const C c;
46+
ASSERT_NOEXCEPT(c.max_size());
47+
ASSERT_SAME_TYPE(decltype(c.max_size()), C::size_type);
48+
assert(c.max_size() <= max_dist);
49+
LIBCPP_ASSERT(c.max_size() == max_dist);
50+
}
51+
{
52+
typedef std::flat_set<char> C;
53+
ASSERT_SAME_TYPE(C::difference_type, std::ptrdiff_t);
54+
ASSERT_SAME_TYPE(C::size_type, std::size_t);
55+
const C::size_type max_dist = static_cast<C::size_type>(std::numeric_limits<C::difference_type>::max());
56+
const C c;
57+
ASSERT_NOEXCEPT(c.max_size());
58+
ASSERT_SAME_TYPE(decltype(c.max_size()), C::size_type);
59+
assert(c.max_size() <= max_dist);
60+
assert(c.max_size() <= alloc_max_size(std::allocator<char>()));
61+
}
62+
return 0;
63+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <flat_set>
12+
13+
// size_type size() const noexcept;
14+
15+
#include <cassert>
16+
#include <deque>
17+
#include <flat_set>
18+
#include <functional>
19+
#include <vector>
20+
21+
#include "MinSequenceContainer.h"
22+
#include "test_macros.h"
23+
#include "min_allocator.h"
24+
25+
template <class KeyContainer>
26+
void test() {
27+
using M = std::flat_set<int, std::less<int>, KeyContainer>;
28+
using S = typename M::size_type;
29+
{
30+
const M m = {1, 1, 4, 5, 5};
31+
ASSERT_SAME_TYPE(decltype(m.size()), S);
32+
ASSERT_NOEXCEPT(m.size());
33+
assert(m.size() == 3);
34+
}
35+
{
36+
const M m = {1};
37+
ASSERT_SAME_TYPE(decltype(m.size()), S);
38+
ASSERT_NOEXCEPT(m.size());
39+
assert(m.size() == 1);
40+
}
41+
{
42+
const M m;
43+
ASSERT_SAME_TYPE(decltype(m.size()), S);
44+
ASSERT_NOEXCEPT(m.size());
45+
assert(m.size() == 0);
46+
}
47+
{
48+
M m;
49+
S s = 1000000;
50+
for (auto i = 0u; i < s; ++i) {
51+
m.emplace(i);
52+
}
53+
ASSERT_SAME_TYPE(decltype(m.size()), S);
54+
ASSERT_NOEXCEPT(m.size());
55+
assert(m.size() == s);
56+
}
57+
}
58+
59+
int main(int, char**) {
60+
test<std::vector<int>>();
61+
test<std::deque<int>>();
62+
test<MinSequenceContainer<int>>();
63+
test<std::vector<int, min_allocator<int>>>();
64+
65+
return 0;
66+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <flat_set>
12+
13+
// template<class Allocator>
14+
// explicit flat_set(const Allocator& a);
15+
16+
#include <cassert>
17+
#include <flat_set>
18+
#include <functional>
19+
#include <vector>
20+
21+
#include "test_macros.h"
22+
#include "test_allocator.h"
23+
#include "../../../test_compare.h"
24+
25+
int main(int, char**) {
26+
{
27+
// The constructors in this subclause shall not participate in overload
28+
// resolution unless uses_allocator_v<container_type, Alloc> is true.
29+
30+
using C = test_less<int>;
31+
using A1 = test_allocator<int>;
32+
using A2 = other_allocator<int>;
33+
using V1 = std::vector<int, A1>;
34+
using V2 = std::vector<int, A2>;
35+
using M1 = std::flat_set<int, C, V1>;
36+
using M2 = std::flat_set<int, C, V2>;
37+
static_assert(std::is_constructible_v<M1, const A1&>);
38+
static_assert(std::is_constructible_v<M2, const A2&>);
39+
static_assert(!std::is_constructible_v<M1, const A2&>);
40+
static_assert(!std::is_constructible_v<M2, const A1&>);
41+
}
42+
{
43+
// explicit
44+
using M = std::flat_set<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+
}
49+
{
50+
using A = test_allocator<short>;
51+
using M = std::flat_set<int, std::less<int>, std::vector<int, test_allocator<int>>>;
52+
M m(A(0, 5));
53+
assert(m.empty());
54+
assert(m.begin() == m.end());
55+
auto v = std::move(m).extract();
56+
assert(v.get_allocator().get_id() == 5);
57+
}
58+
59+
return 0;
60+
}

0 commit comments

Comments
 (0)