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 // <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 20 int new_called = 0; 21 22 void* 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 29 void operator delete(void* p) throw() 30 { 31 --new_called; 32 std::free(p); 33 } 34 35 int A_constructed = 0; 36 37 struct 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 50 int move_only_constructed = 0; 51 52 class move_only 53 { 54 int data; 55 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 56 move_only(const move_only&); 57 move_only& operator=(const move_only&); 58 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 59 move_only(move_only&); 60 move_only& operator=(move_only&); 61 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 62 63 public: 64 65 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 66 move_only(move_only&&) {++move_only_constructed;} 67 move_only& operator=(move_only&&) {return *this;} 68 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES 69 operator std::__rv<move_only> () {return std::__rv<move_only>(*this);} 70 move_only(std::__rv<move_only>) {++move_only_constructed;} 71 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 72 73 move_only() {++move_only_constructed;} 74 ~move_only() {--move_only_constructed;} 75 }; 76 77 int 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 } 154