• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
Moveable()37     Moveable() : int_(0), double_(0) {}
Moveable(int i,double d)38     Moveable(int i, double d) : int_(i), double_(d) {}
Moveable(Moveable && x)39     Moveable(Moveable&& x)
40         : int_(x.int_), double_(x.double_)
41             {x.int_ = -1; x.double_ = -1;}
operator =(Moveable && x)42     Moveable& operator=(Moveable&& x)
43         {int_ = x.int_; x.int_ = -1;
44          double_ = x.double_; x.double_ = -1;
45          return *this;
46         }
47 
operator ==(const Moveable & x) const48     bool operator==(const Moveable& x) const
49         {return int_ == x.int_ && double_ == x.double_;}
operator <(const Moveable & x) const50     bool operator<(const Moveable& x) const
51         {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);}
52 
get() const53     int get() const {return int_;}
moved() const54     bool moved() const {return int_ == -1;}
55 };
56 
57 
main()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