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... Args>
14// iterator emplace_hint(const_iterator position, Args&&... args);
15
16#include <flat_set>
17#include <cassert>
18#include <deque>
19#include <functional>
20#include <vector>
21
22#include "MinSequenceContainer.h"
23#include "test_macros.h"
24#include "../../../Emplaceable.h"
25#include "DefaultOnly.h"
26#include "min_allocator.h"
27#include "../helpers.h"
28
29template <class KeyContainer>
30void test_one() {
31 using Key = typename KeyContainer::value_type;
32 using M = std::flat_set<Key, std::less<Key>, KeyContainer>;
33 using R = M::iterator;
34 {
35 // was empty
36 M m;
37 std::same_as<R> decltype(auto) r = m.emplace_hint(m.end(), typename M::value_type(2));
38 assert(r == m.begin());
39 assert(m.size() == 1);
40 assert(*r == 2);
41 }
42 {
43 // hints correct at the begin
44 M m = {3, 4};
45 auto hint = m.begin();
46 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));
47 assert(r == m.begin());
48 assert(m.size() == 3);
49 assert(*r == 2);
50 }
51 {
52 // hints correct in the middle
53 M m = {0, 1, 3, 4};
54 auto hint = m.begin() + 2;
55 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));
56 assert(r == m.begin() + 2);
57 assert(m.size() == 5);
58 assert(*r == 2);
59 }
60 {
61 // hints correct at the end
62 M m = {0, 1};
63 auto hint = m.end();
64 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));
65 assert(r == m.begin() + 2);
66 assert(m.size() == 3);
67 assert(*r == 2);
68 }
69 {
70 // hints correct but key already exists
71 M m = {0, 1, 2, 3, 4};
72 auto hint = m.begin() + 2;
73 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));
74 assert(r == m.begin() + 2);
75 assert(m.size() == 5);
76 assert(*r == 2);
77 }
78 {
79 // hints incorrectly at the begin
80 M m = {1, 4};
81 auto hint = m.begin();
82 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));
83 assert(r == m.begin() + 1);
84 assert(m.size() == 3);
85 assert(*r == 2);
86 }
87 {
88 // hints incorrectly in the middle
89 M m = {0, 1, 3, 4};
90 auto hint = m.begin() + 1;
91 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));
92 assert(r == m.begin() + 2);
93 assert(m.size() == 5);
94 assert(*r == 2);
95 }
96 {
97 // hints incorrectly at the end
98 M m = {0, 3};
99 auto hint = m.end();
100 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));
101 assert(r == m.begin() + 1);
102 assert(m.size() == 3);
103 assert(*r == 2);
104 }
105 {
106 // hints incorrect and key already exists
107 M m = {0, 1, 2, 3, 4};
108 auto hint = m.begin();
109 std::same_as<R> decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2));
110 assert(r == m.begin() + 2);
111 assert(m.size() == 5);
112 assert(*r == 2);
113 }
114}
115
116template <class KeyContainer>
117void test_emplaceable() {
118 using M = std::flat_set<Emplaceable, std::less<Emplaceable>, KeyContainer>;
119 using R = M::iterator;
120
121 M m;
122 ASSERT_SAME_TYPE(decltype(m.emplace_hint(m.cbegin())), R);
123 R r = m.emplace_hint(m.end(), 2, 0.0);
124 assert(r == m.begin());
125 assert(m.size() == 1);
126 assert(*m.begin() == Emplaceable(2, 0.0));
127 r = m.emplace_hint(m.end(), 1, 3.5);
128 assert(r == m.begin());
129 assert(m.size() == 2);
130 assert(*m.begin() == Emplaceable(1, 3.5));
131 r = m.emplace_hint(m.end(), 1, 3.5);
132 assert(r == m.begin());
133 assert(m.size() == 2);
134 assert(*m.begin() == Emplaceable(1, 3.5));
135}
136
137void test() {
138 test_one<std::vector<int>>();
139 test_one<std::deque<int>>();
140 test_one<MinSequenceContainer<int>>();
141 test_one<std::vector<int, min_allocator<int>>>();
142
143 test_emplaceable<std::vector<Emplaceable>>();
144 test_emplaceable<std::vector<Emplaceable>>();
145 test_emplaceable<MinSequenceContainer<Emplaceable>>();
146 test_emplaceable<std::vector<Emplaceable, min_allocator<Emplaceable>>>();
147}
148
149void test_exception() {
150 auto emplace_func = [](auto& m, auto key_arg) { m.emplace_hint(m.begin(), key_arg); };
151 test_emplace_exception_guarantee(emplace_function&: emplace_func);
152}
153
154int main(int, char**) {
155 test();
156 test_exception();
157
158 return 0;
159}
160

source code of libcxx/test/std/containers/container.adaptors/flat.set/flat.set.modifiers/emplace_hint.pass.cpp