brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · 75ddc49 Raw
135 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// template<class K> pair<iterator, bool> insert(P&& x);14// template<class K> iterator insert(const_iterator hint, P&& x);15 16#include <algorithm>17#include <compare>18#include <concepts>19#include <deque>20#include <flat_map>21#include <functional>22#include <tuple>23 24#include "MinSequenceContainer.h"25#include "../helpers.h"26#include "test_macros.h"27#include "test_iterators.h"28#include "min_allocator.h"29 30// Constraints: is_constructible_v<pair<key_type, mapped_type>, P> is true.31template <class M, class... Args>32concept CanInsert = requires(M m, Args&&... args) { m.insert(std::forward<Args>(args)...); };33 34using Map  = std::flat_map<int, double>;35using Iter = Map::const_iterator;36 37static_assert(CanInsert<Map, std::pair<short, double>&&>);38static_assert(CanInsert<Map, Iter, std::pair<short, double>&&>);39static_assert(CanInsert<Map, std::tuple<short, double>&&>);40static_assert(CanInsert<Map, Iter, std::tuple<short, double>&&>);41static_assert(!CanInsert<Map, int>);42static_assert(!CanInsert<Map, Iter, int>);43 44constexpr bool test() {45  {46    // template<class K> pair<iterator, bool> insert(P&& x);47    bool transparent_used = false;48    TransparentComparator c(transparent_used);49    using M = std::flat_map<int, int, TransparentComparator>;50    M m(std::sorted_unique, {{1, 1}, {2, 2}, {4, 4}}, c);51    assert(!transparent_used);52 53    std::same_as<std::pair<typename M::iterator, bool>> decltype(auto) res =54        m.insert(std::pair(ConvertibleTransparent<int>{3}, 3));55 56    assert(res.second);57    assert(res.first->first == 3);58    assert(res.first->second == 3);59    //   Unlike flat_set, here we can't use key_compare to compare value_type versus P,60    //   so we must eagerly convert to value_type.61    assert(!transparent_used);62  }63  {64    // template<class K> iterator insert(const_iterator hint, P&& x);65    bool transparent_used = false;66    TransparentComparator c(transparent_used);67    using M = std::flat_map<int, int, TransparentComparator>;68    M m(std::sorted_unique, {{1, 1}, {2, 2}, {4, 4}}, c);69    assert(!transparent_used);70 71    std::same_as<typename M::iterator> decltype(auto) res =72        m.insert(m.begin(), std::pair(ConvertibleTransparent<int>{3}, 3));73 74    assert(res->first == 3);75    assert(res->second == 3);76    //   Unlike flat_set, here we can't use key_compare to compare value_type versus P,77    //   so we must eagerly convert to value_type.78    assert(!transparent_used);79  }80  {81    // no ambiguity between insert(pos, P&&) and insert(first, last)82    using M = std::flat_map<int, int>;83    struct Evil {84      operator M::value_type() const;85      operator M::const_iterator() const;86    };87    std::flat_map<int, int> m;88    ASSERT_SAME_TYPE(decltype(m.insert(Evil())), std::pair<M::iterator, bool>);89    ASSERT_SAME_TYPE(decltype(m.insert(m.begin(), Evil())), M::iterator);90    ASSERT_SAME_TYPE(decltype(m.insert(m.begin(), m.end())), void);91  }92 93  if (!TEST_IS_CONSTANT_EVALUATED) {94    {95      auto insert_func = [](auto& m, auto key_arg, auto value_arg) {96        using FlatMap    = std::decay_t<decltype(m)>;97        using tuple_type = std::tuple<typename FlatMap::key_type, typename FlatMap::mapped_type>;98        tuple_type t(key_arg, value_arg);99        m.insert(t);100      };101      test_emplace_exception_guarantee(insert_func);102    }103    {104      auto insert_func_iter = [](auto& m, auto key_arg, auto value_arg) {105        using FlatMap    = std::decay_t<decltype(m)>;106        using tuple_type = std::tuple<typename FlatMap::key_type, typename FlatMap::mapped_type>;107        tuple_type t(key_arg, value_arg);108        m.insert(m.begin(), t);109      };110      test_emplace_exception_guarantee(insert_func_iter);111    }112  }113  {114    // LWG4239 std::string and C string literal115    using M = std::flat_map<std::string, int, std::less<>>;116    M m{{"alpha", 1}, {"beta", 2}, {"epsilon", 1}, {"eta", 3}, {"gamma", 3}};117    auto [it, inserted] = m.insert({"alpha", 1});118    assert(!inserted);119    assert(it == m.begin());120    auto it2 = m.insert(m.begin(), {"beta2", 2});121    assert(it2 == m.begin() + 2);122  }123 124  return true;125}126 127int main(int, char**) {128  test();129#if TEST_STD_VER >= 26130  static_assert(test());131#endif132 133  return 0;134}135