blob: 47ef1d5567843ee5118ffd2aed2baf871e849e74 [file] [log] [blame]
Marshall Clow98760c12014-01-16 16:58:45 +00001//===----------------------------------------------------------------------===//
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
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000010#ifndef TEST_ALLOCATOR_H
11#define TEST_ALLOCATOR_H
12
13#include <cstddef>
14#include <type_traits>
15#include <cstdlib>
16#include <new>
17#include <climits>
Marshall Clow1b921882013-12-03 00:18:10 +000018#include <cassert>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000019
Marshall Clow7b193f72015-06-03 19:56:43 +000020#include "test_macros.h"
21
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000022class test_alloc_base
23{
24protected:
Marshall Clow1b921882013-12-03 00:18:10 +000025 static int time_to_throw;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000026public:
27 static int throw_after;
Marshall Clow1b921882013-12-03 00:18:10 +000028 static int count;
29 static int alloc_count;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000030};
31
32int test_alloc_base::count = 0;
Marshall Clow1b921882013-12-03 00:18:10 +000033int test_alloc_base::time_to_throw = 0;
34int test_alloc_base::alloc_count = 0;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000035int test_alloc_base::throw_after = INT_MAX;
36
37template <class T>
38class test_allocator
39 : public test_alloc_base
40{
41 int data_;
42
43 template <class U> friend class test_allocator;
44public:
45
46 typedef unsigned size_type;
47 typedef int difference_type;
48 typedef T value_type;
49 typedef value_type* pointer;
50 typedef const value_type* const_pointer;
51 typedef typename std::add_lvalue_reference<value_type>::type reference;
52 typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
53
54 template <class U> struct rebind {typedef test_allocator<U> other;};
55
Marshall Clow1b921882013-12-03 00:18:10 +000056 test_allocator() throw() : data_(0) {++count;}
57 explicit test_allocator(int i) throw() : data_(i) {++count;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000058 test_allocator(const test_allocator& a) throw()
Marshall Clow1b921882013-12-03 00:18:10 +000059 : data_(a.data_) {++count;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000060 template <class U> test_allocator(const test_allocator<U>& a) throw()
Marshall Clow1b921882013-12-03 00:18:10 +000061 : data_(a.data_) {++count;}
62 ~test_allocator() throw() {assert(data_ >= 0); --count; data_ = -1;}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000063 pointer address(reference x) const {return &x;}
64 const_pointer address(const_reference x) const {return &x;}
65 pointer allocate(size_type n, const void* = 0)
66 {
Marshall Clow1b921882013-12-03 00:18:10 +000067 assert(data_ >= 0);
68 if (time_to_throw >= throw_after) {
Howard Hinnant9976b552013-03-23 17:27:16 +000069#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000070 throw std::bad_alloc();
Howard Hinnant9976b552013-03-23 17:27:16 +000071#else
72 std::terminate();
73#endif
74 }
Marshall Clow1b921882013-12-03 00:18:10 +000075 ++time_to_throw;
76 ++alloc_count;
Eric Fiselierb05f0592015-06-14 23:30:09 +000077 return (pointer)::operator new(n * sizeof(T));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000078 }
Dan Albert1d4a1ed2016-05-25 22:36:09 -070079 void deallocate(pointer p, size_type n)
Eric Fiselierb05f0592015-06-14 23:30:09 +000080 {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000081 size_type max_size() const throw()
82 {return UINT_MAX / sizeof(T);}
83 void construct(pointer p, const T& val)
84 {::new(p) T(val);}
Howard Hinnant73d21a42010-09-04 23:28:19 +000085#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000086 void construct(pointer p, T&& val)
87 {::new(p) T(std::move(val));}
Howard Hinnant73d21a42010-09-04 23:28:19 +000088#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000089 void destroy(pointer p) {p->~T();}
90
91 friend bool operator==(const test_allocator& x, const test_allocator& y)
92 {return x.data_ == y.data_;}
93 friend bool operator!=(const test_allocator& x, const test_allocator& y)
94 {return !(x == y);}
95};
96
Marshall Clowa178c132014-04-18 17:23:36 +000097template <class T>
98class non_default_test_allocator
99 : public test_alloc_base
100{
101 int data_;
102
103 template <class U> friend class non_default_test_allocator;
104public:
105
106 typedef unsigned size_type;
107 typedef int difference_type;
108 typedef T value_type;
109 typedef value_type* pointer;
110 typedef const value_type* const_pointer;
111 typedef typename std::add_lvalue_reference<value_type>::type reference;
112 typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
113
114 template <class U> struct rebind {typedef non_default_test_allocator<U> other;};
115
116// non_default_test_allocator() throw() : data_(0) {++count;}
117 explicit non_default_test_allocator(int i) throw() : data_(i) {++count;}
118 non_default_test_allocator(const non_default_test_allocator& a) throw()
119 : data_(a.data_) {++count;}
120 template <class U> non_default_test_allocator(const non_default_test_allocator<U>& a) throw()
121 : data_(a.data_) {++count;}
122 ~non_default_test_allocator() throw() {assert(data_ >= 0); --count; data_ = -1;}
123 pointer address(reference x) const {return &x;}
124 const_pointer address(const_reference x) const {return &x;}
125 pointer allocate(size_type n, const void* = 0)
126 {
127 assert(data_ >= 0);
128 if (time_to_throw >= throw_after) {
129#ifndef _LIBCPP_NO_EXCEPTIONS
130 throw std::bad_alloc();
131#else
132 std::terminate();
133#endif
134 }
135 ++time_to_throw;
136 ++alloc_count;
Eric Fiselierb05f0592015-06-14 23:30:09 +0000137 return (pointer)::operator new (n * sizeof(T));
Marshall Clowa178c132014-04-18 17:23:36 +0000138 }
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700139 void deallocate(pointer p, size_type n)
Eric Fiselierb05f0592015-06-14 23:30:09 +0000140 {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p); }
Marshall Clowa178c132014-04-18 17:23:36 +0000141 size_type max_size() const throw()
142 {return UINT_MAX / sizeof(T);}
143 void construct(pointer p, const T& val)
144 {::new(p) T(val);}
145#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
146 void construct(pointer p, T&& val)
147 {::new(p) T(std::move(val));}
148#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
149 void destroy(pointer p) {p->~T();}
150
151 friend bool operator==(const non_default_test_allocator& x, const non_default_test_allocator& y)
152 {return x.data_ == y.data_;}
153 friend bool operator!=(const non_default_test_allocator& x, const non_default_test_allocator& y)
154 {return !(x == y);}
155};
156
Marshall Clow1b921882013-12-03 00:18:10 +0000157template <>
158class test_allocator<void>
159 : public test_alloc_base
160{
161 int data_;
162
163 template <class U> friend class test_allocator;
164public:
165
166 typedef unsigned size_type;
167 typedef int difference_type;
168 typedef void value_type;
169 typedef value_type* pointer;
170 typedef const value_type* const_pointer;
171
172 template <class U> struct rebind {typedef test_allocator<U> other;};
173
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700174 test_allocator() throw() : data_(-1) {}
Marshall Clow1b921882013-12-03 00:18:10 +0000175 explicit test_allocator(int i) throw() : data_(i) {}
176 test_allocator(const test_allocator& a) throw()
177 : data_(a.data_) {}
178 template <class U> test_allocator(const test_allocator<U>& a) throw()
179 : data_(a.data_) {}
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700180 ~test_allocator() throw() {data_ = 0;}
Marshall Clow1b921882013-12-03 00:18:10 +0000181
182 friend bool operator==(const test_allocator& x, const test_allocator& y)
183 {return x.data_ == y.data_;}
184 friend bool operator!=(const test_allocator& x, const test_allocator& y)
185 {return !(x == y);}
186};
187
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000188template <class T>
189class other_allocator
190{
191 int data_;
192
193 template <class U> friend class other_allocator;
194
195public:
196 typedef T value_type;
197
198 other_allocator() : data_(-1) {}
199 explicit other_allocator(int i) : data_(i) {}
200 template <class U> other_allocator(const other_allocator<U>& a)
201 : data_(a.data_) {}
202 T* allocate(std::size_t n)
Eric Fiselierb05f0592015-06-14 23:30:09 +0000203 {return (T*)::operator new(n * sizeof(T));}
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700204 void deallocate(T* p, std::size_t n)
Eric Fiselierb05f0592015-06-14 23:30:09 +0000205 {::operator delete((void*)p);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000206
207 other_allocator select_on_container_copy_construction() const
208 {return other_allocator(-2);}
209
210 friend bool operator==(const other_allocator& x, const other_allocator& y)
211 {return x.data_ == y.data_;}
212 friend bool operator!=(const other_allocator& x, const other_allocator& y)
213 {return !(x == y);}
214
215 typedef std::true_type propagate_on_container_copy_assignment;
216 typedef std::true_type propagate_on_container_move_assignment;
217 typedef std::true_type propagate_on_container_swap;
218
219#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE
220 std::size_t max_size() const
221 {return UINT_MAX / sizeof(T);}
Howard Hinnant6046ace2010-08-22 00:15:28 +0000222#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000223
224};
225
Howard Hinnant6046ace2010-08-22 00:15:28 +0000226#endif // TEST_ALLOCATOR_H