blob: 066d1684306e705a03d8b3a596edc825bd7f67a1 [file] [log] [blame]
Howard Hinnantc52f43e2010-08-22 00:59:46 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <memory>
11
12// allocator:
13// template <class... Args> void construct(pointer p, Args&&... args);
14
15#include <memory>
16#include <new>
17#include <cstdlib>
18#include <cassert>
19
20int new_called = 0;
21
22void* operator new(std::size_t s) throw(std::bad_alloc)
23{
24 ++new_called;
25 assert(s == 3 * sizeof(int));
26 return std::malloc(s);
27}
28
29void operator delete(void* p) throw()
30{
31 --new_called;
32 std::free(p);
33}
34
35int A_constructed = 0;
36
37struct A
38{
39 int data;
40 A() {++A_constructed;}
41
42 A(const A&) {++A_constructed;}
43
44 explicit A(int) {++A_constructed;}
45 A(int, int*) {++A_constructed;}
46
47 ~A() {--A_constructed;}
48};
49
50int move_only_constructed = 0;
51
52class move_only
53{
54 int data;
Howard Hinnant73d21a42010-09-04 23:28:19 +000055#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000056 move_only(const move_only&);
57 move_only& operator=(const move_only&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000058#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000059 move_only(move_only&);
60 move_only& operator=(move_only&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000061#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000062
63public:
64
Howard Hinnant73d21a42010-09-04 23:28:19 +000065#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000066 move_only(move_only&&) {++move_only_constructed;}
67 move_only& operator=(move_only&&) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +000068#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000069 operator std::__rv<move_only> () {return std::__rv<move_only>(*this);}
70 move_only(std::__rv<move_only>) {++move_only_constructed;}
Howard Hinnant73d21a42010-09-04 23:28:19 +000071#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000072
73 move_only() {++move_only_constructed;}
74 ~move_only() {--move_only_constructed;}
75};
76
77int main()
78{
79 {
80 std::allocator<A> a;
81 assert(new_called == 0);
82 assert(A_constructed == 0);
83
84 A* ap = a.allocate(3);
85 assert(new_called == 1);
86 assert(A_constructed == 0);
87
88 a.construct(ap);
89 assert(new_called == 1);
90 assert(A_constructed == 1);
91
92 a.destroy(ap);
93 assert(new_called == 1);
94 assert(A_constructed == 0);
95
96 a.construct(ap, A());
97 assert(new_called == 1);
98 assert(A_constructed == 1);
99
100 a.destroy(ap);
101 assert(new_called == 1);
102 assert(A_constructed == 0);
103
104 a.construct(ap, 5);
105 assert(new_called == 1);
106 assert(A_constructed == 1);
107
108 a.destroy(ap);
109 assert(new_called == 1);
110 assert(A_constructed == 0);
111
112 a.construct(ap, 5, (int*)0);
113 assert(new_called == 1);
114 assert(A_constructed == 1);
115
116 a.destroy(ap);
117 assert(new_called == 1);
118 assert(A_constructed == 0);
119
120 a.deallocate(ap, 3);
121 assert(new_called == 0);
122 assert(A_constructed == 0);
123 }
124 {
125 std::allocator<move_only> a;
126 assert(new_called == 0);
127 assert(move_only_constructed == 0);
128
129 move_only* ap = a.allocate(3);
130 assert(new_called == 1);
131 assert(move_only_constructed == 0);
132
133 a.construct(ap);
134 assert(new_called == 1);
135 assert(move_only_constructed == 1);
136
137 a.destroy(ap);
138 assert(new_called == 1);
139 assert(move_only_constructed == 0);
140
141 a.construct(ap, move_only());
142 assert(new_called == 1);
143 assert(move_only_constructed == 1);
144
145 a.destroy(ap);
146 assert(new_called == 1);
147 assert(move_only_constructed == 0);
148
149 a.deallocate(ap, 3);
150 assert(new_called == 0);
151 assert(move_only_constructed == 0);
152 }
153}