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 #ifndef ALLOCATORS_H 11 #define ALLOCATORS_H 12 13 #include <type_traits> 14 #include <utility> 15 16 #include "test_macros.h" 17 18 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 19 20 template <class T> 21 class A1 22 { 23 int id_; 24 public: id_(id)25 explicit A1(int id = 0) TEST_NOEXCEPT : id_(id) {} 26 27 typedef T value_type; 28 id()29 int id() const {return id_;} 30 31 static bool copy_called; 32 static bool move_called; 33 static bool allocate_called; 34 static std::pair<T*, std::size_t> deallocate_called; 35 A1(const A1 & a)36 A1(const A1& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;} A1(A1 && a)37 A1(A1&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;} 38 39 template <class U> A1(const A1<U> & a)40 A1(const A1<U>& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;} 41 template <class U> A1(A1<U> && a)42 A1(A1<U>&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;} 43 allocate(std::size_t n)44 T* allocate(std::size_t n) 45 { 46 allocate_called = true; 47 return (T*)n; 48 } 49 deallocate(T * p,std::size_t n)50 void deallocate(T* p, std::size_t n) 51 { 52 deallocate_called = std::pair<T*, std::size_t>(p, n); 53 } 54 max_size()55 std::size_t max_size() const {return id_;} 56 }; 57 58 template <class T> bool A1<T>::copy_called = false; 59 template <class T> bool A1<T>::move_called = false; 60 template <class T> bool A1<T>::allocate_called = false; 61 template <class T> std::pair<T*, std::size_t> A1<T>::deallocate_called; 62 63 template <class T, class U> 64 inline 65 bool operator==(const A1<T>& x, const A1<U>& y) 66 { 67 return x.id() == y.id(); 68 } 69 70 template <class T, class U> 71 inline 72 bool operator!=(const A1<T>& x, const A1<U>& y) 73 { 74 return !(x == y); 75 } 76 77 template <class T> 78 class A2 79 { 80 int id_; 81 public: id_(id)82 explicit A2(int id = 0) TEST_NOEXCEPT : id_(id) {} 83 84 typedef T value_type; 85 86 typedef unsigned size_type; 87 typedef int difference_type; 88 89 typedef std::true_type propagate_on_container_move_assignment; 90 id()91 int id() const {return id_;} 92 93 static bool copy_called; 94 static bool move_called; 95 static bool allocate_called; 96 A2(const A2 & a)97 A2(const A2& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;} A2(A2 && a)98 A2(A2&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;} 99 allocate(std::size_t n,const void * hint)100 T* allocate(std::size_t n, const void* hint) 101 { 102 allocate_called = true; 103 return (T*)hint; 104 } 105 }; 106 107 template <class T> bool A2<T>::copy_called = false; 108 template <class T> bool A2<T>::move_called = false; 109 template <class T> bool A2<T>::allocate_called = false; 110 111 template <class T, class U> 112 inline 113 bool operator==(const A2<T>& x, const A2<U>& y) 114 { 115 return x.id() == y.id(); 116 } 117 118 template <class T, class U> 119 inline 120 bool operator!=(const A2<T>& x, const A2<U>& y) 121 { 122 return !(x == y); 123 } 124 125 template <class T> 126 class A3 127 { 128 int id_; 129 public: id_(id)130 explicit A3(int id = 0) TEST_NOEXCEPT : id_(id) {} 131 132 typedef T value_type; 133 134 typedef std::true_type propagate_on_container_copy_assignment; 135 typedef std::true_type propagate_on_container_swap; 136 id()137 int id() const {return id_;} 138 139 static bool copy_called; 140 static bool move_called; 141 static bool constructed; 142 static bool destroy_called; 143 A3(const A3 & a)144 A3(const A3& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;} A3(A3 && a)145 A3(A3&& a) TEST_NOEXCEPT: id_(a.id()) {move_called = true;} 146 147 template <class U, class ...Args> construct(U * p,Args &&...args)148 void construct(U* p, Args&& ...args) 149 { 150 ::new (p) U(std::forward<Args>(args)...); 151 constructed = true; 152 } 153 154 template <class U> destroy(U * p)155 void destroy(U* p) 156 { 157 p->~U(); 158 destroy_called = true; 159 } 160 select_on_container_copy_construction()161 A3 select_on_container_copy_construction() const {return A3(-1);} 162 }; 163 164 template <class T> bool A3<T>::copy_called = false; 165 template <class T> bool A3<T>::move_called = false; 166 template <class T> bool A3<T>::constructed = false; 167 template <class T> bool A3<T>::destroy_called = false; 168 169 template <class T, class U> 170 inline 171 bool operator==(const A3<T>& x, const A3<U>& y) 172 { 173 return x.id() == y.id(); 174 } 175 176 template <class T, class U> 177 inline 178 bool operator!=(const A3<T>& x, const A3<U>& y) 179 { 180 return !(x == y); 181 } 182 183 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 184 185 #endif // ALLOCATORS_H 186