156 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// template <class InputIterator>14// flat_multiset(InputIterator first, InputIterator last, const key_compare& comp = key_compare());15// template<class InputIterator, class Allocator>16// flat_multiset(InputIterator first, InputIterator last, const Allocator& a);17// template<class InputIterator, class Allocator>18// flat_multiset(InputIterator first, InputIterator last, const key_compare& comp, const Allocator& a);19 20#include <algorithm>21#include <deque>22#include <flat_set>23#include <functional>24#include <ranges>25#include <vector>26 27#include "min_allocator.h"28#include "test_allocator.h"29#include "test_iterators.h"30#include "test_macros.h"31#include "../../../test_compare.h"32 33template <template <class...> class KeyContainer>34constexpr void test() {35 {36 // The constructors in this subclause shall not participate in overload37 // resolution unless uses_allocator_v<container_type, Alloc> is true.38 39 using C = test_less<int>;40 using A1 = test_allocator<int>;41 using A2 = other_allocator<int>;42 using V1 = KeyContainer<int, A1>;43 using V2 = KeyContainer<int, A2>;44 using M1 = std::flat_multiset<int, C, V1>;45 using M2 = std::flat_multiset<int, C, V2>;46 using Iter1 = typename M1::iterator;47 using Iter2 = typename M2::iterator;48 static_assert(std::is_constructible_v<M1, Iter1, Iter1, const A1&>);49 static_assert(std::is_constructible_v<M2, Iter2, Iter2, const A2&>);50 static_assert(!std::is_constructible_v<M1, Iter1, Iter1, const A2&>);51 static_assert(!std::is_constructible_v<M2, Iter2, Iter2, const A1&>);52 53 static_assert(std::is_constructible_v<M1, Iter1, Iter1, const C&, const A1&>);54 static_assert(std::is_constructible_v<M2, Iter2, Iter2, const C&, const A2&>);55 static_assert(!std::is_constructible_v<M1, Iter1, Iter1, const C&, const A2&>);56 static_assert(!std::is_constructible_v<M2, Iter2, Iter2, const C&, const A1&>);57 }58 59 int ar[] = {1, 1, 1, 2, 2, 3, 2, 3, 3};60 int expected[] = {1, 1, 1, 2, 2, 2, 3, 3, 3};61 {62 // flat_multiset(InputIterator , InputIterator)63 // cpp17_input_iterator64 using M = std::flat_multiset<int, std::less<int>, KeyContainer<int>>;65 auto m = M(cpp17_input_iterator<const int*>(ar), cpp17_input_iterator<const int*>(ar + 9));66 assert(std::ranges::equal(m, expected));67 68 // explicit(false)69 M m2 = {cpp17_input_iterator<const int*>(ar), cpp17_input_iterator<const int*>(ar + 9)};70 assert(m2 == m);71 }72 {73 // flat_multiset(InputIterator , InputIterator)74 // greater75 using M = std::flat_multiset<int, std::greater<int>, KeyContainer<int, min_allocator<int>>>;76 auto m = M(cpp17_input_iterator<const int*>(ar), cpp17_input_iterator<const int*>(ar + 9));77 assert(std::ranges::equal(m, expected | std::views::reverse));78 }79 {80 // flat_multiset(InputIterator , InputIterator)81 // Test when the operands are of array type (also contiguous iterator type)82 using M = std::flat_multiset<int, std::greater<int>, KeyContainer<int, min_allocator<int>>>;83 auto m = M(ar, ar);84 assert(m.empty());85 }86 {87 // flat_multiset(InputIterator , InputIterator, const key_compare&)88 using C = test_less<int>;89 using M = std::flat_multiset<int, C, KeyContainer<int>>;90 auto m = M(ar, ar + 9, C(3));91 assert(std::ranges::equal(m, expected));92 assert(m.key_comp() == C(3));93 94 // explicit(false)95 M m2 = {ar, ar + 9, C(3)};96 assert(m2 == m);97 assert(m2.key_comp() == C(3));98 }99 {100 // flat_multiset(InputIterator , InputIterator, const Allocator&)101 using A1 = test_allocator<int>;102 using M = std::flat_multiset<int, std::less<int>, KeyContainer<int, A1>>;103 auto m = M(ar, ar + 9, A1(5));104 assert(std::ranges::equal(m, expected));105 assert(std::move(m).extract().get_allocator() == A1(5));106 }107 {108 // flat_multiset(InputIterator , InputIterator, const Allocator&)109 // explicit(false)110 using A1 = test_allocator<int>;111 using M = std::flat_multiset<int, std::less<int>, KeyContainer<int, A1>>;112 M m = {ar, ar + 9, A1(5)}; // implicit ctor113 assert(std::ranges::equal(m, expected));114 assert(std::move(m).extract().get_allocator() == A1(5));115 }116 {117 // flat_multiset(InputIterator , InputIterator, const key_compare&, const Allocator&)118 using C = test_less<int>;119 using A1 = test_allocator<int>;120 using M = std::flat_multiset<int, C, KeyContainer<int, A1>>;121 auto m = M(ar, ar + 9, C(3), A1(5));122 assert(std::ranges::equal(m, expected));123 assert(m.key_comp() == C(3));124 assert(std::move(m).extract().get_allocator() == A1(5));125 }126 {127 // flat_multiset(InputIterator , InputIterator, const key_compare&, const Allocator&)128 // explicit(false)129 using A1 = test_allocator<int>;130 using M = std::flat_multiset<int, std::less<int>, KeyContainer<int, A1>>;131 M m = {ar, ar + 9, {}, A1(5)}; // implicit ctor132 assert(std::ranges::equal(m, expected));133 LIBCPP_ASSERT(std::ranges::equal(m, expected));134 assert(std::move(m).extract().get_allocator() == A1(5));135 }136}137 138constexpr bool test() {139 test<std::vector>();140#ifndef __cpp_lib_constexpr_deque141 if (!TEST_IS_CONSTANT_EVALUATED)142#endif143 test<std::deque>();144 145 return true;146}147 148int main(int, char**) {149 test();150#if TEST_STD_VER >= 26151 static_assert(test());152#endif153 154 return 0;155}156