]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/unordered/test/unordered/allocator_traits.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / unordered / test / unordered / allocator_traits.cpp
1
2 // Copyright 2011 Daniel James.
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <boost/detail/lightweight_test.hpp>
7 #include <boost/limits.hpp>
8 #include <boost/static_assert.hpp>
9 #include <boost/type_traits/is_same.hpp>
10 #include <boost/unordered/detail/implementation.hpp>
11
12 // Boilerplate
13
14 #define ALLOCATOR_METHODS(name) \
15 template <typename U> struct rebind \
16 { \
17 typedef name<U> other; \
18 }; \
19 \
20 name() {} \
21 template <typename Y> name(name<Y> const&) {} \
22 T* address(T& r) { return &r; } \
23 T const* address(T const& r) { return &r; } \
24 T* allocate(std::size_t n) \
25 { \
26 return static_cast<T*>(::operator new(n * sizeof(T))); \
27 } \
28 T* allocate(std::size_t n, void const*) \
29 { \
30 return static_cast<T*>(::operator new(n * sizeof(T))); \
31 } \
32 void deallocate(T* p, std::size_t) { ::operator delete((void*)p); } \
33 void construct(T* p, T const& t) { new (p) T(t); } \
34 void destroy(T* p) { p->~T(); } \
35 std::size_t max_size() const \
36 { \
37 return (std::numeric_limits<std::size_t>::max)(); \
38 } \
39 bool operator==(name<T> const&) { return true; } \
40 bool operator!=(name<T> const&) { return false; } \
41 /**/
42
43 #define ALLOCATOR_METHODS_TYPEDEFS(name) \
44 template <typename U> struct rebind \
45 { \
46 typedef name<U> other; \
47 }; \
48 \
49 name() {} \
50 template <typename Y> name(name<Y> const&) {} \
51 pointer address(T& r) { return &r; } \
52 const_pointer address(T const& r) { return &r; } \
53 pointer allocate(std::size_t n) \
54 { \
55 return pointer(::operator new(n * sizeof(T))); \
56 } \
57 pointer allocate(std::size_t n, void const*) \
58 { \
59 return pointer(::operator new(n * sizeof(T))); \
60 } \
61 void deallocate(pointer p, std::size_t) { ::operator delete((void*)p); } \
62 void construct(T* p, T const& t) { new (p) T(t); } \
63 void destroy(T* p) { p->~T(); } \
64 size_type max_size() const \
65 { \
66 return (std::numeric_limits<size_type>::max)(); \
67 } \
68 bool operator==(name<T> const&) { return true; } \
69 bool operator!=(name<T> const&) { return false; } \
70 /**/
71
72 struct yes_type
73 {
74 enum
75 {
76 value = true
77 };
78 };
79 struct no_type
80 {
81 enum
82 {
83 value = false
84 };
85 };
86
87 // For tracking calls...
88
89 static int selected;
90 void reset() { selected = 0; }
91
92 template <typename Allocator> int call_select()
93 {
94 typedef boost::unordered::detail::allocator_traits<Allocator> traits;
95 Allocator a;
96
97 reset();
98 BOOST_TEST(traits::select_on_container_copy_construction(a) == a);
99 return selected;
100 }
101
102 // Empty allocator test
103
104 template <typename T> struct empty_allocator
105 {
106 typedef T value_type;
107 ALLOCATOR_METHODS(empty_allocator)
108 };
109
110 void test_empty_allocator()
111 {
112 typedef empty_allocator<int> allocator;
113 typedef boost::unordered::detail::allocator_traits<allocator> traits;
114 #if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
115 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
116 std::make_unsigned<std::ptrdiff_t>::type>::value));
117 #else
118 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
119 #endif
120 BOOST_STATIC_ASSERT(
121 (boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
122 BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
123 BOOST_STATIC_ASSERT(
124 (boost::is_same<traits::const_pointer, int const*>::value));
125 BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
126 BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
127 BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
128 BOOST_TEST(!traits::propagate_on_container_swap::value);
129 BOOST_TEST(call_select<allocator>() == 0);
130 }
131
132 // allocator 1
133
134 template <typename T> struct allocator1
135 {
136 typedef T value_type;
137 ALLOCATOR_METHODS(allocator1)
138
139 typedef yes_type propagate_on_container_copy_assignment;
140 typedef yes_type propagate_on_container_move_assignment;
141 typedef yes_type propagate_on_container_swap;
142
143 allocator1<T> select_on_container_copy_construction() const
144 {
145 ++selected;
146 return allocator1<T>();
147 }
148 };
149
150 void test_allocator1()
151 {
152 typedef allocator1<int> allocator;
153 typedef boost::unordered::detail::allocator_traits<allocator> traits;
154 #if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
155 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
156 std::make_unsigned<std::ptrdiff_t>::type>::value));
157 #else
158 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
159 #endif
160 BOOST_STATIC_ASSERT(
161 (boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
162 BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
163 BOOST_STATIC_ASSERT(
164 (boost::is_same<traits::const_pointer, int const*>::value));
165 BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
166 BOOST_TEST(traits::propagate_on_container_copy_assignment::value);
167 BOOST_TEST(traits::propagate_on_container_move_assignment::value);
168 BOOST_TEST(traits::propagate_on_container_swap::value);
169 BOOST_TEST(call_select<allocator>() == 1);
170 }
171
172 // allocator 2
173
174 template <typename Alloc> struct allocator2_base
175 {
176 Alloc select_on_container_copy_construction() const
177 {
178 ++selected;
179 return Alloc();
180 }
181 };
182
183 template <typename T> struct allocator2 : allocator2_base<allocator2<T> >
184 {
185 typedef T value_type;
186 typedef T* pointer;
187 typedef T const* const_pointer;
188 typedef std::size_t size_type;
189
190 ALLOCATOR_METHODS(allocator2)
191
192 typedef no_type propagate_on_container_copy_assignment;
193 typedef no_type propagate_on_container_move_assignment;
194 typedef no_type propagate_on_container_swap;
195 };
196
197 void test_allocator2()
198 {
199 typedef allocator2<int> allocator;
200 typedef boost::unordered::detail::allocator_traits<allocator> traits;
201 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
202 BOOST_STATIC_ASSERT(
203 (boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
204 BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
205 BOOST_STATIC_ASSERT(
206 (boost::is_same<traits::const_pointer, int const*>::value));
207 BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
208 BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
209 BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
210 BOOST_TEST(!traits::propagate_on_container_swap::value);
211 BOOST_TEST(call_select<allocator>() == 1);
212 }
213
214 // allocator 3
215
216 template <typename T> struct ptr
217 {
218 T* value_;
219
220 ptr(void* v) : value_((T*)v) {}
221 T& operator*() const { return *value_; }
222 };
223
224 template <> struct ptr<void>
225 {
226 void* value_;
227 ptr(void* v) : value_(v) {}
228 };
229
230 template <> struct ptr<const void>
231 {
232 void const* value_;
233 ptr(void const* v) : value_(v) {}
234 };
235
236 template <typename T> struct allocator3
237 {
238 typedef T value_type;
239 typedef ptr<T> pointer;
240 typedef ptr<T const> const_pointer;
241 typedef unsigned short size_type;
242
243 ALLOCATOR_METHODS_TYPEDEFS(allocator3)
244
245 typedef yes_type propagate_on_container_copy_assignment;
246 typedef no_type propagate_on_container_move_assignment;
247
248 allocator3<T> select_on_container_copy_construction() const
249 {
250 ++selected;
251 return allocator3<T>();
252 }
253 };
254
255 void test_allocator3()
256 {
257 typedef allocator3<int> allocator;
258 typedef boost::unordered::detail::allocator_traits<allocator> traits;
259 BOOST_STATIC_ASSERT(
260 (boost::is_same<traits::size_type, unsigned short>::value));
261 BOOST_STATIC_ASSERT(
262 (boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
263 BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, ptr<int> >::value));
264 BOOST_STATIC_ASSERT(
265 (boost::is_same<traits::const_pointer, ptr<int const> >::value));
266 BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
267 BOOST_TEST(traits::propagate_on_container_copy_assignment::value);
268 BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
269 BOOST_TEST(!traits::propagate_on_container_swap::value);
270 BOOST_TEST(call_select<allocator>() == 1);
271 }
272
273 int main()
274 {
275 test_empty_allocator();
276 test_allocator1();
277 test_allocator2();
278 test_allocator3();
279 return boost::report_errors();
280 }