184 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++1410 11// <map>12 13// class map14 15// template <class... Args>16// pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++1717// template <class... Args>18// pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++1719// template <class... Args>20// iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++1721// template <class... Args>22// iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++1723 24#include <map>25#include <cassert>26#include <iterator>27#include <tuple>28 29#include "test_macros.h"30 31class Moveable {32 Moveable(const Moveable&);33 Moveable& operator=(const Moveable&);34 35 int int_;36 double double_;37 38public:39 Moveable() : int_(0), double_(0) {}40 Moveable(int i, double d) : int_(i), double_(d) {}41 Moveable(Moveable&& x) : int_(x.int_), double_(x.double_) {42 x.int_ = -1;43 x.double_ = -1;44 }45 Moveable& operator=(Moveable&& x) {46 int_ = x.int_;47 x.int_ = -1;48 double_ = x.double_;49 x.double_ = -1;50 return *this;51 }52 53 bool operator==(const Moveable& x) const { return int_ == x.int_ && double_ == x.double_; }54 bool operator<(const Moveable& x) const { return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_); }55 56 int get() const { return int_; }57 bool moved() const { return int_ == -1; }58};59 60int main(int, char**) {61 { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);62 typedef std::map<int, Moveable> M;63 typedef std::pair<M::iterator, bool> R;64 M m;65 R r;66 for (int i = 0; i < 20; i += 2)67 m.emplace(i, Moveable(i, (double)i));68 assert(m.size() == 10);69 70 Moveable mv1(3, 3.0);71 for (int i = 0; i < 20; i += 2) {72 r = m.try_emplace(i, std::move(mv1));73 assert(m.size() == 10);74 assert(!r.second); // was not inserted75 assert(!mv1.moved()); // was not moved from76 assert(r.first->first == i); // key77 }78 79 r = m.try_emplace(-1, std::move(mv1));80 assert(m.size() == 11);81 assert(r.second); // was inserted82 assert(mv1.moved()); // was moved from83 assert(r.first->first == -1); // key84 assert(r.first->second.get() == 3); // value85 86 Moveable mv2(5, 3.0);87 r = m.try_emplace(5, std::move(mv2));88 assert(m.size() == 12);89 assert(r.second); // was inserted90 assert(mv2.moved()); // was moved from91 assert(r.first->first == 5); // key92 assert(r.first->second.get() == 5); // value93 94 Moveable mv3(-1, 3.0);95 r = m.try_emplace(117, std::move(mv2));96 assert(m.size() == 13);97 assert(r.second); // was inserted98 assert(mv2.moved()); // was moved from99 assert(r.first->first == 117); // key100 assert(r.first->second.get() == -1); // value101 }102 103 { // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);104 typedef std::map<Moveable, Moveable> M;105 typedef std::pair<M::iterator, bool> R;106 M m;107 R r;108 for (int i = 0; i < 20; i += 2)109 m.emplace(Moveable(i, (double)i), Moveable(i + 1, (double)i + 1));110 assert(m.size() == 10);111 112 Moveable mvkey1(2, 2.0);113 Moveable mv1(4, 4.0);114 r = m.try_emplace(std::move(mvkey1), std::move(mv1));115 assert(m.size() == 10);116 assert(!r.second); // was not inserted117 assert(!mv1.moved()); // was not moved from118 assert(!mvkey1.moved()); // was not moved from119 assert(r.first->first == mvkey1); // key120 121 Moveable mvkey2(3, 3.0);122 r = m.try_emplace(std::move(mvkey2), std::move(mv1));123 assert(m.size() == 11);124 assert(r.second); // was inserted125 assert(mv1.moved()); // was moved from126 assert(mvkey2.moved()); // was moved from127 assert(r.first->first.get() == 3); // key128 assert(r.first->second.get() == 4); // value129 }130 131 { // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);132 typedef std::map<int, Moveable> M;133 M m;134 M::iterator r;135 for (int i = 0; i < 20; i += 2)136 m.try_emplace(i, Moveable(i, (double)i));137 assert(m.size() == 10);138 M::const_iterator it = m.find(2);139 140 Moveable mv1(3, 3.0);141 for (int i = 0; i < 20; i += 2) {142 r = m.try_emplace(it, i, std::move(mv1));143 assert(m.size() == 10);144 assert(!mv1.moved()); // was not moved from145 assert(r->first == i); // key146 assert(r->second.get() == i); // value147 }148 149 r = m.try_emplace(it, 3, std::move(mv1));150 assert(m.size() == 11);151 assert(mv1.moved()); // was moved from152 assert(r->first == 3); // key153 assert(r->second.get() == 3); // value154 }155 156 { // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);157 typedef std::map<Moveable, Moveable> M;158 M m;159 M::iterator r;160 for (int i = 0; i < 20; i += 2)161 m.emplace(Moveable(i, (double)i), Moveable(i + 1, (double)i + 1));162 assert(m.size() == 10);163 M::const_iterator it = std::next(m.cbegin());164 165 Moveable mvkey1(2, 2.0);166 Moveable mv1(4, 4.0);167 r = m.try_emplace(it, std::move(mvkey1), std::move(mv1));168 assert(m.size() == 10);169 assert(!mv1.moved()); // was not moved from170 assert(!mvkey1.moved()); // was not moved from171 assert(r->first == mvkey1); // key172 173 Moveable mvkey2(3, 3.0);174 r = m.try_emplace(it, std::move(mvkey2), std::move(mv1));175 assert(m.size() == 11);176 assert(mv1.moved()); // was moved from177 assert(mvkey2.moved()); // was moved from178 assert(r->first.get() == 3); // key179 assert(r->second.get() == 4); // value180 }181 182 return 0;183}184