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 K> pair<iterator,iterator> equal_range(const K& x);
14// template<class K> pair<const_iterator,const_iterator> equal_range(const K& x) const;
15
16#include <cassert>
17#include <deque>
18#include <flat_set>
19#include <functional>
20#include <string>
21#include <utility>
22
23#include "MinSequenceContainer.h"
24#include "../helpers.h"
25#include "test_macros.h"
26#include "min_allocator.h"
27
28// Constraints: The qualified-id Compare::is_transparent is valid and denotes a type.
29template <class M>
30concept CanEqualRange = requires(M m, Transparent<int> k) { m.equal_range(k); };
31using TransparentSet = std::flat_multiset<int, TransparentComparator>;
32using NonTransparentSet = std::flat_multiset<int, NonTransparentComparator>;
33static_assert(CanEqualRange<TransparentSet>);
34static_assert(CanEqualRange<const TransparentSet>);
35static_assert(!CanEqualRange<NonTransparentSet>);
36static_assert(!CanEqualRange<const NonTransparentSet>);
37
38template <class KeyContainer>
39void test_one() {
40 using Key = typename KeyContainer::value_type;
41 using M = std::flat_multiset<Key, TransparentComparator, KeyContainer>;
42
43 using R = std::pair<typename M::iterator, typename M::iterator>;
44 using CR = std::pair<typename M::const_iterator, typename M::const_iterator>;
45
46 auto test_found = [](auto&& set, const std::string& expected_key, long expected_offset, long expected_length) {
47 auto [first, last] = set.equal_range(Transparent<std::string>{.t: expected_key});
48 assert(last - first == expected_length);
49 assert(first - set.begin() == expected_offset);
50 for (auto it = first; it != last; ++it) {
51 assert(*it == expected_key);
52 }
53 };
54
55 auto test_not_found = [](auto&& set, const std::string& expected_key, long expected_offset) {
56 auto [first, last] = set.equal_range(Transparent<std::string>{.t: expected_key});
57 assert(first == last);
58 assert(first - set.begin() == expected_offset);
59 };
60 {
61 M m = {"alpha", "beta", "beta", "beta", "epsilon", "eta", "eta", "eta", "eta", "gamma", "gamma"};
62 const auto& cm = m;
63 ASSERT_SAME_TYPE(decltype(m.equal_range(Transparent<std::string>{"abc"})), R);
64 ASSERT_SAME_TYPE(decltype(std::as_const(m).equal_range(Transparent<std::string>{"b"})), CR);
65
66 test_found(m, "alpha", 0, 1);
67 test_found(m, "beta", 1, 3);
68 test_found(m, "epsilon", 4, 1);
69 test_found(m, "eta", 5, 4);
70 test_found(m, "gamma", 9, 2);
71 test_found(cm, "alpha", 0, 1);
72 test_found(cm, "beta", 1, 3);
73 test_found(cm, "epsilon", 4, 1);
74 test_found(cm, "eta", 5, 4);
75 test_found(cm, "gamma", 9, 2);
76
77 test_not_found(m, "charlie", 4);
78 test_not_found(m, "aaa", 0);
79 test_not_found(m, "zzz", 11);
80 test_not_found(cm, "charlie", 4);
81 test_not_found(cm, "aaa", 0);
82 test_not_found(cm, "zzz", 11);
83 }
84 {
85 // empty
86 M m;
87 const auto& cm = m;
88 test_not_found(m, "aaa", 0);
89 test_not_found(cm, "charlie", 0);
90 }
91}
92
93void test() {
94 test_one<std::vector<std::string>>();
95 test_one<std::deque<std::string>>();
96 test_one<MinSequenceContainer<std::string>>();
97 test_one<std::vector<std::string, min_allocator<std::string>>>();
98
99 {
100 bool transparent_used = false;
101 TransparentComparator c(transparent_used);
102 std::flat_multiset<int, TransparentComparator> m(std::sorted_equivalent, {1, 2, 3, 3, 3}, c);
103 assert(!transparent_used);
104 auto p = m.equal_range(Transparent<int>{3});
105 assert(p.first != p.second);
106 assert(transparent_used);
107 }
108 {
109 // std::string and C string literal
110 using M = std::flat_multiset<std::string, std::less<>>;
111 M m = {"alpha", "beta", "beta", "epsilon", "eta", "gamma"};
112 auto [first, last] = m.equal_range("beta");
113 assert(first == m.begin() + 1);
114 assert(last == m.begin() + 3);
115 }
116}
117
118int main(int, char**) {
119 test();
120
121 return 0;
122}
123

source code of libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/equal_range_transparent.pass.cpp