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