blob: ff180bf1bdf59624baa876bdc9ca4c9e853af883 [file] [log] [blame]
// { dg-do run { target c++23 } }
#include <flat_map>
#include <deque>
#include <vector>
#include <testsuite_allocator.h>
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
#include <tuple>
struct Gt {
template<typename T, typename U>
bool operator()(T const& l, U const & r) const
{ return l > r; }
};
void
test_deduction_guide()
{
__gnu_test::test_input_range<std::pair<long, float>> r(0, 0);
std::flat_multimap it1(r.begin(), r.begin());
static_assert(std::is_same_v<decltype(it1), std::flat_multimap<long, float>>);
std::flat_multimap fr1(std::from_range, r);
static_assert(std::is_same_v<decltype(fr1), std::flat_multimap<long, float>>);
Gt cmp;
std::flat_multimap it2(r.begin(), r.begin(), cmp);
static_assert(std::is_same_v<
decltype(it2),
std::flat_multimap<long, float, Gt>>);
std::flat_multimap fr2(std::from_range, r, cmp);
static_assert(std::is_same_v<
decltype(fr2),
std::flat_multimap<long, float, Gt>>);
using Alloc = __gnu_test::SimpleAllocator<std::pair<const long, float>>;
Alloc alloc;
// No matching deduction guide
// std::flat_multimap it3(r.begin(), r.begin(), alloc);
std::flat_multimap fr3(std::from_range, r, alloc);
static_assert(std::is_same_v<
decltype(fr3),
std::flat_multimap<long, float, std::less<long>,
std::vector<long, __gnu_test::SimpleAllocator<long>>,
std::vector<float, __gnu_test::SimpleAllocator<float>>>>);
// No matching deduction guide
// std::flat_multimap it4(r.begin(), r.begin(), cmp, alloc);
std::flat_multimap fr4(std::from_range, r, cmp, alloc);
static_assert(std::is_same_v<
decltype(fr4),
std::flat_multimap<long, float, Gt,
std::vector<long, __gnu_test::SimpleAllocator<long>>,
std::vector<float, __gnu_test::SimpleAllocator<float>>>>);
// LWG4223: deduces flat_multimap<long, float const>, which in turn instantiates
// std::vector<cosnt float> that is ill-formed.
// __gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0);
// std::flat_multimap it5(r2.begin(), r2.begin());
// std::flat_multimap fr5(std::from_range, r2);
// LWG4223: deduces flat_multimap<const long&, float&>
//__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0);
// std::flat_multimap it6(r3.begin(), r3.begin());
// std::flat_multimap fr6(std::from_range, r3);
__gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0);
std::flat_multimap it7(r4.begin(), r4.begin());
static_assert(std::is_same_v<decltype(it7), std::flat_multimap<long, float>>);
std::flat_multimap fr7(std::from_range, r4);
static_assert(std::is_same_v<decltype(fr7), std::flat_multimap<long, float>>);
}
template<template<typename> class KeyContainer, template<typename> class MappedContainer>
void
test01()
{
std::flat_multimap<int, int, std::less<int>, KeyContainer<int>, MappedContainer<int>> m;
static_assert( std::ranges::random_access_range<decltype(m)> );
m.insert({1,-1});
m.insert({2,-2});
m.insert({3,-3});
m.insert({1,-4});
m.insert({2,-5});
m.insert({3,-6});
m.insert({0, 0});
VERIFY( m.size() == 7 );
VERIFY( std::ranges::equal(m.keys(), (int[]){0, 1, 1, 2, 2, 3, 3}) );
VERIFY( std::ranges::equal(m.values(), (int[]){0, -1, -4, -2, -5, -3, -6}) );
m.clear();
m.insert(m.begin(), {0, 0});
m.insert(m.begin(), {1,-1});
m.insert(m.begin(), {2,-2});
m.insert(m.begin(), {3,-3});
m.insert(m.begin(), {1,-4});
m.insert(m.begin(), {2,-5});
m.insert(m.begin(), {3,-6});
m.insert(m.begin(), {0,-7});
VERIFY( std::ranges::equal(m.keys(), (int[]){0, 0, 1, 1, 2, 2, 3, 3}) );
VERIFY( std::ranges::equal(m.values(), (int[]){-7, 0, -4, -1, -5, -2, -6, -3}) );
m.clear();
m = {{10,0},{10,1}};
VERIFY( m.size() == 2 );
m.insert({{11,2},{12,3},{11,4}});
VERIFY( m.size() == 5 );
VERIFY( m.end()[-1] == std::pair(12,3) );
}
void
test02()
{
std::flat_multimap<int, int, std::greater<int>> m;
static_assert( std::ranges::random_access_range<decltype(m)> );
auto r = m.insert({1,-1});
VERIFY( r->first == 1 && r->second == -1 );
r = m.insert({2,-2});
VERIFY( r->first == 2 && r->second == -2 );
r = m.insert({3,-3});
VERIFY( r->first == 3 && r->second == -3 );
r = m.insert({1,-4});
VERIFY( r->first == 1 && r->second == -4 );
r = m.insert({2,-5});
VERIFY( r->first == 2 && r->second == -5 );
r = m.insert({3,-6});
VERIFY( r->first == 3 && r->second == -6 );
VERIFY( m.size() == 6 );
VERIFY( std::ranges::equal(m.keys(), (int[]){3, 3, 2, 2, 1, 1}) );
VERIFY( std::ranges::equal(m.values(), (int[]){-3, -6, -2, -5, -1, -4}) );
VERIFY( m.contains(3) && !m.contains(7) );
VERIFY( m.count(3) == 2 );
}
void
test03()
{
std::flat_multimap<int, int> m;
m = {std::pair(1, 2), {3, 4}, {5, 6}};
m.insert({std::pair(7, 8), {9, 10}});
auto it = m.find(0);
VERIFY( it == m.end() );
it = m.find(9);
VERIFY( it->second == 10 );
const auto n = m;
VERIFY( m == m );
VERIFY( m == n );
m.erase(m.begin());
m.erase(5);
m.erase(m.end()-2, m.end());
VERIFY( std::ranges::equal(m, (std::pair<int, int>[]){{3, 4}}) );
VERIFY( m != n );
VERIFY( n < m );
m = n;
erase_if(m, [](const auto& x) { auto [k, v] = x; return k < 5 || k > 5; });
VERIFY( std::ranges::equal(m, (std::pair<int, int>[]){{5, 6}}) );
}
void
test04()
{
using vector = std::vector<int, __gnu_test::uneq_allocator<int>>;
vector v1 = {1, 2, 3};
vector v2 = {4, 5, 6};
__gnu_test::uneq_allocator<int> alloc(42);
using flat_multimap = std::flat_multimap<int, int, std::less<int>, vector, vector>;
flat_multimap m1(alloc);
VERIFY( m1.keys().get_allocator().get_personality() == 42 );
VERIFY( m1.values().get_allocator().get_personality() == 42 );
flat_multimap m2(v1, v2, alloc);
VERIFY( m2.keys().get_allocator().get_personality() == 42 );
VERIFY( m2.values().get_allocator().get_personality() == 42 );
flat_multimap m3(std::sorted_equivalent_t{}, v1, v2, alloc);
VERIFY( m2.keys().get_allocator().get_personality() == 42 );
VERIFY( m2.values().get_allocator().get_personality() == 42 );
alloc = __gnu_test::uneq_allocator<int>(43);
flat_multimap m4(m2, alloc);
VERIFY( m4.keys().get_allocator().get_personality() == 43 );
VERIFY( m4.values().get_allocator().get_personality() == 43 );
alloc = __gnu_test::uneq_allocator<int>(44);
flat_multimap m5(std::move(m4), alloc);
VERIFY( m5.keys().get_allocator().get_personality() == 44 );
VERIFY( m5.values().get_allocator().get_personality() == 44 );
}
void
test05()
{
std::vector<std::pair<int, int>> v = {{2, -2}, {3,-3}, {1,-1}, {5,-5}, {4,-4}, {3,3}};
std::flat_multimap<int, int> m = {std::from_range, v};
VERIFY( std::ranges::equal(m | std::views::keys, (int[]){1, 2, 3, 3, 4, 5}) );
VERIFY( std::ranges::equal(m | std::views::values, (int[]){-1, -2, -3, 3, -4, -5}) );
}
void
test06()
{
// PR libstdc++/118156 - flat_foo::insert_range cannot handle non-common ranges
std::flat_multimap<int, int> m;
auto r = std::views::zip(std::views::iota(1), std::views::iota(2)) | std::views::take(5);
static_assert(!std::ranges::common_range<decltype(r)>);
m.insert_range(r);
VERIFY( std::ranges::equal(m | std::views::keys, (int[]){1, 2, 3, 4, 5}) );
VERIFY( std::ranges::equal(m | std::views::values, (int[]){2, 3, 4, 5, 6}) );
m.clear();
m.insert_range(r | std::views::reverse);
VERIFY( std::ranges::equal(m | std::views::keys, (int[]){1, 2, 3, 4, 5}) );
VERIFY( std::ranges::equal(m | std::views::values, (int[]){2, 3, 4, 5, 6}) );
}
int
main()
{
test01<std::vector, std::vector>();
test01<std::deque, std::deque>();
test01<std::vector, std::deque>();
test01<std::deque, std::vector>();
test02();
test03();
test04();
test05();
test06();
}