1 #ifndef TEST_ALLOCATOR_H 2 #define TEST_ALLOCATOR_H 3 4 #include <cstddef> 5 #include <type_traits> 6 #include <cstdlib> 7 #include <new> 8 #include <climits> 9 10 class test_alloc_base 11 { 12 public: 13 static int count; 14 public: 15 static int throw_after; 16 }; 17 18 int test_alloc_base::count = 0; 19 int test_alloc_base::throw_after = INT_MAX; 20 21 template <class T> 22 class test_allocator 23 : public test_alloc_base 24 { 25 int data_; 26 27 template <class U> friend class test_allocator; 28 public: 29 30 typedef unsigned size_type; 31 typedef int difference_type; 32 typedef T value_type; 33 typedef value_type* pointer; 34 typedef const value_type* const_pointer; 35 typedef typename std::add_lvalue_reference<value_type>::type reference; 36 typedef typename std::add_lvalue_reference<const value_type>::type const_reference; 37 38 template <class U> struct rebind {typedef test_allocator<U> other;}; 39 throw()40 test_allocator() throw() : data_(-1) {} test_allocator(int i)41 explicit test_allocator(int i) throw() : data_(i) {} throw()42 test_allocator(const test_allocator& a) throw() 43 : data_(a.data_) {} test_allocator(const test_allocator<U> & a)44 template <class U> test_allocator(const test_allocator<U>& a) throw() 45 : data_(a.data_) {} throw()46 ~test_allocator() throw() {data_ = 0;} address(reference x)47 pointer address(reference x) const {return &x;} address(const_reference x)48 const_pointer address(const_reference x) const {return &x;} 49 pointer allocate(size_type n, const void* = 0) 50 { 51 if (count >= throw_after) 52 throw std::bad_alloc(); 53 ++count; 54 return (pointer)std::malloc(n * sizeof(T)); 55 } deallocate(pointer p,size_type n)56 void deallocate(pointer p, size_type n) 57 {--count; std::free(p);} max_size()58 size_type max_size() const throw() 59 {return UINT_MAX / sizeof(T);} construct(pointer p,const T & val)60 void construct(pointer p, const T& val) 61 {::new(p) T(val);} 62 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES construct(pointer p,T && val)63 void construct(pointer p, T&& val) 64 {::new(p) T(std::move(val));} 65 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES destroy(pointer p)66 void destroy(pointer p) {p->~T();} 67 68 friend bool operator==(const test_allocator& x, const test_allocator& y) 69 {return x.data_ == y.data_;} 70 friend bool operator!=(const test_allocator& x, const test_allocator& y) 71 {return !(x == y);} 72 }; 73 74 template <> 75 class test_allocator<void> 76 : public test_alloc_base 77 { 78 int data_; 79 80 template <class U> friend class test_allocator; 81 public: 82 83 typedef unsigned size_type; 84 typedef int difference_type; 85 typedef void value_type; 86 typedef value_type* pointer; 87 typedef const value_type* const_pointer; 88 89 template <class U> struct rebind {typedef test_allocator<U> other;}; 90 throw()91 test_allocator() throw() : data_(-1) {} test_allocator(int i)92 explicit test_allocator(int i) throw() : data_(i) {} throw()93 test_allocator(const test_allocator& a) throw() 94 : data_(a.data_) {} test_allocator(const test_allocator<U> & a)95 template <class U> test_allocator(const test_allocator<U>& a) throw() 96 : data_(a.data_) {} throw()97 ~test_allocator() throw() {data_ = 0;} 98 99 friend bool operator==(const test_allocator& x, const test_allocator& y) 100 {return x.data_ == y.data_;} 101 friend bool operator!=(const test_allocator& x, const test_allocator& y) 102 {return !(x == y);} 103 }; 104 105 template <class T> 106 class other_allocator 107 { 108 int data_; 109 110 template <class U> friend class other_allocator; 111 112 public: 113 typedef T value_type; 114 other_allocator()115 other_allocator() : data_(-1) {} other_allocator(int i)116 explicit other_allocator(int i) : data_(i) {} other_allocator(const other_allocator<U> & a)117 template <class U> other_allocator(const other_allocator<U>& a) 118 : data_(a.data_) {} allocate(std::size_t n)119 T* allocate(std::size_t n) 120 {return (T*)std::malloc(n * sizeof(T));} deallocate(T * p,std::size_t n)121 void deallocate(T* p, std::size_t n) 122 {std::free(p);} 123 select_on_container_copy_construction()124 other_allocator select_on_container_copy_construction() const 125 {return other_allocator(-2);} 126 127 friend bool operator==(const other_allocator& x, const other_allocator& y) 128 {return x.data_ == y.data_;} 129 friend bool operator!=(const other_allocator& x, const other_allocator& y) 130 {return !(x == y);} 131 132 typedef std::true_type propagate_on_container_copy_assignment; 133 typedef std::true_type propagate_on_container_move_assignment; 134 typedef std::true_type propagate_on_container_swap; 135 136 #ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE max_size()137 std::size_t max_size() const 138 {return UINT_MAX / sizeof(T);} 139 #endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE 140 141 }; 142 143 #endif // TEST_ALLOCATOR_H 144