brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · 7fdddc4 Raw
263 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... Args>14//   pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);15// template<class... Args>16//   pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);17// template<class... Args>18//   iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);19// template<class... Args>20//   iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);21 22#include <flat_map>23#include <cassert>24#include <functional>25#include <deque>26 27#include "MinSequenceContainer.h"28#include "test_macros.h"29#include "../helpers.h"30#include "min_allocator.h"31#include "../../../Emplaceable.h"32 33// Constraints: is_constructible_v<mapped_type, Args...> is true.34template <class M, class... Args>35concept CanTryEmplace = requires(M m, Args&&... args) { m.try_emplace(std::forward<Args>(args)...); };36 37using Map  = std::flat_map<Emplaceable, Emplaceable>;38using Iter = typename Map::const_iterator;39static_assert(!CanTryEmplace<Map>);40 41static_assert(CanTryEmplace<Map, const Emplaceable&>);42static_assert(CanTryEmplace<Map, const Emplaceable&, Emplaceable>);43static_assert(CanTryEmplace<Map, const Emplaceable&, int, double>);44static_assert(!CanTryEmplace<Map, const Emplaceable&, const Emplaceable&>);45static_assert(!CanTryEmplace<Map, const Emplaceable&, int>);46 47static_assert(CanTryEmplace<Map, Emplaceable>);48static_assert(CanTryEmplace<Map, Emplaceable, Emplaceable>);49static_assert(CanTryEmplace<Map, Emplaceable, int, double>);50static_assert(!CanTryEmplace<Map, Emplaceable, const Emplaceable&>);51static_assert(!CanTryEmplace<Map, Emplaceable, int>);52 53static_assert(CanTryEmplace<Map, Iter, const Emplaceable&>);54static_assert(CanTryEmplace<Map, Iter, const Emplaceable&, Emplaceable>);55static_assert(CanTryEmplace<Map, Iter, const Emplaceable&, int, double>);56static_assert(!CanTryEmplace<Map, Iter, const Emplaceable&, const Emplaceable&>);57static_assert(!CanTryEmplace<Map, Iter, const Emplaceable&, int>);58 59static_assert(CanTryEmplace<Map, Iter, Emplaceable>);60static_assert(CanTryEmplace<Map, Iter, Emplaceable, Emplaceable>);61static_assert(CanTryEmplace<Map, Iter, Emplaceable, int, double>);62static_assert(!CanTryEmplace<Map, Iter, Emplaceable, const Emplaceable&>);63static_assert(!CanTryEmplace<Map, Iter, Emplaceable, int>);64 65template <class KeyContainer, class ValueContainer>66constexpr void test_ck() {67  using Key   = typename KeyContainer::value_type;68  using Value = typename ValueContainer::value_type;69  using M     = std::flat_map<Key, Value, std::less<Key>, KeyContainer, ValueContainer>;70 71  { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);72    using R = std::pair<typename M::iterator, bool>;73    M m;74    for (int i = 0; i < 20; i += 2)75      m.emplace(i, Moveable(i, (double)i));76 77    assert(m.size() == 10);78 79    Moveable mv1(3, 3.0);80    for (int i = 0; i < 20; i += 2) {81      std::same_as<R> decltype(auto) r = m.try_emplace(i, std::move(mv1));82      assert(m.size() == 10);83      assert(!r.second);           // was not inserted84      assert(!mv1.moved());        // was not moved from85      assert(r.first->first == i); // key86    }87 88    std::same_as<R> decltype(auto) r2 = m.try_emplace(-1, std::move(mv1));89    assert(m.size() == 11);90    assert(r2.second);                   // was inserted91    assert(mv1.moved());                 // was moved from92    assert(r2.first->first == -1);       // key93    assert(r2.first->second.get() == 3); // value94 95    Moveable mv2(5, 3.0);96    std::same_as<R> decltype(auto) r3 = m.try_emplace(5, std::move(mv2));97    assert(m.size() == 12);98    assert(r3.second);                   // was inserted99    assert(mv2.moved());                 // was moved from100    assert(r3.first->first == 5);        // key101    assert(r3.first->second.get() == 5); // value102 103    Moveable mv3(-1, 3.0);104    std::same_as<R> decltype(auto) r4 = m.try_emplace(117, std::move(mv3));105    assert(m.size() == 13);106    assert(r4.second);                    // was inserted107    assert(mv2.moved());                  // was moved from108    assert(r4.first->first == 117);       // key109    assert(r4.first->second.get() == -1); // value110  }111 112  { // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);113    using R = typename M::iterator;114    M m;115    for (int i = 0; i < 20; i += 2)116      m.try_emplace(i, Moveable(i, (double)i));117    assert(m.size() == 10);118    typename M::const_iterator it = m.find(2);119 120    Moveable mv1(3, 3.0);121    for (int i = 0; i < 20; i += 2) {122      std::same_as<R> decltype(auto) r1 = m.try_emplace(it, i, std::move(mv1));123      assert(m.size() == 10);124      assert(!mv1.moved());          // was not moved from125      assert(r1->first == i);        // key126      assert(r1->second.get() == i); // value127    }128 129    std::same_as<R> decltype(auto) r2 = m.try_emplace(it, 3, std::move(mv1));130    assert(m.size() == 11);131    assert(mv1.moved());           // was moved from132    assert(r2->first == 3);        // key133    assert(r2->second.get() == 3); // value134  }135}136 137template <class KeyContainer, class ValueContainer>138constexpr void test_rk() {139  using Key   = typename KeyContainer::value_type;140  using Value = typename ValueContainer::value_type;141  using M     = std::flat_map<Key, Value, std::less<Key>, KeyContainer, ValueContainer>;142 143  { // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);144    using R = std::pair<typename M::iterator, bool>;145    M m;146    for (int i = 0; i < 20; i += 2) {147      m.emplace(Moveable(i, (double)i), Moveable(i + 1, (double)i + 1));148    }149    assert(m.size() == 10);150 151    Moveable mvkey1(2, 2.0);152    Moveable mv1(4, 4.0);153    std::same_as<R> decltype(auto) r1 = m.try_emplace(std::move(mvkey1), std::move(mv1));154    assert(m.size() == 10);155    assert(!r1.second);                // was not inserted156    assert(!mv1.moved());              // was not moved from157    assert(!mvkey1.moved());           // was not moved from158    assert(r1.first->first == mvkey1); // key159 160    Moveable mvkey2(3, 3.0);161    std::same_as<R> decltype(auto) r2 = m.try_emplace(std::move(mvkey2), std::move(mv1));162    assert(m.size() == 11);163    assert(r2.second);                   // was inserted164    assert(mv1.moved());                 // was moved from165    assert(mvkey2.moved());              // was moved from166    assert(r2.first->first.get() == 3);  // key167    assert(r2.first->second.get() == 4); // value168  }169 170  { // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);171    using R = typename M::iterator;172    M m;173    for (int i = 0; i < 20; i += 2)174      m.emplace(Moveable(i, (double)i), Moveable(i + 1, (double)i + 1));175    assert(m.size() == 10);176    typename M::const_iterator it = std::next(m.cbegin());177 178    Moveable mvkey1(2, 2.0);179    Moveable mv1(4, 4.0);180    std::same_as<R> decltype(auto) r1 = m.try_emplace(it, std::move(mvkey1), std::move(mv1));181    assert(m.size() == 10);182    assert(!mv1.moved());        // was not moved from183    assert(!mvkey1.moved());     // was not moved from184    assert(r1->first == mvkey1); // key185 186    Moveable mvkey2(3, 3.0);187    std::same_as<R> decltype(auto) r2 = m.try_emplace(it, std::move(mvkey2), std::move(mv1));188    assert(m.size() == 11);189    assert(mv1.moved());           // was moved from190    assert(mvkey2.moved());        // was moved from191    assert(r2->first.get() == 3);  // key192    assert(r2->second.get() == 4); // value193  }194}195 196constexpr bool test() {197  test_ck<std::vector<int>, std::vector<Moveable>>();198#ifndef __cpp_lib_constexpr_deque199  if (!TEST_IS_CONSTANT_EVALUATED)200#endif201  {202    test_ck<std::deque<int>, std::vector<Moveable>>();203    test_rk<std::deque<Moveable>, std::vector<Moveable>>();204  }205  test_ck<MinSequenceContainer<int>, MinSequenceContainer<Moveable>>();206  test_ck<std::vector<int, min_allocator<int>>, std::vector<Moveable, min_allocator<Moveable>>>();207 208  test_rk<std::vector<Moveable>, std::vector<Moveable>>();209  test_rk<MinSequenceContainer<Moveable>, MinSequenceContainer<Moveable>>();210  test_rk<std::vector<Moveable, min_allocator<Moveable>>, std::vector<Moveable, min_allocator<Moveable>>>();211 212  if (!TEST_IS_CONSTANT_EVALUATED) {213    {214      auto try_emplace_ck = [](auto& m, auto key_arg, auto value_arg) {215        using M   = std::decay_t<decltype(m)>;216        using Key = typename M::key_type;217        const Key key{key_arg};218        m.try_emplace(key, value_arg);219      };220      test_emplace_exception_guarantee(try_emplace_ck);221    }222 223    {224      auto try_emplace_rk = [](auto& m, auto key_arg, auto value_arg) {225        using M   = std::decay_t<decltype(m)>;226        using Key = typename M::key_type;227        m.try_emplace(Key{key_arg}, value_arg);228      };229      test_emplace_exception_guarantee(try_emplace_rk);230    }231 232    {233      auto try_emplace_iter_ck = [](auto& m, auto key_arg, auto value_arg) {234        using M   = std::decay_t<decltype(m)>;235        using Key = typename M::key_type;236        const Key key{key_arg};237        m.try_emplace(m.begin(), key, value_arg);238      };239      test_emplace_exception_guarantee(try_emplace_iter_ck);240    }241 242    {243      auto try_emplace_iter_rk = [](auto& m, auto key_arg, auto value_arg) {244        using M   = std::decay_t<decltype(m)>;245        using Key = typename M::key_type;246        m.try_emplace(m.begin(), Key{key_arg}, value_arg);247      };248      test_emplace_exception_guarantee(try_emplace_iter_rk);249    }250  }251 252  return true;253}254 255int main(int, char**) {256  test();257#if TEST_STD_VER >= 26258  static_assert(test());259#endif260 261  return 0;262}263