• 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 // <map>
11 
12 // class map
13 
14 // map& operator=(const map& m);
15 
16 #include <map>
17 #include <cassert>
18 #include <vector>
19 #include <algorithm>
20 #include <iterator>
21 
22 #include <iostream>
23 
24 #include "../../../test_compare.h"
25 #include "test_allocator.h"
26 #include "min_allocator.h"
27 
28 #if TEST_STD_VER >= 11
29 std::vector<int> ca_allocs;
30 std::vector<int> ca_deallocs;
31 
32 template <class T>
33 class counting_allocatorT {
34 public:
35     typedef T value_type;
36     int foo{0};
counting_allocatorT(int f)37     counting_allocatorT(int f) noexcept : foo(f) {}
38 
39     using propagate_on_container_copy_assignment = std::true_type;
counting_allocatorT(const counting_allocatorT<U> & other)40     template <class U> counting_allocatorT(const counting_allocatorT<U>& other) noexcept {foo = other.foo;}
operator ==(const counting_allocatorT<U> & other) const41     template <class U> bool operator==(const counting_allocatorT<U>& other) const noexcept { return foo == other.foo; }
operator !=(const counting_allocatorT<U> & other) const42     template <class U> bool operator!=(const counting_allocatorT<U>& other) const noexcept { return foo != other.foo; }
43 
allocate(const size_t n) const44     T * allocate(const size_t n) const {
45         ca_allocs.push_back(foo);
46         void * const pv = ::malloc(n * sizeof(T));
47         return static_cast<T *>(pv);
48     }
deallocate(T * const p,size_t) const49     void deallocate(T * const p, size_t) const noexcept {
50         ca_deallocs.push_back(foo);
51         free(p);
52     }
53 };
54 
55 template <class T>
56 class counting_allocatorF {
57 public:
58     typedef T value_type;
59     int foo{0};
counting_allocatorF(int f)60     counting_allocatorF(int f) noexcept : foo(f) {}
61 
62     using propagate_on_container_copy_assignment = std::false_type;
counting_allocatorF(const counting_allocatorF<U> & other)63     template <class U> counting_allocatorF(const counting_allocatorF<U>& other) noexcept {foo = other.foo;}
operator ==(const counting_allocatorF<U> & other) const64     template <class U> bool operator==(const counting_allocatorF<U>& other) const noexcept { return foo == other.foo; }
operator !=(const counting_allocatorF<U> & other) const65     template <class U> bool operator!=(const counting_allocatorF<U>& other) const noexcept { return foo != other.foo; }
66 
allocate(const size_t n) const67     T * allocate(const size_t n) const {
68         ca_allocs.push_back(foo);
69         void * const pv = ::malloc(n * sizeof(T));
70         return static_cast<T *>(pv);
71     }
deallocate(T * const p,size_t) const72     void deallocate(T * const p, size_t) const noexcept {
73         ca_deallocs.push_back(foo);
74         free(p);
75     }
76 };
77 
balanced_allocs()78 bool balanced_allocs() {
79     std::vector<int> temp1, temp2;
80 
81     std::cout << "Allocations = " << ca_allocs.size() << ", deallocatons = " << ca_deallocs.size() << std::endl;
82     if (ca_allocs.size() != ca_deallocs.size())
83         return false;
84 
85     temp1 = ca_allocs;
86     std::sort(temp1.begin(), temp1.end());
87     temp2.clear();
88     std::unique_copy(temp1.begin(), temp1.end(), std::back_inserter<std::vector<int>>(temp2));
89     std::cout << "There were " << temp2.size() << " different allocators\n";
90 
91     for (std::vector<int>::const_iterator it = temp2.begin(); it != temp2.end(); ++it ) {
92         std::cout << *it << ": " << std::count(ca_allocs.begin(), ca_allocs.end(), *it) << " vs " << std::count(ca_deallocs.begin(), ca_deallocs.end(), *it) << std::endl;
93         if ( std::count(ca_allocs.begin(), ca_allocs.end(), *it) != std::count(ca_deallocs.begin(), ca_deallocs.end(), *it))
94             return false;
95         }
96 
97     temp1 = ca_allocs;
98     std::sort(temp1.begin(), temp1.end());
99     temp2.clear();
100     std::unique_copy(temp1.begin(), temp1.end(), std::back_inserter<std::vector<int>>(temp2));
101     std::cout << "There were " << temp2.size() << " different (de)allocators\n";
102     for (std::vector<int>::const_iterator it = ca_deallocs.begin(); it != ca_deallocs.end(); ++it ) {
103         std::cout << *it << ": " << std::count(ca_allocs.begin(), ca_allocs.end(), *it) << " vs " << std::count(ca_deallocs.begin(), ca_deallocs.end(), *it) << std::endl;
104         if ( std::count(ca_allocs.begin(), ca_allocs.end(), *it) != std::count(ca_deallocs.begin(), ca_deallocs.end(), *it))
105             return false;
106         }
107 
108     return true;
109     }
110 #endif
111 
main()112 int main()
113 {
114     {
115         typedef std::pair<const int, double> V;
116         V ar[] =
117         {
118             V(1, 1),
119             V(1, 1.5),
120             V(1, 2),
121             V(2, 1),
122             V(2, 1.5),
123             V(2, 2),
124             V(3, 1),
125             V(3, 1.5),
126             V(3, 2)
127         };
128         typedef test_compare<std::less<int> > C;
129         typedef test_allocator<V> A;
130         std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(2));
131         std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(7));
132         m = mo;
133         assert(m.get_allocator() == A(7));
134         assert(m.key_comp() == C(5));
135         assert(m.size() == 3);
136         assert(distance(m.begin(), m.end()) == 3);
137         assert(*m.begin() == V(1, 1));
138         assert(*next(m.begin()) == V(2, 1));
139         assert(*next(m.begin(), 2) == V(3, 1));
140 
141         assert(mo.get_allocator() == A(2));
142         assert(mo.key_comp() == C(5));
143         assert(mo.size() == 3);
144         assert(distance(mo.begin(), mo.end()) == 3);
145         assert(*mo.begin() == V(1, 1));
146         assert(*next(mo.begin()) == V(2, 1));
147         assert(*next(mo.begin(), 2) == V(3, 1));
148     }
149     {
150         typedef std::pair<const int, double> V;
151         const V ar[] =
152         {
153             V(1, 1),
154             V(2, 1),
155             V(3, 1),
156         };
157         std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
158         std::map<int, double> *p = &m;
159         m = *p;
160 
161         assert(m.size() == 3);
162         assert(std::equal(m.begin(), m.end(), ar));
163     }
164     {
165         typedef std::pair<const int, double> V;
166         V ar[] =
167         {
168             V(1, 1),
169             V(1, 1.5),
170             V(1, 2),
171             V(2, 1),
172             V(2, 1.5),
173             V(2, 2),
174             V(3, 1),
175             V(3, 1.5),
176             V(3, 2)
177         };
178         typedef test_compare<std::less<int> > C;
179         typedef other_allocator<V> A;
180         std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(2));
181         std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(7));
182         m = mo;
183         assert(m.get_allocator() == A(2));
184         assert(m.key_comp() == C(5));
185         assert(m.size() == 3);
186         assert(distance(m.begin(), m.end()) == 3);
187         assert(*m.begin() == V(1, 1));
188         assert(*next(m.begin()) == V(2, 1));
189         assert(*next(m.begin(), 2) == V(3, 1));
190 
191         assert(mo.get_allocator() == A(2));
192         assert(mo.key_comp() == C(5));
193         assert(mo.size() == 3);
194         assert(distance(mo.begin(), mo.end()) == 3);
195         assert(*mo.begin() == V(1, 1));
196         assert(*next(mo.begin()) == V(2, 1));
197         assert(*next(mo.begin(), 2) == V(3, 1));
198     }
199 #if TEST_STD_VER >= 11
200     {
201         typedef std::pair<const int, double> V;
202         V ar[] =
203         {
204             V(1, 1),
205             V(1, 1.5),
206             V(1, 2),
207             V(2, 1),
208             V(2, 1.5),
209             V(2, 2),
210             V(3, 1),
211             V(3, 1.5),
212             V(3, 2)
213         };
214         typedef test_compare<std::less<int> > C;
215         typedef min_allocator<V> A;
216         std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
217         std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A());
218         m = mo;
219         assert(m.get_allocator() == A());
220         assert(m.key_comp() == C(5));
221         assert(m.size() == 3);
222         assert(distance(m.begin(), m.end()) == 3);
223         assert(*m.begin() == V(1, 1));
224         assert(*next(m.begin()) == V(2, 1));
225         assert(*next(m.begin(), 2) == V(3, 1));
226 
227         assert(mo.get_allocator() == A());
228         assert(mo.key_comp() == C(5));
229         assert(mo.size() == 3);
230         assert(distance(mo.begin(), mo.end()) == 3);
231         assert(*mo.begin() == V(1, 1));
232         assert(*next(mo.begin()) == V(2, 1));
233         assert(*next(mo.begin(), 2) == V(3, 1));
234     }
235     {
236         typedef std::pair<const int, double> V;
237         V ar[] =
238         {
239             V(1, 1),
240             V(1, 1.5),
241             V(1, 2),
242             V(2, 1),
243             V(2, 1.5),
244             V(2, 2),
245             V(3, 1),
246             V(3, 1.5),
247             V(3, 2)
248         };
249         typedef test_compare<std::less<int> > C;
250         typedef min_allocator<V> A;
251         std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A());
252         std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A());
253         m = mo;
254         assert(m.get_allocator() == A());
255         assert(m.key_comp() == C(5));
256         assert(m.size() == 3);
257         assert(distance(m.begin(), m.end()) == 3);
258         assert(*m.begin() == V(1, 1));
259         assert(*next(m.begin()) == V(2, 1));
260         assert(*next(m.begin(), 2) == V(3, 1));
261 
262         assert(mo.get_allocator() == A());
263         assert(mo.key_comp() == C(5));
264         assert(mo.size() == 3);
265         assert(distance(mo.begin(), mo.end()) == 3);
266         assert(*mo.begin() == V(1, 1));
267         assert(*next(mo.begin()) == V(2, 1));
268         assert(*next(mo.begin(), 2) == V(3, 1));
269     }
270 
271     assert(balanced_allocs());
272     {
273         typedef std::pair<const int, double> V;
274         V ar[] =
275         {
276             V(1, 1),
277             V(1, 1.5),
278             V(1, 2),
279             V(2, 1),
280             V(2, 1.5),
281             V(2, 2),
282             V(3, 1),
283             V(3, 1.5),
284             V(3, 2)
285         };
286         typedef test_compare<std::less<int> > C;
287         typedef counting_allocatorT<V> A;
288         std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(1));
289         std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(2));
290         m = mo;
291         assert(m.key_comp() == C(5));
292         assert(m.size() == 3);
293         assert(distance(m.begin(), m.end()) == 3);
294         assert(*m.begin() == V(1, 1));
295         assert(*next(m.begin()) == V(2, 1));
296         assert(*next(m.begin(), 2) == V(3, 1));
297 
298         assert(mo.key_comp() == C(5));
299         assert(mo.size() == 3);
300         assert(distance(mo.begin(), mo.end()) == 3);
301         assert(*mo.begin() == V(1, 1));
302         assert(*next(mo.begin()) == V(2, 1));
303         assert(*next(mo.begin(), 2) == V(3, 1));
304     }
305     assert(balanced_allocs());
306     {
307         typedef std::pair<const int, double> V;
308         V ar[] =
309         {
310             V(1, 1),
311             V(1, 1.5),
312             V(1, 2),
313             V(2, 1),
314             V(2, 1.5),
315             V(2, 2),
316             V(3, 1),
317             V(3, 1.5),
318             V(3, 2)
319         };
320         typedef test_compare<std::less<int> > C;
321         typedef counting_allocatorF<V> A;
322         std::map<int, double, C, A> mo(ar, ar+sizeof(ar)/sizeof(ar[0]), C(5), A(100));
323         std::map<int, double, C, A> m(ar, ar+sizeof(ar)/sizeof(ar[0])/2, C(3), A(200));
324         m = mo;
325         assert(m.key_comp() == C(5));
326         assert(m.size() == 3);
327         assert(distance(m.begin(), m.end()) == 3);
328         assert(*m.begin() == V(1, 1));
329         assert(*next(m.begin()) == V(2, 1));
330         assert(*next(m.begin(), 2) == V(3, 1));
331 
332         assert(mo.key_comp() == C(5));
333         assert(mo.size() == 3);
334         assert(distance(mo.begin(), mo.end()) == 3);
335         assert(*mo.begin() == V(1, 1));
336         assert(*next(mo.begin()) == V(2, 1));
337         assert(*next(mo.begin(), 2) == V(3, 1));
338     }
339     assert(balanced_allocs());
340 #endif
341 }
342