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 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; 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 63public: 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 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} 154