1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // UNSUPPORTED: c++98, c++03, c++11, c++14 11 12 // <map> 13 14 // class map 15 16 // template <class... Args> 17 // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17 18 // template <class... Args> 19 // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17 20 // template <class... Args> 21 // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17 22 // template <class... Args> 23 // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 24 25 #include <map> 26 #include <cassert> 27 #include <tuple> 28 29 class Moveable 30 { 31 Moveable(const Moveable&); 32 Moveable& operator=(const Moveable&); 33 34 int int_; 35 double double_; 36 public: 37 Moveable() : int_(0), double_(0) {} 38 Moveable(int i, double d) : int_(i), double_(d) {} 39 Moveable(Moveable&& x) 40 : int_(x.int_), double_(x.double_) 41 {x.int_ = -1; x.double_ = -1;} 42 Moveable& operator=(Moveable&& x) 43 {int_ = x.int_; x.int_ = -1; 44 double_ = x.double_; x.double_ = -1; 45 return *this; 46 } 47 48 bool operator==(const Moveable& x) const 49 {return int_ == x.int_ && double_ == x.double_;} 50 bool operator<(const Moveable& x) const 51 {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);} 52 53 int get() const {return int_;} 54 bool moved() const {return int_ == -1;} 55 }; 56 57 58 int main() 59 { 60 { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); 61 typedef std::map<int, Moveable> M; 62 typedef std::pair<M::iterator, bool> R; 63 M m; 64 R r; 65 for (int i = 0; i < 20; i += 2) 66 m.emplace (i, Moveable(i, (double) i)); 67 assert(m.size() == 10); 68 69 Moveable mv1(3, 3.0); 70 for (int i=0; i < 20; i += 2) 71 { 72 r = m.try_emplace(i, std::move(mv1)); 73 assert(m.size() == 10); 74 assert(!r.second); // was not inserted 75 assert(!mv1.moved()); // was not moved from 76 assert(r.first->first == i); // key 77 } 78 79 r = m.try_emplace(-1, std::move(mv1)); 80 assert(m.size() == 11); 81 assert(r.second); // was inserted 82 assert(mv1.moved()); // was moved from 83 assert(r.first->first == -1); // key 84 assert(r.first->second.get() == 3); // value 85 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 inserted 90 assert(mv2.moved()); // was moved from 91 assert(r.first->first == 5); // key 92 assert(r.first->second.get() == 5); // value 93 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 inserted 98 assert(mv2.moved()); // was moved from 99 assert(r.first->first == 117); // key 100 assert(r.first->second.get() == -1); // value 101 } 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 inserted 117 assert(!mv1.moved()); // was not moved from 118 assert(!mvkey1.moved()); // was not moved from 119 assert(r.first->first == mvkey1); // key 120 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 inserted 125 assert(mv1.moved()); // was moved from 126 assert(mvkey2.moved()); // was moved from 127 assert(r.first->first.get() == 3); // key 128 assert(r.first->second.get() == 4); // value 129 } 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 { 143 r = m.try_emplace(it, i, std::move(mv1)); 144 assert(m.size() == 10); 145 assert(!mv1.moved()); // was not moved from 146 assert(r->first == i); // key 147 assert(r->second.get() == i); // value 148 } 149 150 r = m.try_emplace(it, 3, std::move(mv1)); 151 assert(m.size() == 11); 152 assert(mv1.moved()); // was moved from 153 assert(r->first == 3); // key 154 assert(r->second.get() == 3); // value 155 } 156 157 { // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); 158 typedef std::map<Moveable, Moveable> M; 159 M m; 160 M::iterator r; 161 for ( int i = 0; i < 20; i += 2 ) 162 m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1)); 163 assert(m.size() == 10); 164 M::const_iterator it = std::next(m.cbegin()); 165 166 Moveable mvkey1(2, 2.0); 167 Moveable mv1(4, 4.0); 168 r = m.try_emplace(it, std::move(mvkey1), std::move(mv1)); 169 assert(m.size() == 10); 170 assert(!mv1.moved()); // was not moved from 171 assert(!mvkey1.moved()); // was not moved from 172 assert(r->first == mvkey1); // key 173 174 Moveable mvkey2(3, 3.0); 175 r = m.try_emplace(it, std::move(mvkey2), std::move(mv1)); 176 assert(m.size() == 11); 177 assert(mv1.moved()); // was moved from 178 assert(mvkey2.moved()); // was moved from 179 assert(r->first.get() == 3); // key 180 assert(r->second.get() == 4); // value 181 } 182 } 183