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