Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 166 additions & 112 deletions libcxx/include/__flat_set/flat_set.h

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions libcxx/include/__flat_set/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ struct __flat_set_utils {
// When an exception is thrown during the emplacement, the function will clear the set if the container does not
// have strong exception safety guarantee on emplacement.
template <class _Set, class _Iter, class _KeyArg>
_LIBCPP_HIDE_FROM_ABI static auto __emplace_exact_pos(_Set& __set, _Iter&& __iter, _KeyArg&& __key) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto
__emplace_exact_pos(_Set& __set, _Iter&& __iter, _KeyArg&& __key) {
using _KeyContainer = typename decay_t<_Set>::container_type;
auto __on_failure = std::__make_exception_guard([&]() noexcept {
if constexpr (!__container_traits<_KeyContainer>::__emplacement_has_strong_exception_safety_guarantee) {
Expand All @@ -51,12 +52,13 @@ struct __flat_set_utils {
}

template <class _Set, class _InputIterator>
_LIBCPP_HIDE_FROM_ABI static void __append(_Set& __set, _InputIterator __first, _InputIterator __last) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void
__append(_Set& __set, _InputIterator __first, _InputIterator __last) {
__set.__keys_.insert(__set.__keys_.end(), std::move(__first), std::move(__last));
}

template <class _Set, class _Range>
_LIBCPP_HIDE_FROM_ABI static void __append(_Set& __set, _Range&& __rng) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void __append(_Set& __set, _Range&& __rng) {
if constexpr (requires { __set.__keys_.insert_range(__set.__keys_.end(), std::forward<_Range>(__rng)); }) {
// C++23 Sequence Container should have insert_range member function
// Note that not all Sequence Containers provide append_range.
Expand Down
3 changes: 3 additions & 0 deletions libcxx/include/module.modulemap.in
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,9 @@ module std [system] {
export std.flat_map.sorted_unique
export std.flat_map.sorted_equivalent
export *
export std.algorithm.ranges_sort
export std.ranges.zip_view
export std.tuple
}

module format {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "../flat_helpers.h"
#include "test_macros.h"

bool test() {
constexpr bool test() {
using M = std::flat_set<TrackCopyMove>;
{
M m;
Expand All @@ -43,6 +43,9 @@ bool test() {

int main(int, char**) {
test();
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,33 @@
#include <vector>

#include "../flat_helpers.h"
#include "test_iterators.h"
#include "test_macros.h"

void test() {
constexpr bool test() {
NotQuiteSequenceContainer<int> v;
std::flat_set s(v);
std::istringstream ints("0 1 1 0");
auto r = std::ranges::subrange(std::istream_iterator<int>(ints), std::istream_iterator<int>()) |
std::views::transform([](int i) { return i * i; });

int ar[] = {0, 1, 1, 0};
using Iter = cpp20_input_iterator<const int*>;
using Sent = sentinel_wrapper<Iter>;
using R = std::ranges::subrange<Iter, Sent>;
auto r = R(Iter(ar), Sent(Iter(ar + 4)));

static_assert(
![](auto& t) { return requires { t.insert_range(t.end(), r); }; }(v),
"This test is to test the case where the underlying container does not provide insert_range");
s.insert_range(r);
assert(std::ranges::equal(s, std::vector<int>{0, 1}));

return true;
}

int main(int, char**) {
test();
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "min_allocator.h"

template <class KeyContainer>
void test_one() {
constexpr void test_one() {
using Key = typename KeyContainer::value_type;
using M = std::flat_set<Key, std::less<int>, KeyContainer>;
M m;
Expand All @@ -38,15 +38,23 @@ void test_one() {
assert(m.empty());
}

void test() {
constexpr bool test() {
test_one<std::vector<int>>();
test_one<std::deque<int>>();
#ifndef __cpp_lib_constexpr_deque
if (!TEST_IS_CONSTANT_EVALUATED)
#endif
test_one<std::deque<int>>();
test_one<MinSequenceContainer<int>>();
test_one<std::vector<int, min_allocator<int>>>();

return true;
}

int main(int, char**) {
test();
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "test_allocator.h"
#include "test_macros.h"

void test() {
constexpr bool test() {
{
using A1 = limited_allocator<int, 10>;
using C = std::flat_set<int, std::less<int>, std::vector<int, A1>>;
Expand Down Expand Up @@ -59,10 +59,15 @@ void test() {
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(std::allocator<char>()));
}

return true;
}

int main(int, char**) {
test();
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
#include <deque>
#include <flat_set>
#include <functional>
#include <type_traits>
#include <vector>

#include "MinSequenceContainer.h"
#include "test_macros.h"
#include "min_allocator.h"

template <class KeyContainer>
void test_one() {
constexpr void test_one() {
using M = std::flat_set<int, std::less<int>, KeyContainer>;
using S = typename M::size_type;
{
Expand All @@ -46,7 +47,7 @@ void test_one() {
}
{
M m;
S s = 1000000;
S s = TEST_IS_CONSTANT_EVALUATED ? 100 : 1000000;
for (auto i = 0u; i < s; ++i) {
m.emplace(i);
}
Expand All @@ -56,15 +57,23 @@ void test_one() {
}
}

void test() {
constexpr bool test() {
test_one<std::vector<int>>();
test_one<std::deque<int>>();
#ifndef __cpp_lib_constexpr_deque
if (!TEST_IS_CONSTANT_EVALUATED)
#endif
test_one<std::deque<int>>();
test_one<MinSequenceContainer<int>>();
test_one<std::vector<int, min_allocator<int>>>();

return true;
}

int main(int, char**) {
test();
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,27 @@
// explicit flat_set(const Allocator& a);

#include <cassert>
#include <deque>
#include <flat_set>
#include <functional>
#include <vector>

#include "MinSequenceContainer.h"
#include "test_macros.h"
#include "test_allocator.h"
#include "../../../test_compare.h"

void test() {
template <template <class...> class KeyContainer>
constexpr void test() {
{
// The constructors in this subclause shall not participate in overload
// resolution unless uses_allocator_v<container_type, Alloc> is true.

using C = test_less<int>;
using A1 = test_allocator<int>;
using A2 = other_allocator<int>;
using V1 = std::vector<int, A1>;
using V2 = std::vector<int, A2>;
using V1 = KeyContainer<int, A1>;
using V2 = KeyContainer<int, A2>;
using M1 = std::flat_set<int, C, V1>;
using M2 = std::flat_set<int, C, V2>;
static_assert(std::is_constructible_v<M1, const A1&>);
Expand All @@ -41,14 +44,14 @@ void test() {
}
{
// explicit
using M = std::flat_set<int, std::less<int>, std::vector<int, test_allocator<int>>>;
using M = std::flat_set<int, std::less<int>, KeyContainer<int, test_allocator<int>>>;

static_assert(std::is_constructible_v<M, test_allocator<int>>);
static_assert(!std::is_convertible_v<test_allocator<int>, M>);
}
{
using A = test_allocator<short>;
using M = std::flat_set<int, std::less<int>, std::vector<int, test_allocator<int>>>;
using M = std::flat_set<int, std::less<int>, KeyContainer<int, test_allocator<int>>>;
M m(A(0, 5));
assert(m.empty());
assert(m.begin() == m.end());
Expand All @@ -57,8 +60,21 @@ void test() {
}
}

constexpr bool test() {
test<std::vector>();
#ifndef __cpp_lib_constexpr_deque
if (!TEST_IS_CONSTANT_EVALUATED)
#endif
test<std::deque>();

return true;
}

int main(int, char**) {
test();
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "min_allocator.h"

template <class KeyContainer>
void test_one() {
constexpr void test_one() {
using Key = typename KeyContainer::value_type;
using M = std::flat_set<Key, std::less<Key>, KeyContainer>;
{
Expand All @@ -45,17 +45,25 @@ void test_one() {
}
}

void test() {
constexpr bool test() {
test_one<std::vector<int>>();
test_one<std::vector<int>>();
test_one<std::deque<int>>();
#ifndef __cpp_lib_constexpr_deque
if (!TEST_IS_CONSTANT_EVALUATED)
#endif
test_one<std::deque<int>>();
test_one<MinSequenceContainer<int>>();
test_one<std::vector<int, min_allocator<int>>>();
test_one<std::vector<int, min_allocator<int>>>();

return true;
}

int main(int, char**) {
test();
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Loading
Loading