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// flat_multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
14// template<class Alloc>
15// flat_multimap(initializer_list<value_type> il, const Alloc& a);
16// template<class Alloc>
17// flat_multimap(initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
18
19#include <algorithm>
20#include <cassert>
21#include <deque>
22#include <flat_map>
23#include <functional>
24#include <type_traits>
25#include <vector>
26
27#include "test_macros.h"
28#include "min_allocator.h"
29#include "test_allocator.h"
30
31#include "../../../test_compare.h"
32
33struct DefaultCtableComp {
34 explicit DefaultCtableComp() { default_constructed_ = true; }
35 bool operator()(int, int) const { return false; }
36 bool default_constructed_ = false;
37};
38
39int main(int, char**) {
40 {
41 // The constructors in this subclause shall not participate in overload
42 // resolution unless uses_allocator_v<key_container_type, Alloc> is true
43 // and uses_allocator_v<mapped_container_type, Alloc> is true.
44
45 using C = test_less<int>;
46 using A1 = test_allocator<int>;
47 using A2 = other_allocator<int>;
48 using V1 = std::vector<int, A1>;
49 using V2 = std::vector<int, A2>;
50 using M1 = std::flat_multimap<int, int, C, V1, V1>;
51 using M2 = std::flat_multimap<int, int, C, V1, V2>;
52 using M3 = std::flat_multimap<int, int, C, V2, V1>;
53 using IL = std::initializer_list<std::pair<int, int>>;
54 static_assert(std::is_constructible_v<M1, IL, const A1&>);
55 static_assert(!std::is_constructible_v<M1, IL, const A2&>);
56 static_assert(!std::is_constructible_v<M2, IL, const A2&>);
57 static_assert(!std::is_constructible_v<M3, IL, const A2&>);
58
59 static_assert(std::is_constructible_v<M1, IL, const C&, const A1&>);
60 static_assert(!std::is_constructible_v<M1, IL, const C&, const A2&>);
61 static_assert(!std::is_constructible_v<M2, IL, const C&, const A2&>);
62 static_assert(!std::is_constructible_v<M3, IL, const C&, const A2&>);
63 }
64
65 {
66 // initializer_list<value_type> needs to match exactly
67 using M = std::flat_multimap<int, short>;
68 using C = typename M::key_compare;
69 static_assert(std::is_constructible_v<M, std::initializer_list<std::pair<int, short>>>);
70 static_assert(std::is_constructible_v<M, std::initializer_list<std::pair<int, short>>, C>);
71 static_assert(std::is_constructible_v<M, std::initializer_list<std::pair<int, short>>, C, std::allocator<int>>);
72 static_assert(std::is_constructible_v<M, std::initializer_list<std::pair<int, short>>, std::allocator<int>>);
73 static_assert(!std::is_constructible_v<M, std::initializer_list<std::pair<const int, short>>>);
74 static_assert(!std::is_constructible_v<M, std::initializer_list<std::pair<const int, short>>, C>);
75 static_assert(
76 !std::is_constructible_v<M, std::initializer_list<std::pair<const int, short>>, C, std::allocator<int>>);
77 static_assert(!std::is_constructible_v<M, std::initializer_list<std::pair<const int, short>>, std::allocator<int>>);
78 static_assert(!std::is_constructible_v<M, std::initializer_list<std::pair<const int, const short>>>);
79 static_assert(!std::is_constructible_v<M, std::initializer_list<std::pair<const int, const short>>, C>);
80 static_assert(
81 !std::is_constructible_v<M, std::initializer_list<std::pair<const int, const short>>, C, std::allocator<int>>);
82 static_assert(
83 !std::is_constructible_v<M, std::initializer_list<std::pair<const int, const short>>, std::allocator<int>>);
84 }
85
86 std::pair<int, short> expected[] = {{1, 1}, {2, 2}, {2, 2}, {3, 3}, {3, 3}, {5, 2}};
87 {
88 // flat_multimap(initializer_list<value_type>);
89 using M = std::flat_multimap<int, short>;
90 std::initializer_list<std::pair<int, short>> il = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
91 M m(il);
92 assert(std::ranges::equal(m, expected));
93 }
94 {
95 // flat_multimap(initializer_list<value_type>);
96 // explicit(false)
97 using M = std::flat_multimap<int, short>;
98 M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
99 assert(std::ranges::equal(m, expected));
100 }
101 {
102 // flat_multimap(initializer_list<value_type>);
103 using M = std::flat_multimap<int, short, std::greater<int>, std::deque<int, min_allocator<int>>>;
104 M m = {{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}};
105 assert(std::equal(m.rbegin(), m.rend(), expected, expected + 6));
106 }
107 {
108 using A = explicit_allocator<int>;
109 {
110 // flat_multimap(initializer_list<value_type>);
111 // different comparator
112 using M = std::flat_multimap<int, int, DefaultCtableComp, std::vector<int, A>, std::deque<int, A>>;
113 M m = {{1, 1}, {2, 2}, {3, 3}};
114 assert(m.size() == 3);
115
116 std::pair<int, int> expected1[] = {{1, 1}, {2, 2}, {3, 3}};
117 assert(std::ranges::equal(m, expected1));
118 assert(m.key_comp().default_constructed_);
119 }
120 {
121 // flat_multimap(initializer_list<value_type>, const Allocator&);
122 using M = std::flat_multimap<int, int, std::greater<int>, std::deque<int, A>, std::vector<int, A>>;
123 A a;
124 M m({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, a);
125 assert(std::equal(m.rbegin(), m.rend(), expected, expected + 6));
126 }
127 }
128 {
129 // flat_multimap(initializer_list<value_type>, const key_compare&);
130 using C = test_less<int>;
131 using M = std::flat_multimap<int, short, C>;
132 auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, C(10));
133 assert(std::ranges::equal(m, expected));
134 assert(m.key_comp() == C(10));
135
136 // explicit(false)
137 M m2 = {{{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, C(10)};
138 assert(m2 == m);
139 assert(m2.key_comp() == C(10));
140 }
141 {
142 // flat_multimap(initializer_list<value_type>, const key_compare&);
143 // Sorting uses the comparator that was passed in
144 using M = std::flat_multimap<int, short, std::function<bool(int, int)>, std::deque<int, min_allocator<int>>>;
145 auto m = M({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, std::greater<int>());
146 assert(std::equal(m.rbegin(), m.rend(), expected, expected + 6));
147 assert(m.key_comp()(2, 1) == true);
148 }
149 {
150 // flat_multimap(initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
151 using A = explicit_allocator<int>;
152 using M = std::flat_multimap<int, int, std::greater<int>, std::deque<int, A>, std::vector<int, A>>;
153 A a;
154 M m({{5, 2}, {2, 2}, {2, 2}, {3, 3}, {1, 1}, {3, 3}}, {}, a);
155 assert(std::equal(m.rbegin(), m.rend(), expected, expected + 6));
156 }
157
158 return 0;
159}
160

source code of libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp