xref: /minix3/external/bsd/libc++/dist/libcxx/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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++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 <__config>
26 #include <map>
27 #include <cassert>
28 #include <tuple>
29 
30 class Moveable
31 {
32     Moveable(const Moveable&);
33     Moveable& operator=(const Moveable&);
34 
35     int int_;
36     double double_;
37 public:
Moveable()38     Moveable() : int_(0), double_(0) {}
Moveable(int i,double d)39     Moveable(int i, double d) : int_(i), double_(d) {}
Moveable(Moveable && x)40     Moveable(Moveable&& x)
41         : int_(x.int_), double_(x.double_)
42             {x.int_ = -1; x.double_ = -1;}
operator =(Moveable && x)43     Moveable& operator=(Moveable&& x)
44         {int_ = x.int_; x.int_ = -1;
45          double_ = x.double_; x.double_ = -1;
46          return *this;
47         }
48 
operator ==(const Moveable & x) const49     bool operator==(const Moveable& x) const
50         {return int_ == x.int_ && double_ == x.double_;}
operator <(const Moveable & x) const51     bool operator<(const Moveable& x) const
52         {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);}
53 
get() const54     int get() const {return int_;}
moved() const55     bool moved() const {return int_ == -1;}
56 };
57 
58 
main()59 int main()
60 {
61 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
62 #ifndef _LIBCPP_HAS_NO_VARIADICS
63 
64     { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
65         typedef std::map<int, Moveable> M;
66         typedef std::pair<M::iterator, bool> R;
67         M m;
68         R r;
69         for (int i = 0; i < 20; i += 2)
70             m.emplace (i, Moveable(i, (double) i));
71         assert(m.size() == 10);
72 
73         Moveable mv1(3, 3.0);
74         for (int i=0; i < 20; i += 2)
75         {
76             r = m.try_emplace(i, std::move(mv1));
77             assert(m.size() == 10);
78             assert(!r.second);              // was not inserted
79             assert(!mv1.moved());           // was not moved from
80             assert(r.first->first == i);    // key
81         }
82 
83         r = m.try_emplace(-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() == 3); // value
89 
90         Moveable mv2(5, 3.0);
91         r = m.try_emplace(5, 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 == 5);        // key
96         assert(r.first->second.get() == 5); // value
97 
98         Moveable mv3(-1, 3.0);
99         r = m.try_emplace(117, std::move(mv2));
100         assert(m.size() == 13);
101         assert(r.second);                    // was inserted
102         assert(mv2.moved());                 // was moved from
103         assert(r.first->first == 117);       // key
104         assert(r.first->second.get() == -1); // value
105     }
106 
107     {  // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
108         typedef std::map<Moveable, Moveable> M;
109         typedef std::pair<M::iterator, bool> R;
110         M m;
111         R r;
112         for ( int i = 0; i < 20; i += 2 )
113             m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
114         assert(m.size() == 10);
115 
116         Moveable mvkey1(2, 2.0);
117         Moveable mv1(4, 4.0);
118         r = m.try_emplace(std::move(mvkey1), std::move(mv1));
119         assert(m.size() == 10);
120         assert(!r.second);                 // was not inserted
121         assert(!mv1.moved());              // was not moved from
122         assert(!mvkey1.moved());           // was not moved from
123         assert(r.first->first == mvkey1);  // key
124 
125         Moveable mvkey2(3, 3.0);
126         r = m.try_emplace(std::move(mvkey2), std::move(mv1));
127         assert(m.size() == 11);
128         assert(r.second);                   // was inserted
129         assert(mv1.moved());                // was moved from
130         assert(mvkey2.moved());             // was moved from
131         assert(r.first->first.get()  == 3); // key
132         assert(r.first->second.get() == 4); // value
133     }
134 
135     {  // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
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.try_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         for (int i=0; i < 20; i += 2)
146         {
147             r = m.try_emplace(it, i, std::move(mv1));
148             assert(m.size() == 10);
149             assert(!mv1.moved());         // was not moved from
150             assert(r->first == i);        // key
151             assert(r->second.get() == i); // value
152         }
153 
154         r = m.try_emplace(it, 3, std::move(mv1));
155         assert(m.size() == 11);
156         assert(mv1.moved());          // was moved from
157         assert(r->first == 3);        // key
158         assert(r->second.get() == 3); // value
159     }
160 
161     {  // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
162         typedef std::map<Moveable, Moveable> M;
163         M m;
164         M::iterator r;
165         for ( int i = 0; i < 20; i += 2 )
166             m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
167         assert(m.size() == 10);
168         M::const_iterator it = std::next(m.cbegin());
169 
170         Moveable mvkey1(2, 2.0);
171         Moveable mv1(4, 4.0);
172         r = m.try_emplace(it, std::move(mvkey1), std::move(mv1));
173         assert(m.size() == 10);
174         assert(!mv1.moved());        // was not moved from
175         assert(!mvkey1.moved());     // was not moved from
176         assert(r->first == mvkey1);  // key
177 
178         Moveable mvkey2(3, 3.0);
179         r = m.try_emplace(it, std::move(mvkey2), std::move(mv1));
180         assert(m.size() == 11);
181         assert(mv1.moved());          // was moved from
182         assert(mvkey2.moved());       // was moved from
183         assert(r->first.get()  == 3); // key
184         assert(r->second.get() == 4); // value
185     }
186 
187 #endif  // _LIBCPP_HAS_NO_VARIADICS
188 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
189 }
190