411 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 11// <flat_set>12 13#include <algorithm>14#include <cassert>15#include <climits>16#include <deque>17#include <initializer_list>18#include <list>19#include <flat_set>20#include <functional>21#include <ranges>22#include <type_traits>23#include <utility>24#include <vector>25 26#include "deduction_guides_sfinae_checks.h"27#include "test_allocator.h"28 29void test() {30 {31 // Deduction guide generated from32 // flat_multiset(const flat_multiset&)33 std::flat_multiset<long> source = {1, 2, 2};34 std::flat_multiset s(source);35 ASSERT_SAME_TYPE(decltype(s), decltype(source));36 assert(s == source);37 }38 {39 // Deduction guide generated from40 // flat_multiset(const flat_multiset&)41 // braces instead of parens42 std::flat_multiset<short, std::greater<short>> source = {1, 2, 2};43 std::flat_multiset s{source};44 ASSERT_SAME_TYPE(decltype(s), decltype(source));45 assert(s == source);46 }47 {48 // Deduction guide generated from49 // flat_set(const flat_set&, const Allocator&)50 std::flat_multiset<long, std::greater<long>> source = {1, 2, 2};51 std::flat_multiset s(source, std::allocator<int>());52 ASSERT_SAME_TYPE(decltype(s), decltype(source));53 assert(s == source);54 }55 {56 std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));57 std::deque<int, test_allocator<int>> sorted_ks({1, 1, 2, 3, INT_MAX}, test_allocator<int>(0, 42));58 int expected[] = {1, 1, 2, 3, INT_MAX};59 {60 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>61 // flat_multiset(KeyContainer, Compare = Compare())62 // -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;63 std::flat_multiset s(ks);64 65 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::less<int>, decltype(ks)>);66 assert(std::ranges::equal(s, expected));67 assert(std::move(s).extract().get_allocator().get_id() == 42);68 }69 {70 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>71 // flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare())72 // -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;73 std::flat_multiset s(std::sorted_equivalent, sorted_ks);74 75 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::less<int>, decltype(ks)>);76 assert(std::ranges::equal(s, expected));77 assert(std::move(s).extract().get_allocator().get_id() == 42);78 }79 {80 // template<class KeyContainer, class Allocator>81 // flat_multiset(KeyContainer, Allocator)82 // -> flat_multiset<typename KeyContainer::value_type,83 // less<typename KeyContainer::value_type>, KeyContainer>;84 std::flat_multiset s(ks, test_allocator<long>(0, 44));85 86 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::less<int>, decltype(ks)>);87 assert(std::ranges::equal(s, expected));88 assert(std::move(s).extract().get_allocator().get_id() == 44);89 }90 {91 // template<class KeyContainer, class Allocator>92 // flat_multiset(sorted_equivalent_t, KeyContainer, Allocator)93 // -> flat_multiset<typename KeyContainer::value_type,94 // less<typename KeyContainer::value_type>, KeyContainer>;95 std::flat_multiset s(std::sorted_equivalent, sorted_ks, test_allocator<long>(0, 44));96 97 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::less<int>, decltype(ks)>);98 assert(std::ranges::equal(s, expected));99 assert(std::move(s).extract().get_allocator().get_id() == 44);100 }101 }102 {103 std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));104 std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 1, 1}, test_allocator<int>(0, 42));105 int expected[] = {INT_MAX, 3, 2, 1, 1};106 {107 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>108 // flat_multiset(KeyContainer, Compare = Compare())109 // -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;110 std::flat_multiset s(ks, std::greater<int>());111 112 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::greater<int>, decltype(ks)>);113 assert(std::ranges::equal(s, expected));114 assert(std::move(s).extract().get_allocator().get_id() == 42);115 }116 {117 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>118 // flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare())119 // -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;120 121 std::flat_multiset s(std::sorted_equivalent, sorted_ks, std::greater<int>());122 123 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::greater<int>, decltype(ks)>);124 assert(std::ranges::equal(s, expected));125 assert(std::move(s).extract().get_allocator().get_id() == 42);126 }127 {128 // template<class KeyContainer, class Compare, class Allocator>129 // flat_multiset(KeyContainer, Compare, Allocator)130 // -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;131 std::flat_multiset s(ks, std::greater<int>(), test_allocator<long>(0, 44));132 133 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::greater<int>, decltype(ks)>);134 assert(std::ranges::equal(s, expected));135 assert(std::move(s).extract().get_allocator().get_id() == 44);136 }137 {138 // template<class KeyContainer, class Compare, class Allocator>139 // flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator)140 // -> flat_multiset<typename KeyContainer::value_type, Compare, KeyContainer>;141 std::flat_multiset s(std::sorted_equivalent, sorted_ks, std::greater<int>(), test_allocator<long>(0, 44));142 143 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::greater<int>, decltype(ks)>);144 assert(std::ranges::equal(s, expected));145 assert(std::move(s).extract().get_allocator().get_id() == 44);146 }147 }148 149 {150 int arr[] = {1, 2, 1, INT_MAX, 3};151 int sorted_arr[] = {1, 1, 2, 3, INT_MAX};152 const int arrc[] = {1, 2, 1, INT_MAX, 3};153 const int sorted_arrc[] = {1, 1, 2, 3, INT_MAX};154 {155 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>156 // flat_multiset(InputIterator, InputIterator, Compare = Compare())157 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;158 std::flat_multiset m(std::begin(arr), std::end(arr));159 160 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int>);161 assert(std::ranges::equal(m, sorted_arr));162 }163 {164 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>165 // flat_multiset(InputIterator, InputIterator, Compare = Compare())166 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;167 // const168 std::flat_multiset m(std::begin(arrc), std::end(arrc));169 170 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int>);171 assert(std::ranges::equal(m, sorted_arr));172 }173 {174 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>175 // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())176 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;177 std::flat_multiset m(std::sorted_equivalent, std::begin(sorted_arr), std::end(sorted_arr));178 179 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int>);180 assert(std::ranges::equal(m, sorted_arr));181 }182 {183 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>184 // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())185 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;186 // const187 std::flat_multiset m(std::sorted_equivalent, std::begin(sorted_arrc), std::end(sorted_arrc));188 189 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int>);190 assert(std::ranges::equal(m, sorted_arr));191 }192 {193 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>194 // flat_multiset(InputIterator, InputIterator, Compare = Compare())195 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;196 // flat_multiset iterator197 std::flat_multiset<int> mo;198 std::flat_multiset m(mo.begin(), mo.end());199 ASSERT_SAME_TYPE(decltype(m), decltype(mo));200 }201 {202 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>203 // flat_multiset(InputIterator, InputIterator, Compare = Compare())204 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;205 // flat_multiset const_iterator206 std::flat_multiset<int> mo;207 std::flat_multiset m(mo.cbegin(), mo.cend());208 ASSERT_SAME_TYPE(decltype(m), decltype(mo));209 }210 {211 // This does not deduce to flat_multiset(InputIterator, InputIterator)212 // But deduces to flat_multiset(initializer_list<int*>)213 int source[3] = {1, 2, 3};214 std::flat_multiset s = {source, source + 3};215 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int*>);216 assert(s.size() == 2);217 }218 {219 // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator)220 // braces221 int source[3] = {1, 2, 3};222 std::flat_multiset s{std::sorted_equivalent, source, source + 3};223 static_assert(std::is_same_v<decltype(s), std::flat_multiset<int>>);224 assert(s.size() == 3);225 }226 }227 228 {229 int arr[] = {1, 2, 1, INT_MAX, 3};230 int sorted_arr[] = {INT_MAX, 3, 2, 1, 1};231 const int arrc[] = {1, 2, 1, INT_MAX, 3};232 const int sorted_arrc[] = {INT_MAX, 3, 2, 1, 1};233 using C = std::greater<long>;234 {235 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>236 // flat_multiset(InputIterator, InputIterator, Compare = Compare())237 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;238 std::flat_multiset m(std::begin(arr), std::end(arr), C());239 240 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int, C>);241 assert(std::ranges::equal(m, sorted_arr));242 }243 {244 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>245 // flat_multiset(InputIterator, InputIterator, Compare = Compare())246 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;247 // const248 std::flat_multiset m(std::begin(arrc), std::end(arrc), C());249 250 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int, C>);251 assert(std::ranges::equal(m, sorted_arr));252 }253 {254 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>255 // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())256 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;257 std::flat_multiset m(std::sorted_equivalent, std::begin(sorted_arr), std::end(sorted_arr), C());258 259 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int, C>);260 assert(std::ranges::equal(m, sorted_arr));261 }262 {263 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>264 // flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())265 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;266 // const267 std::flat_multiset m(std::sorted_equivalent, std::begin(sorted_arrc), std::end(sorted_arrc), C());268 269 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int, C>);270 assert(std::ranges::equal(m, sorted_arr));271 }272 {273 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>274 // flat_multiset(InputIterator, InputIterator, Compare = Compare())275 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;276 // flat_multiset iterator277 std::flat_multiset<int> mo;278 std::flat_multiset m(mo.begin(), mo.end(), C());279 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int, C>);280 }281 {282 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>283 // flat_multiset(InputIterator, InputIterator, Compare = Compare())284 // -> flat_multiset<iter-value-type<InputIterator>, Compare>;285 // flat_multiset const_iterator286 std::flat_multiset<int> mo;287 std::flat_multiset m(mo.cbegin(), mo.cend(), C());288 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int, C>);289 }290 }291 {292 const int sorted_arr[] = {1, 1, 2, 3, INT_MAX};293 {294 // template<class Key, class Compare = less<Key>>295 // flat_multiset(initializer_list<Key>, Compare = Compare())296 // -> flat_multiset<Key, Compare>;297 std::flat_multiset m{1, 2, 1, INT_MAX, 3};298 299 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int>);300 assert(std::ranges::equal(m, sorted_arr));301 }302 {303 // template<class Key, class Compare = less<Key>>304 // flat_multiset(sorted_equivalent_t, initializer_list<Key>, Compare = Compare())305 // -> flat_multiset<Key, Compare>;306 std::flat_multiset m(std::sorted_equivalent, {1, 1, 2, 3, INT_MAX});307 308 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int>);309 assert(std::ranges::equal(m, sorted_arr));310 }311 {312 // One element with brace was treated as initializer_list313 std::flat_multiset s = {1};314 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int>);315 assert(s.size() == 1);316 }317 {318 // Two elements with brace was treated as initializer_list319 using M = std::flat_multiset<int>;320 M m;321 std::flat_multiset s{m, m}; // flat_multiset(initializer_list<M>)322 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<M>);323 assert(s.size() == 2);324 }325 }326 {327 const int sorted_arr[] = {INT_MAX, 3, 2, 1, 1};328 using C = std::greater<long>;329 {330 // template<class Key, class Compare = less<Key>>331 // flat_multiset(initializer_list<Key>, Compare = Compare())332 // -> flat_multiset<Key, Compare>;333 std::flat_multiset m({1, 2, 1, INT_MAX, 3}, C());334 335 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int, C>);336 assert(std::ranges::equal(m, sorted_arr));337 }338 {339 // template<class Key, class Compare = less<Key>>340 // flat_multiset(sorted_equivalent_t, initializer_list<Key>, Compare = Compare())341 // -> flat_multiset<Key, Compare>;342 std::flat_multiset m(std::sorted_equivalent, {INT_MAX, 3, 2, 1, 1}, C());343 344 ASSERT_SAME_TYPE(decltype(m), std::flat_multiset<int, C>);345 assert(std::ranges::equal(m, sorted_arr));346 }347 }348 {349 std::list<int> r = {1, 2, 1, INT_MAX, 3};350 const int expected[] = {1, 1, 2, 3, INT_MAX};351 {352 // template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,353 // class Allocator = allocator<ranges::range_value_t<R>>>354 // flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())355 // -> flat_multiset<ranges::range_value_t<R>, Compare,356 // vector<ranges::range_value_t<R>,357 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;358 std::flat_multiset s(std::from_range, r);359 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::less<int>>);360 assert(std::ranges::equal(s, expected));361 }362 {363 // template<ranges::input_range R, class Allocator>364 // flat_multiset(from_range_t, R&&, Allocator)365 // -> flat_multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,366 // vector<ranges::range_value_t<R>,367 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;368 std::flat_multiset s(std::from_range, r, test_allocator<long>(0, 42));369 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::less<int>, std::vector<int, test_allocator<int>>>);370 assert(std::ranges::equal(s, expected));371 assert(std::move(s).extract().get_allocator().get_id() == 42);372 }373 }374 375 {376 // with comparator377 std::list<int> r = {1, 2, 1, INT_MAX, 3};378 const int expected[] = {INT_MAX, 3, 2, 1, 1};379 {380 // template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,381 // class Allocator = allocator<ranges::range_value_t<R>>>382 // flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())383 // -> flat_multiset<ranges::range_value_t<R>, Compare,384 // vector<ranges::range_value_t<R>,385 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;386 std::flat_multiset s(std::from_range, r, std::greater<int>());387 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::greater<int>>);388 assert(std::ranges::equal(s, expected));389 }390 {391 // template<ranges::input_range R, class Allocator>392 // flat_multiset(from_range_t, R&&, Allocator)393 // -> flat_multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,394 // vector<ranges::range_value_t<R>,395 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;396 std::flat_multiset s(std::from_range, r, std::greater<int>(), test_allocator<long>(0, 42));397 ASSERT_SAME_TYPE(decltype(s), std::flat_multiset<int, std::greater<int>, std::vector<int, test_allocator<int>>>);398 assert(std::ranges::equal(s, expected));399 assert(std::move(s).extract().get_allocator().get_id() == 42);400 }401 }402 403 AssociativeContainerDeductionGuidesSfinaeAway<std::flat_multiset, std::flat_multiset<int>>();404}405 406int main(int, char**) {407 test();408 409 return 0;410}411