brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 639f1c0 Raw
114 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_map>12 13// class flat_multimap14 15// template<container-compatible-range<value_type> R>16//   void insert_range(R&& rg);17 18#include <algorithm>19#include <deque>20#include <flat_map>21#include <functional>22#include <ranges>23#include <vector>24 25#include "MinSequenceContainer.h"26#include "../helpers.h"27#include "MoveOnly.h"28#include "test_macros.h"29#include "test_iterators.h"30#include "min_allocator.h"31 32// test constraint container-compatible-range33template <class M, class R>34concept CanInsertRange = requires(M m, R&& r) { m.insert_range(std::forward<R>(r)); };35 36using Map = std::flat_multimap<int, double>;37 38static_assert(CanInsertRange<Map, std::ranges::subrange<std::pair<int, double>*>>);39static_assert(CanInsertRange<Map, std::ranges::subrange<std::pair<short, double>*>>);40static_assert(!CanInsertRange<Map, std::ranges::subrange<int*>>);41static_assert(!CanInsertRange<Map, std::ranges::subrange<double*>>);42 43template <class KeyContainer, class ValueContainer>44constexpr void test() {45  using Key   = typename KeyContainer::value_type;46  using Value = typename ValueContainer::value_type;47 48  {49    using P                 = std::pair<int, int>;50    using M                 = std::flat_multimap<Key, Value, std::less<Key>, KeyContainer, ValueContainer>;51    using It                = forward_iterator<const P*>;52    M m                     = {{10, 1}, {8, 2}, {5, 3}, {2, 4}, {1, 5}};53    P ar[]                  = {{3, 1}, {1, 2}, {4, 3}, {1, 4}, {5, 5}, {9, 6}};54    std::ranges::subrange r = {It(ar), It(ar + 6)};55    static_assert(std::ranges::common_range<decltype(r)>);56    m.insert_range(r);57    std::vector<P> expected = {{1, 5}, {1, 2}, {1, 4}, {2, 4}, {3, 1}, {4, 3}, {5, 3}, {5, 5}, {8, 2}, {9, 6}, {10, 1}};58    assert(std::ranges::equal(m, expected));59  }60  {61    using P                 = std::pair<int, int>;62    using M                 = std::flat_multimap<Key, Value, std::greater<>, KeyContainer, ValueContainer>;63    using It                = cpp20_input_iterator<const P*>;64    M m                     = {{8, 1}, {5, 2}, {3, 3}, {2, 4}};65    P ar[]                  = {{3, 1}, {1, 2}, {4, 3}, {1, 4}, {5, 5}, {9, 6}};66    std::ranges::subrange r = {It(ar), sentinel_wrapper<It>(It(ar + 6))};67    static_assert(!std::ranges::common_range<decltype(r)>);68    m.insert_range(r);69    std::vector<P> expected = {{9, 6}, {8, 1}, {5, 2}, {5, 5}, {4, 3}, {3, 3}, {3, 1}, {2, 4}, {1, 2}, {1, 4}};70    assert(std::ranges::equal(m, expected));71  }72}73 74constexpr bool test() {75  test<std::vector<int>, std::vector<int>>();76#ifndef __cpp_lib_constexpr_deque77  if (!TEST_IS_CONSTANT_EVALUATED)78#endif79    test<std::deque<int>, std::vector<int>>();80  test<MinSequenceContainer<int>, MinSequenceContainer<int>>();81  test<std::vector<int, min_allocator<int>>, std::vector<int, min_allocator<int>>>();82  {83    // Items are forwarded correctly from the input range (P2767).84    std::pair<MoveOnly, MoveOnly> a[] = {{3, 3}, {1, 1}, {4, 4}, {1, 1}, {5, 5}};85    std::flat_multimap<MoveOnly, MoveOnly> m;86    m.insert_range(a | std::views::as_rvalue);87    std::pair<MoveOnly, MoveOnly> expected[] = {{1, 1}, {1, 1}, {3, 3}, {4, 4}, {5, 5}};88    assert(std::ranges::equal(m, expected));89  }90  {91    // The element type of the range doesn't need to be std::pair (P2767).92    std::pair<int, int> pa[] = {{3, 3}, {1, 1}, {4, 4}, {1, 1}, {5, 5}};93    std::vector<std::reference_wrapper<std::pair<int, int>>> a(pa, pa + 5);94    std::flat_multimap<int, int> m;95    m.insert_range(a);96    std::pair<int, int> expected[] = {{1, 1}, {1, 1}, {3, 3}, {4, 4}, {5, 5}};97    assert(std::ranges::equal(m, expected));98  }99  if (!TEST_IS_CONSTANT_EVALUATED) {100    auto insert_func = [](auto& m, const auto& newValues) { m.insert_range(newValues); };101    test_insert_range_exception_guarantee(insert_func);102  }103  return true;104}105 106int main(int, char**) {107  test();108#if TEST_STD_VER >= 26109  static_assert(test());110#endif111 112  return 0;113}114