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