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