387 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_set(const flat_set&)33 std::flat_set<long> source = {1, 2};34 std::flat_set s(source);35 ASSERT_SAME_TYPE(decltype(s), decltype(source));36 assert(s == source);37 }38 {39 // deduction guide generated from40 // flat_set(const flat_set&)41 std::flat_set<short, std::greater<short>> source = {1, 2};42 std::flat_set s{source}; // braces instead of parens43 ASSERT_SAME_TYPE(decltype(s), decltype(source));44 assert(s == source);45 }46 {47 // deduction guide generated from48 // flat_set(const flat_set&, const Allocator&)49 std::flat_set<long, std::greater<long>> source = {1, 2};50 std::flat_set s(source, std::allocator<int>());51 ASSERT_SAME_TYPE(decltype(s), decltype(source));52 assert(s == source);53 }54 55 {56 // various overloads that takes a container57 std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));58 std::deque<int, test_allocator<int>> sorted_ks({1, 2, 3, INT_MAX}, test_allocator<int>(0, 42));59 int expected[] = {1, 2, 3, INT_MAX};60 {61 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>62 // flat_set(KeyContainer, Compare = Compare())63 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;64 std::flat_set s(ks);65 66 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, decltype(ks)>);67 assert(std::ranges::equal(s, expected));68 assert(std::move(s).extract().get_allocator().get_id() == 42);69 }70 {71 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>72 // flat_set(sorted_unique_t, KeyContainer, Compare = Compare())73 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;74 std::flat_set s(std::sorted_unique, sorted_ks);75 76 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, decltype(ks)>);77 assert(std::ranges::equal(s, expected));78 assert(std::move(s).extract().get_allocator().get_id() == 42);79 }80 {81 // template<class KeyContainer, class Allocator>82 // flat_set(KeyContainer, Allocator)83 // -> flat_set<typename KeyContainer::value_type,84 // less<typename KeyContainer::value_type>, KeyContainer>;85 std::flat_set s(ks, test_allocator<long>(0, 44));86 87 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, decltype(ks)>);88 assert(std::ranges::equal(s, expected));89 assert(std::move(s).extract().get_allocator().get_id() == 44);90 }91 {92 // template<class KeyContainer, class Allocator>93 // flat_set(sorted_unique_t, KeyContainer, Allocator)94 // -> flat_set<typename KeyContainer::value_type,95 // less<typename KeyContainer::value_type>, KeyContainer>;96 std::flat_set s(std::sorted_unique, sorted_ks, test_allocator<long>(0, 44));97 98 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, decltype(ks)>);99 assert(std::ranges::equal(s, expected));100 assert(std::move(s).extract().get_allocator().get_id() == 44);101 }102 }103 {104 // various overloads that takes a container and a comparator105 std::deque<int, test_allocator<int>> ks({1, 2, 1, INT_MAX, 3}, test_allocator<int>(0, 42));106 std::deque<int, test_allocator<int>> sorted_ks({INT_MAX, 3, 2, 1}, test_allocator<int>(0, 42));107 int expected[] = {INT_MAX, 3, 2, 1};108 {109 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>110 // flat_set(KeyContainer, Compare = Compare())111 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;112 std::flat_set s(ks, std::greater<int>());113 114 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, decltype(ks)>);115 assert(std::ranges::equal(s, expected));116 assert(std::move(s).extract().get_allocator().get_id() == 42);117 }118 {119 // template<class KeyContainer, class Compare = less<typename KeyContainer::value_type>>120 // flat_set(sorted_unique_t, KeyContainer, Compare = Compare())121 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;122 std::flat_set s(std::sorted_unique, sorted_ks, std::greater<int>());123 124 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, decltype(ks)>);125 assert(std::ranges::equal(s, expected));126 assert(std::move(s).extract().get_allocator().get_id() == 42);127 }128 {129 // template<class KeyContainer, class Compare, class Allocator>130 // flat_set(KeyContainer, Compare, Allocator)131 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;132 std::flat_set s(ks, std::greater<int>(), test_allocator<long>(0, 44));133 134 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, decltype(ks)>);135 assert(std::ranges::equal(s, expected));136 assert(std::move(s).extract().get_allocator().get_id() == 44);137 }138 {139 // template<class KeyContainer, class Compare, class Allocator>140 // flat_set(sorted_unique_t, KeyContainer, Compare, Allocator)141 // -> flat_set<typename KeyContainer::value_type, Compare, KeyContainer>;142 std::flat_set s(std::sorted_unique, sorted_ks, std::greater<int>(), test_allocator<long>(0, 44));143 144 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, decltype(ks)>);145 assert(std::ranges::equal(s, expected));146 assert(std::move(s).extract().get_allocator().get_id() == 44);147 }148 }149 {150 // overloads that take pair of iterators151 int arr[] = {1, 2, 1, INT_MAX, 3};152 int sorted_arr[] = {1, 2, 3, INT_MAX};153 const int arrc[] = {1, 2, 1, INT_MAX, 3};154 const int sorted_arrc[] = {1, 2, 3, INT_MAX};155 {156 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>157 // flat_set(InputIterator, InputIterator, Compare = Compare())158 // -> flat_set<iter-value-type<InputIterator>, Compare>;159 std::flat_set m(std::begin(arr), std::end(arr));160 161 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);162 assert(std::ranges::equal(m, sorted_arr));163 }164 {165 // const166 std::flat_set m(std::begin(arrc), std::end(arrc));167 168 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);169 assert(std::ranges::equal(m, sorted_arr));170 }171 {172 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>173 // flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())174 // -> flat_set<iter-value-type<InputIterator>, Compare>;175 std::flat_set m(std::sorted_unique, std::begin(sorted_arr), std::end(sorted_arr));176 177 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);178 assert(std::ranges::equal(m, sorted_arr));179 }180 {181 // const182 std::flat_set m(std::sorted_unique, std::begin(sorted_arrc), std::end(sorted_arrc));183 184 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);185 assert(std::ranges::equal(m, sorted_arr));186 }187 {188 // from flat_set::iterator189 std::flat_set<int> mo;190 std::flat_set m(mo.begin(), mo.end());191 ASSERT_SAME_TYPE(decltype(m), decltype(mo));192 }193 {194 // from flat_set::const_iterator195 std::flat_set<int> mo;196 std::flat_set m(mo.cbegin(), mo.cend());197 ASSERT_SAME_TYPE(decltype(m), decltype(mo));198 }199 {200 // This does not deduce to flat_set(InputIterator, InputIterator)201 // But deduces to flat_set(initializer_list<int*>)202 std::flat_set s = {arr, arr + 3};203 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int*>);204 assert(s.size() == 2);205 }206 {207 // This deduces to flat_set(sorted_unique_t, InputIterator, InputIterator)208 std::flat_set s{std::sorted_unique, sorted_arr, sorted_arr + 3};209 static_assert(std::is_same_v<decltype(s), std::flat_set<int>>);210 assert(s.size() == 3);211 }212 }213 {214 // overloads that take pair of iterators and comparator215 int arr[] = {1, 2, 1, INT_MAX, 3};216 int sorted_arr[] = {INT_MAX, 3, 2, 1};217 const int arrc[] = {1, 2, 1, INT_MAX, 3};218 const int sorted_arrc[] = {INT_MAX, 3, 2, 1};219 using C = std::greater<long>;220 {221 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>222 // flat_set(InputIterator, InputIterator, Compare = Compare())223 // -> flat_set<iter-value-type<InputIterator>, Compare>;224 std::flat_set m(std::begin(arr), std::end(arr), C());225 226 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);227 assert(std::ranges::equal(m, sorted_arr));228 }229 {230 // const231 std::flat_set m(std::begin(arrc), std::end(arrc), C());232 233 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);234 assert(std::ranges::equal(m, sorted_arr));235 }236 {237 // template<class InputIterator, class Compare = less<iter-value-type<InputIterator>>>238 // flat_set(sorted_unique_t, InputIterator, InputIterator, Compare = Compare())239 // -> flat_set<iter-value-type<InputIterator>, Compare>;240 std::flat_set m(std::sorted_unique, std::begin(sorted_arr), std::end(sorted_arr), C());241 242 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);243 assert(std::ranges::equal(m, sorted_arr));244 }245 {246 // const247 std::flat_set m(std::sorted_unique, std::begin(sorted_arrc), std::end(sorted_arrc), C());248 249 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);250 assert(std::ranges::equal(m, sorted_arr));251 }252 {253 // from flat_set::iterator254 std::flat_set<int> mo;255 std::flat_set m(mo.begin(), mo.end(), C());256 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);257 }258 {259 // from flat_set::const_iterator260 std::flat_set<int> mo;261 std::flat_set m(mo.cbegin(), mo.cend(), C());262 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);263 }264 }265 {266 // overloads that take an initializer_list267 const int sorted_arr[] = {1, 2, 3, INT_MAX};268 {269 // template<class Key, class Compare = less<Key>>270 // flat_set(initializer_list<Key>, Compare = Compare())271 // -> flat_set<Key, Compare>;272 std::flat_set m{1, 2, 1, INT_MAX, 3};273 274 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);275 assert(std::ranges::equal(m, sorted_arr));276 }277 {278 // template<class Key, class Compare = less<Key>>279 // flat_set(sorted_unique_t, initializer_list<Key>, Compare = Compare())280 // -> flat_set<Key, Compare>;281 std::flat_set m(std::sorted_unique, {1, 2, 3, INT_MAX});282 283 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int>);284 assert(std::ranges::equal(m, sorted_arr));285 }286 {287 // one argument/element of an int -> should be treated as an initializer_list<int>288 std::flat_set s = {1};289 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int>);290 assert(s.size() == 1);291 }292 {293 // two of the flat_sets -> should be treated as an initializer_list<flat_set<int>>294 using M = std::flat_set<int>;295 M m;296 std::flat_set s{m, m}; // flat_set(initializer_list<M>)297 ASSERT_SAME_TYPE(decltype(s), std::flat_set<M>);298 assert(s.size() == 1);299 }300 }301 {302 // overloads that take an initializer_list and a comparator303 const int sorted_arr[] = {INT_MAX, 3, 2, 1};304 using C = std::greater<long>;305 {306 // template<class Key, class Compare = less<Key>>307 // flat_set(initializer_list<Key>, Compare = Compare())308 // -> flat_set<Key, Compare>;309 std::flat_set m({1, 2, 1, INT_MAX, 3}, C());310 311 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);312 assert(std::ranges::equal(m, sorted_arr));313 }314 {315 // template<class Key, class Compare = less<Key>>316 // flat_set(sorted_unique_t, initializer_list<Key>, Compare = Compare())317 // -> flat_set<Key, Compare>;318 std::flat_set m(std::sorted_unique, {INT_MAX, 3, 2, 1}, C());319 320 ASSERT_SAME_TYPE(decltype(m), std::flat_set<int, C>);321 assert(std::ranges::equal(m, sorted_arr));322 }323 }324 {325 // from_range without comparator326 std::list<int> r = {1, 2, 1, INT_MAX, 3};327 const int expected[] = {1, 2, 3, INT_MAX};328 {329 // template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,330 // class Allocator = allocator<ranges::range_value_t<R>>>331 // flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())332 // -> flat_set<ranges::range_value_t<R>, Compare,333 // vector<ranges::range_value_t<R>,334 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;335 std::flat_set s(std::from_range, r);336 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>>);337 assert(std::ranges::equal(s, expected));338 }339 {340 // template<ranges::input_range R, class Allocator>341 // flat_set(from_range_t, R&&, Allocator)342 // -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,343 // vector<ranges::range_value_t<R>,344 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;345 std::flat_set s(std::from_range, r, test_allocator<long>(0, 42));346 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::less<int>, std::vector<int, test_allocator<int>>>);347 assert(std::ranges::equal(s, expected));348 assert(std::move(s).extract().get_allocator().get_id() == 42);349 }350 }351 {352 // from_range with comparator353 std::list<int> r = {1, 2, 1, INT_MAX, 3};354 const int expected[] = {INT_MAX, 3, 2, 1};355 {356 // template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,357 // class Allocator = allocator<ranges::range_value_t<R>>>358 // flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())359 // -> flat_set<ranges::range_value_t<R>, Compare,360 // vector<ranges::range_value_t<R>,361 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;362 std::flat_set s(std::from_range, r, std::greater<int>());363 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>>);364 assert(std::ranges::equal(s, expected));365 }366 {367 // template<ranges::input_range R, class Allocator>368 // flat_set(from_range_t, R&&, Allocator)369 // -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,370 // vector<ranges::range_value_t<R>,371 // alloc-rebind<Allocator, ranges::range_value_t<R>>>>;372 std::flat_set s(std::from_range, r, std::greater<int>(), test_allocator<long>(0, 42));373 ASSERT_SAME_TYPE(decltype(s), std::flat_set<int, std::greater<int>, std::vector<int, test_allocator<int>>>);374 assert(std::ranges::equal(s, expected));375 assert(std::move(s).extract().get_allocator().get_id() == 42);376 }377 }378 379 AssociativeContainerDeductionGuidesSfinaeAway<std::flat_set, std::flat_set<int>>();380}381 382int main(int, char**) {383 test();384 385 return 0;386}387