]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/unordered/test/unordered/allocator_traits.cpp
bump version to 19.2.0-pve1
[ceph.git] / ceph / src / boost / libs / unordered / test / unordered / allocator_traits.cpp
CommitLineData
7c673cae
FG
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
11fdf7f2 6#include <boost/core/lightweight_test.hpp>
7c673cae 7#include <boost/limits.hpp>
b32b8144
FG
8#include <boost/static_assert.hpp>
9#include <boost/type_traits/is_same.hpp>
10#include <boost/unordered/detail/implementation.hpp>
7c673cae
FG
11
12// Boilerplate
13
b32b8144
FG
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 } \
11fdf7f2
TL
39 bool operator==(name<T> const&) const { return true; } \
40 bool operator!=(name<T> const&) const { return false; } \
7c673cae
FG
41/**/
42
b32b8144
FG
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 } \
1e59de90
TL
68 bool operator==(name<T> const&) const { return true; } \
69 bool operator!=(name<T> const&) const { return false; } \
70 /**/
7c673cae 71
b32b8144
FG
72struct yes_type
73{
74 enum
75 {
76 value = true
77 };
78};
79struct no_type
80{
81 enum
82 {
83 value = false
84 };
85};
7c673cae
FG
86
87// For tracking calls...
88
89static int selected;
b32b8144 90void reset() { selected = 0; }
7c673cae 91
b32b8144 92template <typename Allocator> int call_select()
7c673cae 93{
b32b8144
FG
94 typedef boost::unordered::detail::allocator_traits<Allocator> traits;
95 Allocator a;
7c673cae 96
b32b8144
FG
97 reset();
98 BOOST_TEST(traits::select_on_container_copy_construction(a) == a);
99 return selected;
7c673cae
FG
100}
101
102// Empty allocator test
103
b32b8144 104template <typename T> struct empty_allocator
7c673cae 105{
b32b8144
FG
106 typedef T value_type;
107 ALLOCATOR_METHODS(empty_allocator)
7c673cae
FG
108};
109
110void test_empty_allocator()
111{
b32b8144
FG
112 typedef empty_allocator<int> allocator;
113 typedef boost::unordered::detail::allocator_traits<allocator> traits;
1e59de90 114#if !defined(BOOST_NO_CXX11_ALLOCATOR)
b32b8144
FG
115 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
116 std::make_unsigned<std::ptrdiff_t>::type>::value));
7c673cae 117#else
b32b8144 118 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
7c673cae 119#endif
b32b8144
FG
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);
11fdf7f2 129 BOOST_TEST(traits::is_always_equal::value);
b32b8144 130 BOOST_TEST(call_select<allocator>() == 0);
7c673cae
FG
131}
132
133// allocator 1
134
b32b8144
FG
135template <typename T> struct allocator1
136{
137 typedef T value_type;
138 ALLOCATOR_METHODS(allocator1)
139
140 typedef yes_type propagate_on_container_copy_assignment;
141 typedef yes_type propagate_on_container_move_assignment;
142 typedef yes_type propagate_on_container_swap;
11fdf7f2 143 typedef yes_type is_always_equal;
b32b8144
FG
144
145 allocator1<T> select_on_container_copy_construction() const
146 {
147 ++selected;
148 return allocator1<T>();
149 }
7c673cae
FG
150};
151
152void test_allocator1()
153{
b32b8144
FG
154 typedef allocator1<int> allocator;
155 typedef boost::unordered::detail::allocator_traits<allocator> traits;
1e59de90 156#if !defined(BOOST_NO_CXX11_ALLOCATOR)
b32b8144
FG
157 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
158 std::make_unsigned<std::ptrdiff_t>::type>::value));
7c673cae 159#else
b32b8144 160 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
7c673cae 161#endif
b32b8144
FG
162 BOOST_STATIC_ASSERT(
163 (boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
164 BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
165 BOOST_STATIC_ASSERT(
166 (boost::is_same<traits::const_pointer, int const*>::value));
167 BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
168 BOOST_TEST(traits::propagate_on_container_copy_assignment::value);
169 BOOST_TEST(traits::propagate_on_container_move_assignment::value);
170 BOOST_TEST(traits::propagate_on_container_swap::value);
11fdf7f2 171 BOOST_TEST(traits::is_always_equal::value);
b32b8144 172 BOOST_TEST(call_select<allocator>() == 1);
7c673cae
FG
173}
174
175// allocator 2
176
b32b8144 177template <typename Alloc> struct allocator2_base
7c673cae 178{
b32b8144
FG
179 Alloc select_on_container_copy_construction() const
180 {
181 ++selected;
182 return Alloc();
183 }
7c673cae
FG
184};
185
b32b8144
FG
186template <typename T> struct allocator2 : allocator2_base<allocator2<T> >
187{
188 typedef T value_type;
189 typedef T* pointer;
190 typedef T const* const_pointer;
191 typedef std::size_t size_type;
192
193 ALLOCATOR_METHODS(allocator2)
194
195 typedef no_type propagate_on_container_copy_assignment;
196 typedef no_type propagate_on_container_move_assignment;
197 typedef no_type propagate_on_container_swap;
11fdf7f2 198 typedef no_type is_always_equal;
7c673cae
FG
199};
200
201void test_allocator2()
202{
b32b8144
FG
203 typedef allocator2<int> allocator;
204 typedef boost::unordered::detail::allocator_traits<allocator> traits;
205 BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
206 BOOST_STATIC_ASSERT(
207 (boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
208 BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
209 BOOST_STATIC_ASSERT(
210 (boost::is_same<traits::const_pointer, int const*>::value));
211 BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
212 BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
213 BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
214 BOOST_TEST(!traits::propagate_on_container_swap::value);
11fdf7f2 215 BOOST_TEST(!traits::is_always_equal::value);
1e59de90
TL
216
217#if !defined(BOOST_NO_CXX11_ALLOCATOR)
218 // conditionally compile this assertion as all C++03 emulations of expression
219 // SFINAE are broken one way or another and the benefits of using Core's
220 // `allocator_traits` outweigh the costs of breaking this kind of code (i.e.
221 // inheriting SOCCC via a base)
222 //
b32b8144 223 BOOST_TEST(call_select<allocator>() == 1);
1e59de90 224#endif
7c673cae
FG
225}
226
227// allocator 3
228
b32b8144 229template <typename T> struct ptr
7c673cae 230{
b32b8144
FG
231 T* value_;
232
233 ptr(void* v) : value_((T*)v) {}
234 T& operator*() const { return *value_; }
7c673cae
FG
235};
236
b32b8144 237template <> struct ptr<void>
7c673cae 238{
b32b8144
FG
239 void* value_;
240 ptr(void* v) : value_(v) {}
7c673cae
FG
241};
242
b32b8144 243template <> struct ptr<const void>
7c673cae 244{
b32b8144
FG
245 void const* value_;
246 ptr(void const* v) : value_(v) {}
7c673cae
FG
247};
248
b32b8144 249template <typename T> struct allocator3
7c673cae 250{
b32b8144
FG
251 typedef T value_type;
252 typedef ptr<T> pointer;
253 typedef ptr<T const> const_pointer;
254 typedef unsigned short size_type;
255
11fdf7f2
TL
256 int x; // Just to make it non-empty, so that is_always_equal is false.
257
b32b8144 258 ALLOCATOR_METHODS_TYPEDEFS(allocator3)
7c673cae 259
b32b8144
FG
260 typedef yes_type propagate_on_container_copy_assignment;
261 typedef no_type propagate_on_container_move_assignment;
7c673cae 262
b32b8144
FG
263 allocator3<T> select_on_container_copy_construction() const
264 {
265 ++selected;
1e59de90
TL
266 allocator3<T> a;
267 a.x = 0;
268 return a;
b32b8144 269 }
7c673cae
FG
270};
271
272void test_allocator3()
273{
b32b8144
FG
274 typedef allocator3<int> allocator;
275 typedef boost::unordered::detail::allocator_traits<allocator> traits;
276 BOOST_STATIC_ASSERT(
277 (boost::is_same<traits::size_type, unsigned short>::value));
278 BOOST_STATIC_ASSERT(
279 (boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
280 BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, ptr<int> >::value));
281 BOOST_STATIC_ASSERT(
282 (boost::is_same<traits::const_pointer, ptr<int const> >::value));
283 BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
284 BOOST_TEST(traits::propagate_on_container_copy_assignment::value);
285 BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
286 BOOST_TEST(!traits::propagate_on_container_swap::value);
11fdf7f2 287 BOOST_TEST(!traits::is_always_equal::value);
b32b8144 288 BOOST_TEST(call_select<allocator>() == 1);
7c673cae
FG
289}
290
291int main()
292{
b32b8144
FG
293 test_empty_allocator();
294 test_allocator1();
295 test_allocator2();
296 test_allocator3();
297 return boost::report_errors();
7c673cae 298}