Skip to content

Commit f58b918

Browse files
committed
complete tests
1 parent f1f95bd commit f58b918

Some content is hidden

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

45 files changed

+4001
-48
lines changed

libcxx/include/__flat_set/flat_multiset.h

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -375,45 +375,6 @@ class flat_multiset {
375375
} else {
376376
return __emplace_hint(std::move(__hint), _Key(std::forward<_Args>(__args)...));
377377
}
378-
/*
379-
std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...);
380-
381-
auto __prev_larger = __hint != cbegin() && __compare_(__pair.first, (__hint - 1)->first);
382-
auto __next_smaller = __hint != cend() && __compare_(__hint->first, __pair.first);
383-
384-
auto __hint_distance = __hint.__key_iter_ - __containers_.keys.cbegin();
385-
auto __key_iter = __containers_.keys.begin() + __hint_distance;
386-
auto __mapped_iter = __containers_.values.begin() + __hint_distance;
387-
388-
if (!__prev_larger && !__next_smaller) [[likely]] {
389-
// hint correct, just use exact hint iterators
390-
} else if (__prev_larger && !__next_smaller) {
391-
// the hint position is more to the right than the key should have been.
392-
// we want to emplace the element to a position as right as possible
393-
// e.g. Insert new element "2" in the following range
394-
// 1, 1, 2, 2, 2, 3, 4, 6
395-
// ^
396-
// |
397-
// hint
398-
// We want to insert "2" after the last existing "2"
399-
__key_iter = ranges::upper_bound(__containers_.keys.begin(), __key_iter, __pair.first, __compare_);
400-
__mapped_iter = __corresponding_mapped_it(*this, __key_iter);
401-
} else {
402-
_LIBCPP_ASSERT_INTERNAL(!__prev_larger && __next_smaller, "this means that the multiset is not sorted");
403-
404-
// the hint position is more to the left than the key should have been.
405-
// we want to emplace the element to a position as left as possible
406-
// 1, 1, 2, 2, 2, 3, 4, 6
407-
// ^
408-
// |
409-
// hint
410-
// We want to insert "2" before the first existing "2"
411-
__key_iter = ranges::lower_bound(__key_iter, __containers_.keys.end(), __pair.first, __compare_);
412-
__mapped_iter = __corresponding_mapped_it(*this, __key_iter);
413-
}
414-
return __flat_map_utils::__emplace_exact_pos(
415-
*this, __key_iter, __mapped_iter, std::move(__pair.first), std::move(__pair.second));
416-
*/
417378
}
418379

419380
_LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return emplace(__x); }
@@ -641,8 +602,8 @@ class flat_multiset {
641602
if constexpr (!_WasSorted) {
642603
ranges::sort(__keys_.begin() + __old_size, __keys_.end(), __compare_);
643604
} else {
644-
_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted_and_unique(__keys_ | ranges::views::drop(__old_size)),
645-
"Either the key container is not sorted or it contains duplicates");
605+
_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
606+
ranges::is_sorted(__keys_ | ranges::views::drop(__old_size)), "Key container is not sorted");
646607
}
647608
ranges::inplace_merge(__keys_.begin(), __keys_.begin() + __old_size, __keys_.end(), __compare_);
648609
}
@@ -655,6 +616,38 @@ class flat_multiset {
655616
return __flat_set_utils::__emplace_exact_pos(*this, __it, std::forward<_Kp>(__key));
656617
}
657618

