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

source code of libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.operations/upper_bound_transparent.pass.cpp