insert_or_assign.pass.cpp (6831B)
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 M> 17 // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17 18 // template <class M> 19 // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17 20 // template <class M> 21 // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17 22 // template <class M> 23 // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17 24 25 #include <map> 26 #include <cassert> 27 #include <tuple> 28 29 #include <iostream> 30 31 class Moveable 32 { 33 Moveable(const Moveable&); 34 Moveable& operator=(const Moveable&); 35 36 int int_; 37 double double_; 38 public: 39 Moveable() : int_(0), double_(0) {} 40 Moveable(int i, double d) : int_(i), double_(d) {} 41 Moveable(Moveable&& x) 42 : int_(x.int_), double_(x.double_) 43 {x.int_ = -1; x.double_ = -1;} 44 Moveable& operator=(Moveable&& x) 45 {int_ = x.int_; x.int_ = -1; 46 double_ = x.double_; x.double_ = -1; 47 return *this; 48 } 49 50 bool operator==(const Moveable& x) const 51 {return int_ == x.int_ && double_ == x.double_;} 52 bool operator<(const Moveable& x) const 53 {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);} 54 55 int get() const {return int_;} 56 bool moved() const {return int_ == -1;} 57 }; 58 59 60 int main() 61 { 62 { // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); 63 typedef std::map<int, Moveable> M; 64 typedef std::pair<M::iterator, bool> R; 65 M m; 66 R r; 67 for ( int i = 0; i < 20; i += 2 ) 68 m.emplace ( i, Moveable(i, (double) i)); 69 assert(m.size() == 10); 70 71 for (int i=0; i < 20; i += 2) 72 { 73 Moveable mv(i+1, i+1); 74 r = m.insert_or_assign(i, std::move(mv)); 75 assert(m.size() == 10); 76 assert(!r.second); // was not inserted 77 assert(mv.moved()); // was moved from 78 assert(r.first->first == i); // key 79 assert(r.first->second.get() == i+1); // value 80 } 81 82 Moveable mv1(5, 5.0); 83 r = m.insert_or_assign(-1, std::move(mv1)); 84 assert(m.size() == 11); 85 assert(r.second); // was inserted 86 assert(mv1.moved()); // was moved from 87 assert(r.first->first == -1); // key 88 assert(r.first->second.get() == 5); // value 89 90 Moveable mv2(9, 9.0); 91 r = m.insert_or_assign(3, std::move(mv2)); 92 assert(m.size() == 12); 93 assert(r.second); // was inserted 94 assert(mv2.moved()); // was moved from 95 assert(r.first->first == 3); // key 96 assert(r.first->second.get() == 9); // value 97 98 Moveable mv3(-1, 5.0); 99 r = m.insert_or_assign(117, std::move(mv3)); 100 assert(m.size() == 13); 101 assert(r.second); // was inserted 102 assert(mv3.moved()); // was moved from 103 assert(r.first->first == 117); // key 104 assert(r.first->second.get() == -1); // value 105 } 106 { // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); 107 typedef std::map<Moveable, Moveable> M; 108 typedef std::pair<M::iterator, bool> R; 109 M m; 110 R r; 111 for ( int i = 0; i < 20; i += 2 ) 112 m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1)); 113 assert(m.size() == 10); 114 115 Moveable mvkey1(2, 2.0); 116 Moveable mv1(4, 4.0); 117 r = m.insert_or_assign(std::move(mvkey1), std::move(mv1)); 118 assert(m.size() == 10); 119 assert(!r.second); // was not inserted 120 assert(!mvkey1.moved()); // was not moved from 121 assert(mv1.moved()); // was moved from 122 assert(r.first->first == mvkey1); // key 123 assert(r.first->second.get() == 4); // value 124 125 Moveable mvkey2(3, 3.0); 126 Moveable mv2(5, 5.0); 127 r = m.try_emplace(std::move(mvkey2), std::move(mv2)); 128 assert(m.size() == 11); 129 assert(r.second); // was inserted 130 assert(mv2.moved()); // was moved from 131 assert(mvkey2.moved()); // was moved from 132 assert(r.first->first.get() == 3); // key 133 assert(r.first->second.get() == 5); // value 134 } 135 { // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); 136 typedef std::map<int, Moveable> M; 137 M m; 138 M::iterator r; 139 for ( int i = 0; i < 20; i += 2 ) 140 m.emplace ( i, Moveable(i, (double) i)); 141 assert(m.size() == 10); 142 M::const_iterator it = m.find(2); 143 144 Moveable mv1(3, 3.0); 145 r = m.insert_or_assign(it, 2, std::move(mv1)); 146 assert(m.size() == 10); 147 assert(mv1.moved()); // was moved from 148 assert(r->first == 2); // key 149 assert(r->second.get() == 3); // value 150 151 Moveable mv2(5, 5.0); 152 r = m.insert_or_assign(it, 3, std::move(mv2)); 153 assert(m.size() == 11); 154 assert(mv2.moved()); // was moved from 155 assert(r->first == 3); // key 156 assert(r->second.get() == 5); // value 157 } 158 { // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); 159 typedef std::map<Moveable, Moveable> M; 160 M m; 161 M::iterator r; 162 for ( int i = 0; i < 20; i += 2 ) 163 m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1)); 164 assert(m.size() == 10); 165 M::const_iterator it = std::next(m.cbegin()); 166 167 Moveable mvkey1(2, 2.0); 168 Moveable mv1(4, 4.0); 169 r = m.insert_or_assign(it, std::move(mvkey1), std::move(mv1)); 170 assert(m.size() == 10); 171 assert(mv1.moved()); // was moved from 172 assert(!mvkey1.moved()); // was not moved from 173 assert(r->first == mvkey1); // key 174 assert(r->second.get() == 4); // value 175 176 Moveable mvkey2(3, 3.0); 177 Moveable mv2(5, 5.0); 178 r = m.insert_or_assign(it, std::move(mvkey2), std::move(mv2)); 179 assert(m.size() == 11); 180 assert(mv2.moved()); // was moved from 181 assert(mvkey2.moved()); // was moved from 182 assert(r->first.get() == 3); // key 183 assert(r->second.get() == 5); // value 184 } 185 }