619+
template <class _Kp>
620+
_LIBCPP_HIDE_FROM_ABI iterator __emplace_hint(const_iterator __hint, _Kp&& __key) {
621+
auto __prev_larger = __hint != cbegin() && __compare_(__key, *std::prev(__hint));
622+
auto __next_smaller = __hint != cend() && __compare_(*__hint, __key);
623+
624+
if (!__prev_larger && !__next_smaller) [[likely]] {
625+
// hint correct, just use exact hint iterators
626+
} else if (__prev_larger && !__next_smaller) {
627+
// the hint position is more to the right than the key should have been.
628+
// we want to emplace the element to a position as right as possible
629+
// e.g. Insert new element "2" in the following range
630+
// 1, 1, 2, 2, 2, 3, 4, 6
631+
// ^
632+
// |
633+
// hint
634+
// We want to insert "2" after the last existing "2"
635+
__hint = ranges::upper_bound(begin(), __hint, __key, __compare_);
636+
} else {
637+
_LIBCPP_ASSERT_INTERNAL(!__prev_larger && __next_smaller, "this means that the multiset is not sorted");
638+
639+
// the hint position is more to the left than the key should have been.
640+
// we want to emplace the element to a position as left as possible
641+
// 1, 1, 2, 2, 2, 3, 4, 6
642+
// ^
643+
// |
644+
// hint
645+
// We want to insert "2" before the first existing "2"
646+
__hint = ranges::lower_bound(__hint, end(), __key, __compare_);
647+
}
648+
return __flat_set_utils::__emplace_exact_pos(*this, __hint, std::forward<_Kp>(__key));
649+
}
650+
658651
template <class _Self, class _Kp>
659652
_LIBCPP_HIDE_FROM_ABI static auto __find_impl(_Self&& __self, const _Kp& __key) {
660653
auto __it = __self.lower_bound(__key);
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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_multiset(container_type , const key_compare& __comp = key_compare())
17+
// flat_multiset(const container_type& , const _Allocator& )
18+
// flat_multiset(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_multiset<int>;
33+
34+
TEST_LIBCPP_ASSERT_FAILURE(([] { M m(std::sorted_equivalent, {4, 2, 3}); }()), "Key container is not sorted");
35+
36+
TEST_LIBCPP_ASSERT_FAILURE(
37+
([] { M m(std::sorted_equivalent, {4, 2, 3}, std::less<int>{}); }()), "Key container is not sorted");
38+
39+
TEST_LIBCPP_ASSERT_FAILURE(
40+
([] {
41+
const std::vector keys{4, 2, 3};
42+
const std::allocator<int> alloc{};
43+
M m(std::sorted_equivalent, keys, alloc);
44+
}()),
45+
"Key container is not sorted");
46+
47+
TEST_LIBCPP_ASSERT_FAILURE(
48+
([] {
49+
const std::vector keys{4, 2, 3};
50+
const std::allocator<int> alloc{};
51+
const std::less<int> comp{};
52+
M m(std::sorted_equivalent, keys, comp, alloc);
53+
}()),
54+
"Key container is not sorted");
55+
56+
TEST_LIBCPP_ASSERT_FAILURE(
57+
([] {
58+
const std::vector<int> v{4, 2, 3};
59+
const std::less<int> comp{};
60+
M m(std::sorted_equivalent, v.begin(), v.end(), comp);
61+
}()),
62+
"Key container is not sorted");
63+
64+
TEST_LIBCPP_ASSERT_FAILURE(
65+
([] {
66+
const std::vector<int> v{4, 2, 3};
67+
const std::less<int> comp{};
68+
const std::allocator<int> alloc{};
69+
M m(std::sorted_equivalent, v.begin(), v.end(), comp, alloc);
70+
}()),
71+
"Key container is not sorted");
72+
73+
TEST_LIBCPP_ASSERT_FAILURE(
74+
([] {
75+
const std::vector<int> v{4, 2, 3};
76+
const std::allocator<int> alloc{};
77+
M m(std::sorted_equivalent, v.begin(), v.end(), alloc);
78+
}()),
79+
"Key container is not sorted");
80+
81+
TEST_LIBCPP_ASSERT_FAILURE(
82+
([] {
83+
std::initializer_list<int> v{4, 2, 3};
84+
const std::less<int> comp{};
85+
M m(std::sorted_equivalent, v, comp);
86+
}()),
87+
"Key container is not sorted");
88+
89+
TEST_LIBCPP_ASSERT_FAILURE(
90+
([] {
91+
std::initializer_list<int> v{4, 2, 3};
92+
const std::less<int> comp{};
93+
const std::allocator<int> alloc{};
94+
M m(std::sorted_equivalent, v, comp, alloc);
95+
}()),
96+
"Key container is not sorted");
97+
98+
TEST_LIBCPP_ASSERT_FAILURE(
99+
([] {
100+
std::initializer_list<int> v{4, 2, 3};
101+
const std::allocator<int> alloc{};
102+
M m(std::sorted_equivalent, v, alloc);
103+
}()),
104+
"Key container is not sorted");
105+
106+
TEST_LIBCPP_ASSERT_FAILURE(
107+
([] {
108+
const std::vector<int> v{4, 2, 3};
109+
M m;
110+
m.insert(std::sorted_equivalent, v.begin(), v.end());
111+
}()),
112+
"Key container is not sorted");
113+
114+
TEST_LIBCPP_ASSERT_FAILURE(
115+
([] {
116+
std::initializer_list<int> v{4, 2, 3};
117+
M m;
118+
m.insert(std::sorted_equivalent, v);
119+
}()),
120+
"Key container is not sorted");
121+
122+
TEST_LIBCPP_ASSERT_FAILURE(
123+
([] {
124+
std::vector keys{2, 1, 3};
125+
M m;
126+
m.replace(std::move(keys));
127+
}()),
128+
"Key container is not sorted");
129+
130+
return 0;
131+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9+
10+
// <flat_set>
11+
12+
// test that iterators from different types of flat_multiset are not compatible
13+
14+
#include <deque>
15+
#include <functional>
16+
#include <flat_set>
17+
#include <type_traits>
18+
19+
using Iter1 = std::flat_multiset<int>::iterator;
20+
using Iter2 = std::flat_multiset<double>::iterator;
21+
using Iter3 = std::flat_multiset<int, std::greater<>>::iterator;
22+
using Iter4 = std::flat_multiset<int, std::less<int>, std::deque<int>>::iterator;
23+
24+
static_assert(std::is_convertible_v<Iter1, Iter1>);
25+
static_assert(!std::is_convertible_v<Iter1, Iter2>);
26+
static_assert(!std::is_convertible_v<Iter1, Iter3>);
27+
static_assert(!std::is_convertible_v<Iter1, Iter4>);
28+
29+
static_assert(!std::is_convertible_v<Iter2, Iter1>);
30+
static_assert(std::is_convertible_v<Iter2, Iter2>);
31+
static_assert(!std::is_convertible_v<Iter2, Iter3>);
32+
static_assert(!std::is_convertible_v<Iter2, Iter4>);
33+
34+
static_assert(!std::is_convertible_v<Iter3, Iter1>);
35+
static_assert(!std::is_convertible_v<Iter3, Iter2>);
36+
static_assert(std::is_convertible_v<Iter3, Iter3>);
37+
static_assert(!std::is_convertible_v<Iter3, Iter4>);
38+
39+
static_assert(!std::is_convertible_v<Iter4, Iter1>);
40+
static_assert(!std::is_convertible_v<Iter4, Iter2>);
41+
static_assert(!std::is_convertible_v<Iter4, Iter3>);
42+
static_assert(std::is_convertible_v<Iter4, Iter4>);
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_multiset<int> c;
19+
c.empty(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
20+
}

libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/pmr.pass.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ void test() {
5454
assert(std::move(vm[0]).extract().get_allocator().resource() == &mr);
5555
}
5656
{
57-
// flat_multiset(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
58-
// const Allocator& a);
57+
// flat_multiset(const container_type& key_cont, const Allocator& a);
5958
using M = std::flat_multiset<int, std::less<int>, std::pmr::vector<int>>;
6059
std::pmr::monotonic_buffer_resource mr;
6160
std::pmr::vector<M> vm(&mr);

0 commit comments

Comments
 (0)