]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/unordered/test/objects/test.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / unordered / test / objects / test.hpp
CommitLineData
7c673cae
FG
1
2// Copyright 2006-2009 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#if !defined(BOOST_UNORDERED_TEST_OBJECTS_HEADER)
7#define BOOST_UNORDERED_TEST_OBJECTS_HEADER
8
b32b8144
FG
9#include "../helpers/count.hpp"
10#include "../helpers/fwd.hpp"
11#include "../helpers/memory.hpp"
7c673cae
FG
12#include <boost/config.hpp>
13#include <boost/limits.hpp>
14#include <cstddef>
7c673cae 15
b32b8144
FG
16namespace test {
17 // Note that the default hash function will work for any equal_to (but not
18 // very well).
19 class object;
20 class movable;
21 class implicitly_convertible;
22 class hash;
23 class less;
24 class equal_to;
25 template <class T> class allocator1;
26 template <class T> class allocator2;
27 object generate(object const*, random_generator);
28 movable generate(movable const*, random_generator);
29 implicitly_convertible generate(
30 implicitly_convertible const*, random_generator);
31
32 inline void ignore_variable(void const*) {}
33
34 class object : private counted_object
35 {
36 friend class hash;
37 friend class equal_to;
38 friend class less;
39 int tag1_, tag2_;
40
41 public:
42 explicit object(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
43
44 ~object()
45 {
46 tag1_ = -1;
47 tag2_ = -1;
48 }
7c673cae 49
b32b8144
FG
50 friend bool operator==(object const& x1, object const& x2)
51 {
52 return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
53 }
7c673cae 54
b32b8144 55 friend bool operator!=(object const& x1, object const& x2)
7c673cae 56 {
b32b8144
FG
57 return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_;
58 }
7c673cae 59
b32b8144
FG
60 friend bool operator<(object const& x1, object const& x2)
61 {
62 return x1.tag1_ < x2.tag1_ ||
63 (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
64 }
7c673cae 65
b32b8144
FG
66 friend object generate(object const*, random_generator g)
67 {
68 int* x = 0;
69 return object(generate(x, g), generate(x, g));
70 }
7c673cae 71
b32b8144
FG
72 friend std::ostream& operator<<(std::ostream& out, object const& o)
73 {
74 return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
75 }
76 };
7c673cae 77
b32b8144
FG
78 class movable : private counted_object
79 {
80 friend class hash;
81 friend class equal_to;
82 friend class less;
83 int tag1_, tag2_;
7c673cae 84
b32b8144
FG
85 BOOST_COPYABLE_AND_MOVABLE(movable)
86 public:
87 explicit movable(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
7c673cae 88
b32b8144
FG
89 movable(movable const& x)
90 : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
91 {
92 BOOST_TEST(x.tag1_ != -1);
93 }
7c673cae 94
b32b8144
FG
95 movable(BOOST_RV_REF(movable) x)
96 : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
97 {
98 BOOST_TEST(x.tag1_ != -1);
99 x.tag1_ = -1;
100 x.tag2_ = -1;
101 }
102
103 movable& operator=(BOOST_COPY_ASSIGN_REF(movable) x) // Copy assignment
104 {
105 BOOST_TEST(x.tag1_ != -1);
106 tag1_ = x.tag1_;
107 tag2_ = x.tag2_;
108 return *this;
109 }
110
111 movable& operator=(BOOST_RV_REF(movable) x) // Move assignment
112 {
113 BOOST_TEST(x.tag1_ != -1);
114 tag1_ = x.tag1_;
115 tag2_ = x.tag2_;
116 x.tag1_ = -1;
117 x.tag2_ = -1;
118 return *this;
119 }
120
121 ~movable()
122 {
123 tag1_ = -1;
124 tag2_ = -1;
125 }
126
127 friend bool operator==(movable const& x1, movable const& x2)
128 {
129 BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1);
130 return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
131 }
132
133 friend bool operator!=(movable const& x1, movable const& x2)
134 {
135 BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1);
136 return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_;
137 }
138
139 friend bool operator<(movable const& x1, movable const& x2)
140 {
141 BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1);
142 return x1.tag1_ < x2.tag1_ ||
143 (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
144 }
145
146 friend movable generate(movable const*, random_generator g)
147 {
148 int* x = 0;
149 return movable(generate(x, g), generate(x, g));
150 }
151
152 friend std::ostream& operator<<(std::ostream& out, movable const& o)
153 {
154 return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
155 }
156 };
157
158 class implicitly_convertible : private counted_object
159 {
160 int tag1_, tag2_;
161
162 public:
163 explicit implicitly_convertible(int t1 = 0, int t2 = 0)
164 : tag1_(t1), tag2_(t2)
165 {
166 }
167
168 operator object() const { return object(tag1_, tag2_); }
169
170 operator movable() const { return movable(tag1_, tag2_); }
171
172 friend implicitly_convertible generate(
173 implicitly_convertible const*, random_generator g)
174 {
175 int* x = 0;
176 return implicitly_convertible(generate(x, g), generate(x, g));
177 }
178
179 friend std::ostream& operator<<(
180 std::ostream& out, implicitly_convertible const& o)
181 {
182 return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
183 }
184 };
185
186 // Note: This is a deliberately bad hash function.
187 class hash
188 {
189 int type_;
190
191 public:
192 explicit hash(int t = 0) : type_(t) {}
193
194 std::size_t operator()(object const& x) const
195 {
196 int result;
197 switch (type_) {
198 case 1:
199 result = x.tag1_;
200 break;
201 case 2:
202 result = x.tag2_;
203 break;
204 default:
205 result = x.tag1_ + x.tag2_;
206 }
207 return static_cast<std::size_t>(result);
208 }
209
210 std::size_t operator()(movable const& x) const
211 {
212 int result;
213 switch (type_) {
214 case 1:
215 result = x.tag1_;
216 break;
217 case 2:
218 result = x.tag2_;
219 break;
220 default:
221 result = x.tag1_ + x.tag2_;
222 }
223 return static_cast<std::size_t>(result);
224 }
225
226 std::size_t operator()(int x) const
227 {
228 int result;
229 switch (type_) {
230 case 1:
231 result = x;
232 break;
233 case 2:
234 result = x * 7;
235 break;
236 default:
237 result = x * 256;
238 }
239 return static_cast<std::size_t>(result);
240 }
241
242 friend bool operator==(hash const& x1, hash const& x2)
243 {
244 return x1.type_ == x2.type_;
245 }
246
247 friend bool operator!=(hash const& x1, hash const& x2)
248 {
249 return x1.type_ != x2.type_;
250 }
251 };
252
253 std::size_t hash_value(test::object const& x) { return hash()(x); }
254
255 std::size_t hash_value(test::movable const& x) { return hash()(x); }
256
257 class less
258 {
259 int type_;
260
261 public:
262 explicit less(int t = 0) : type_(t) {}
263
264 bool operator()(object const& x1, object const& x2) const
265 {
266 switch (type_) {
267 case 1:
268 return x1.tag1_ < x2.tag1_;
269 case 2:
270 return x1.tag2_ < x2.tag2_;
271 default:
272 return x1 < x2;
273 }
274 }
275
276 bool operator()(movable const& x1, movable const& x2) const
277 {
278 switch (type_) {
279 case 1:
280 return x1.tag1_ < x2.tag1_;
281 case 2:
282 return x1.tag2_ < x2.tag2_;
283 default:
284 return x1 < x2;
285 }
286 }
287
288 std::size_t operator()(int x1, int x2) const { return x1 < x2; }
289
290 friend bool operator==(less const& x1, less const& x2)
291 {
292 return x1.type_ == x2.type_;
293 }
294 };
295
296 class equal_to
297 {
298 int type_;
299
300 public:
301 explicit equal_to(int t = 0) : type_(t) {}
302
303 bool operator()(object const& x1, object const& x2) const
304 {
305 switch (type_) {
306 case 1:
307 return x1.tag1_ == x2.tag1_;
308 case 2:
309 return x1.tag2_ == x2.tag2_;
310 default:
311 return x1 == x2;
312 }
313 }
314
315 bool operator()(movable const& x1, movable const& x2) const
316 {
317 switch (type_) {
318 case 1:
319 return x1.tag1_ == x2.tag1_;
320 case 2:
321 return x1.tag2_ == x2.tag2_;
322 default:
323 return x1 == x2;
324 }
325 }
326
327 std::size_t operator()(int x1, int x2) const { return x1 == x2; }
328
329 friend bool operator==(equal_to const& x1, equal_to const& x2)
330 {
331 return x1.type_ == x2.type_;
332 }
333
334 friend bool operator!=(equal_to const& x1, equal_to const& x2)
335 {
336 return x1.type_ != x2.type_;
337 }
338
339 friend less create_compare(equal_to x) { return less(x.type_); }
340 };
341
342 // allocator1 only has the old fashioned 'construct' method and has
343 // a few less typedefs. allocator2 uses a custom pointer class.
344
345 template <class T> class allocator1
346 {
347 public:
348 int tag_;
349
350 typedef T value_type;
7c673cae 351
b32b8144
FG
352 template <class U> struct rebind
353 {
354 typedef allocator1<U> other;
7c673cae
FG
355 };
356
b32b8144
FG
357 explicit allocator1(int t = 0) : tag_(t)
358 {
359 detail::tracker.allocator_ref();
360 }
361
362 template <class Y> allocator1(allocator1<Y> const& x) : tag_(x.tag_)
363 {
364 detail::tracker.allocator_ref();
365 }
366
367 allocator1(allocator1 const& x) : tag_(x.tag_)
368 {
369 detail::tracker.allocator_ref();
370 }
371
372 ~allocator1() { detail::tracker.allocator_unref(); }
373
374 T* allocate(std::size_t n)
375 {
376 T* ptr(static_cast<T*>(::operator new(n * sizeof(T))));
377 detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
378 return ptr;
379 }
380
381 T* allocate(std::size_t n, void const*)
382 {
383 T* ptr(static_cast<T*>(::operator new(n * sizeof(T))));
384 detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
385 return ptr;
386 }
387
388 void deallocate(T* p, std::size_t n)
389 {
390 detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_);
391 ::operator delete((void*)p);
392 }
7c673cae 393
b32b8144
FG
394#if BOOST_UNORDERED_CXX11_CONSTRUCTION
395 template <typename U, typename... Args> void construct(U* p, Args&&... args)
7c673cae 396 {
b32b8144
FG
397 detail::tracker.track_construct((void*)p, sizeof(U), tag_);
398 new (p) U(boost::forward<Args>(args)...);
399 }
400
401 template <typename U> void destroy(U* p)
402 {
403 detail::tracker.track_destroy((void*)p, sizeof(U), tag_);
404 p->~U();
405
406 // Work around MSVC buggy unused parameter warning.
407 ignore_variable(&p);
408 }
409#else
410 private:
411 // I'm going to claim in the documentation that construct/destroy
412 // is never used when C++11 support isn't available, so might as
413 // well check that in the text.
414 // TODO: Or maybe just disallow them for values?
415 template <typename U> void construct(U* p);
416 template <typename U, typename A0> void construct(U* p, A0 const&);
417 template <typename U, typename A0, typename A1>
418 void construct(U* p, A0 const&, A1 const&);
419 template <typename U, typename A0, typename A1, typename A2>
420 void construct(U* p, A0 const&, A1 const&, A2 const&);
421 template <typename U> void destroy(U* p);
422
423 public:
424#endif
425
426 bool operator==(allocator1 const& x) const { return tag_ == x.tag_; }
427
428 bool operator!=(allocator1 const& x) const { return tag_ != x.tag_; }
429
430 enum
431 {
432 is_select_on_copy = false,
433 is_propagate_on_swap = false,
434 is_propagate_on_assign = false,
435 is_propagate_on_move = false
436 };
437 };
438
439 template <class T> class ptr;
440 template <class T> class const_ptr;
441
442 struct void_ptr
443 {
7c673cae 444#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
b32b8144
FG
445 template <typename T> friend class ptr;
446
447 private:
7c673cae
FG
448#endif
449
b32b8144 450 void* ptr_;
7c673cae 451
b32b8144
FG
452 public:
453 void_ptr() : ptr_(0) {}
7c673cae 454
b32b8144 455 template <typename T> explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
7c673cae 456
b32b8144
FG
457 // I'm not using the safe bool idiom because the containers should be
458 // able to cope with bool conversions.
459 operator bool() const { return !!ptr_; }
7c673cae 460
b32b8144
FG
461 bool operator==(void_ptr const& x) const { return ptr_ == x.ptr_; }
462 bool operator!=(void_ptr const& x) const { return ptr_ != x.ptr_; }
463 };
7c673cae 464
b32b8144
FG
465 class void_const_ptr
466 {
7c673cae 467#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
b32b8144
FG
468 template <typename T> friend class const_ptr;
469
470 private:
7c673cae
FG
471#endif
472
b32b8144
FG
473 void* ptr_;
474
475 public:
476 void_const_ptr() : ptr_(0) {}
7c673cae 477
b32b8144
FG
478 template <typename T>
479 explicit void_const_ptr(const_ptr<T> const& x) : ptr_(x.ptr_)
480 {
481 }
7c673cae 482
b32b8144
FG
483 // I'm not using the safe bool idiom because the containers should be
484 // able to cope with bool conversions.
485 operator bool() const { return !!ptr_; }
7c673cae 486
b32b8144
FG
487 bool operator==(void_const_ptr const& x) const { return ptr_ == x.ptr_; }
488 bool operator!=(void_const_ptr const& x) const { return ptr_ != x.ptr_; }
489 };
7c673cae 490
b32b8144
FG
491 template <class T> class ptr
492 {
493 friend class allocator2<T>;
494 friend class const_ptr<T>;
495 friend struct void_ptr;
7c673cae 496
b32b8144 497 T* ptr_;
7c673cae 498
b32b8144
FG
499 ptr(T* x) : ptr_(x) {}
500
501 public:
502 ptr() : ptr_(0) {}
503 explicit ptr(void_ptr const& x) : ptr_((T*)x.ptr_) {}
504
505 T& operator*() const { return *ptr_; }
506 T* operator->() const { return ptr_; }
507 ptr& operator++()
508 {
509 ++ptr_;
510 return *this;
511 }
512 ptr operator++(int)
513 {
514 ptr tmp(*this);
515 ++ptr_;
516 return tmp;
517 }
518 ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
519 friend ptr operator+(std::ptrdiff_t s, ptr p) { return ptr<T>(s + p.ptr_); }
520 T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
521 bool operator!() const { return !ptr_; }
522
523 // I'm not using the safe bool idiom because the containers should be
524 // able to cope with bool conversions.
525 operator bool() const { return !!ptr_; }
526
527 bool operator==(ptr const& x) const { return ptr_ == x.ptr_; }
528 bool operator!=(ptr const& x) const { return ptr_ != x.ptr_; }
529 bool operator<(ptr const& x) const { return ptr_ < x.ptr_; }
530 bool operator>(ptr const& x) const { return ptr_ > x.ptr_; }
531 bool operator<=(ptr const& x) const { return ptr_ <= x.ptr_; }
532 bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; }
533 };
534
535 template <class T> class const_ptr
536 {
537 friend class allocator2<T>;
538 friend struct const_void_ptr;
539
540 T const* ptr_;
541
542 const_ptr(T const* ptr) : ptr_(ptr) {}
543
544 public:
545 const_ptr() : ptr_(0) {}
546 const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
547 explicit const_ptr(void_const_ptr const& x) : ptr_((T const*)x.ptr_) {}
548
549 T const& operator*() const { return *ptr_; }
550 T const* operator->() const { return ptr_; }
551 const_ptr& operator++()
552 {
553 ++ptr_;
554 return *this;
555 }
556 const_ptr operator++(int)
557 {
558 const_ptr tmp(*this);
559 ++ptr_;
560 return tmp;
561 }
562 const_ptr operator+(std::ptrdiff_t s) const { return const_ptr(ptr_ + s); }
563 friend const_ptr operator+(std::ptrdiff_t s, const_ptr p)
564 {
565 return ptr<T>(s + p.ptr_);
566 }
567 T const& operator[](int s) const { return ptr_[s]; }
568 bool operator!() const { return !ptr_; }
569 operator bool() const { return !!ptr_; }
570
571 bool operator==(const_ptr const& x) const { return ptr_ == x.ptr_; }
572 bool operator!=(const_ptr const& x) const { return ptr_ != x.ptr_; }
573 bool operator<(const_ptr const& x) const { return ptr_ < x.ptr_; }
574 bool operator>(const_ptr const& x) const { return ptr_ > x.ptr_; }
575 bool operator<=(const_ptr const& x) const { return ptr_ <= x.ptr_; }
576 bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; }
577 };
578
579 template <class T> class allocator2
580 {
581#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
582 public:
583#else
584 template <class> friend class allocator2;
585#endif
586 int tag_;
587
588 public:
589 typedef std::size_t size_type;
590 typedef std::ptrdiff_t difference_type;
591 typedef void_ptr void_pointer;
592 typedef void_const_ptr const_void_pointer;
593 typedef ptr<T> pointer;
594 typedef const_ptr<T> const_pointer;
595 typedef T& reference;
596 typedef T const& const_reference;
597 typedef T value_type;
598
599 template <class U> struct rebind
600 {
601 typedef allocator2<U> other;
7c673cae
FG
602 };
603
b32b8144
FG
604 explicit allocator2(int t = 0) : tag_(t)
605 {
606 detail::tracker.allocator_ref();
607 }
608
609 template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_)
610 {
611 detail::tracker.allocator_ref();
612 }
613
614 allocator2(allocator2 const& x) : tag_(x.tag_)
615 {
616 detail::tracker.allocator_ref();
617 }
618
619 ~allocator2() { detail::tracker.allocator_unref(); }
620
621 pointer address(reference r) { return pointer(&r); }
622
623 const_pointer address(const_reference r) { return const_pointer(&r); }
624
625 pointer allocate(size_type n)
626 {
627 pointer p(static_cast<T*>(::operator new(n * sizeof(T))));
628 detail::tracker.track_allocate((void*)p.ptr_, n, sizeof(T), tag_);
629 return p;
630 }
631
632 pointer allocate(size_type n, void const*)
633 {
634 pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
635 detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
636 return ptr;
637 }
638
639 void deallocate(pointer p, size_type n)
640 {
641 detail::tracker.track_deallocate((void*)p.ptr_, n, sizeof(T), tag_);
642 ::operator delete((void*)p.ptr_);
643 }
644
645 void construct(T* p, T const& t)
646 {
647 detail::tracker.track_construct((void*)p, sizeof(T), tag_);
648 new (p) T(t);
649 }
7c673cae
FG
650
651#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
b32b8144
FG
652 template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
653 {
654 detail::tracker.track_construct((void*)p, sizeof(T), tag_);
655 new (p) T(boost::forward<Args>(args)...);
656 }
7c673cae
FG
657#endif
658
b32b8144 659 void destroy(T* p)
7c673cae 660 {
b32b8144
FG
661 detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
662 p->~T();
7c673cae
FG
663 }
664
b32b8144 665 size_type max_size() const
7c673cae 666 {
b32b8144 667 return (std::numeric_limits<size_type>::max)();
7c673cae 668 }
b32b8144
FG
669
670 bool operator==(allocator2 const& x) const { return tag_ == x.tag_; }
671
672 bool operator!=(allocator2 const& x) const { return tag_ != x.tag_; }
673
674 enum
675 {
676 is_select_on_copy = false,
677 is_propagate_on_swap = false,
678 is_propagate_on_assign = false,
679 is_propagate_on_move = false
680 };
681 };
682
683 template <class T>
684 bool equivalent_impl(
685 allocator1<T> const& x, allocator1<T> const& y, test::derived_type)
686 {
687 return x == y;
688 }
689
690 template <class T>
691 bool equivalent_impl(
692 allocator2<T> const& x, allocator2<T> const& y, test::derived_type)
693 {
694 return x == y;
695 }
7c673cae
FG
696}
697
698#endif