]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/unordered/test/objects/test.hpp
update ceph source to reef 18.1.2
[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:
11fdf7f2
TL
192 hash() : type_(0) {}
193
194 explicit hash(int t) : type_(t) {}
b32b8144
FG
195
196 std::size_t operator()(object const& x) const
197 {
1e59de90 198 unsigned result;
b32b8144
FG
199 switch (type_) {
200 case 1:
1e59de90 201 result = static_cast<unsigned>(x.tag1_);
b32b8144
FG
202 break;
203 case 2:
1e59de90 204 result = static_cast<unsigned>(x.tag2_);
b32b8144
FG
205 break;
206 default:
1e59de90
TL
207 result =
208 static_cast<unsigned>(x.tag1_) + static_cast<unsigned>(x.tag2_);
b32b8144 209 }
1e59de90 210 return result;
b32b8144
FG
211 }
212
213 std::size_t operator()(movable const& x) const
214 {
1e59de90 215 unsigned result;
b32b8144
FG
216 switch (type_) {
217 case 1:
1e59de90 218 result = static_cast<unsigned>(x.tag1_);
b32b8144
FG
219 break;
220 case 2:
1e59de90 221 result = static_cast<unsigned>(x.tag2_);
b32b8144
FG
222 break;
223 default:
1e59de90
TL
224 result =
225 static_cast<unsigned>(x.tag1_) + static_cast<unsigned>(x.tag2_);
b32b8144 226 }
1e59de90 227 return result;
b32b8144
FG
228 }
229
230 std::size_t operator()(int x) const
231 {
232 int result;
233 switch (type_) {
234 case 1:
235 result = x;
236 break;
237 case 2:
238 result = x * 7;
239 break;
240 default:
241 result = x * 256;
242 }
243 return static_cast<std::size_t>(result);
244 }
245
246 friend bool operator==(hash const& x1, hash const& x2)
247 {
248 return x1.type_ == x2.type_;
249 }
250
251 friend bool operator!=(hash const& x1, hash const& x2)
252 {
253 return x1.type_ != x2.type_;
254 }
255 };
256
257 std::size_t hash_value(test::object const& x) { return hash()(x); }
258
259 std::size_t hash_value(test::movable const& x) { return hash()(x); }
260
261 class less
262 {
263 int type_;
264
265 public:
266 explicit less(int t = 0) : type_(t) {}
267
268 bool operator()(object const& x1, object const& x2) const
269 {
270 switch (type_) {
271 case 1:
272 return x1.tag1_ < x2.tag1_;
273 case 2:
274 return x1.tag2_ < x2.tag2_;
275 default:
276 return x1 < x2;
277 }
278 }
279
280 bool operator()(movable const& x1, movable const& x2) const
281 {
282 switch (type_) {
283 case 1:
284 return x1.tag1_ < x2.tag1_;
285 case 2:
286 return x1.tag2_ < x2.tag2_;
287 default:
288 return x1 < x2;
289 }
290 }
291
292 std::size_t operator()(int x1, int x2) const { return x1 < x2; }
293
294 friend bool operator==(less const& x1, less const& x2)
295 {
296 return x1.type_ == x2.type_;
297 }
298 };
299
300 class equal_to
301 {
302 int type_;
303
304 public:
11fdf7f2
TL
305 equal_to() : type_(0) {}
306
307 explicit equal_to(int t) : type_(t) {}
b32b8144
FG
308
309 bool operator()(object const& x1, object const& x2) const
310 {
311 switch (type_) {
312 case 1:
313 return x1.tag1_ == x2.tag1_;
314 case 2:
315 return x1.tag2_ == x2.tag2_;
316 default:
317 return x1 == x2;
318 }
319 }
320
321 bool operator()(movable const& x1, movable const& x2) const
322 {
323 switch (type_) {
324 case 1:
325 return x1.tag1_ == x2.tag1_;
326 case 2:
327 return x1.tag2_ == x2.tag2_;
328 default:
329 return x1 == x2;
330 }
331 }
332
333 std::size_t operator()(int x1, int x2) const { return x1 == x2; }
334
335 friend bool operator==(equal_to const& x1, equal_to const& x2)
336 {
337 return x1.type_ == x2.type_;
338 }
339
340 friend bool operator!=(equal_to const& x1, equal_to const& x2)
341 {
342 return x1.type_ != x2.type_;
343 }
344
345 friend less create_compare(equal_to x) { return less(x.type_); }
346 };
347
348 // allocator1 only has the old fashioned 'construct' method and has
349 // a few less typedefs. allocator2 uses a custom pointer class.
350
351 template <class T> class allocator1
352 {
353 public:
354 int tag_;
355
356 typedef T value_type;
7c673cae 357
b32b8144
FG
358 template <class U> struct rebind
359 {
360 typedef allocator1<U> other;
7c673cae
FG
361 };
362
11fdf7f2
TL
363 allocator1() : tag_(0) { detail::tracker.allocator_ref(); }
364
365 explicit allocator1(int t) : tag_(t) { detail::tracker.allocator_ref(); }
b32b8144
FG
366
367 template <class Y> allocator1(allocator1<Y> const& x) : tag_(x.tag_)
368 {
369 detail::tracker.allocator_ref();
370 }
371
372 allocator1(allocator1 const& x) : tag_(x.tag_)
373 {
374 detail::tracker.allocator_ref();
375 }
376
377 ~allocator1() { detail::tracker.allocator_unref(); }
378
379 T* allocate(std::size_t n)
380 {
381 T* ptr(static_cast<T*>(::operator new(n * sizeof(T))));
382 detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
383 return ptr;
384 }
385
386 T* allocate(std::size_t n, void const*)
387 {
388 T* ptr(static_cast<T*>(::operator new(n * sizeof(T))));
389 detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
390 return ptr;
391 }
392
393 void deallocate(T* p, std::size_t n)
394 {
395 detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_);
396 ::operator delete((void*)p);
397 }
7c673cae 398
b32b8144
FG
399#if BOOST_UNORDERED_CXX11_CONSTRUCTION
400 template <typename U, typename... Args> void construct(U* p, Args&&... args)
7c673cae 401 {
b32b8144
FG
402 detail::tracker.track_construct((void*)p, sizeof(U), tag_);
403 new (p) U(boost::forward<Args>(args)...);
404 }
405
406 template <typename U> void destroy(U* p)
407 {
408 detail::tracker.track_destroy((void*)p, sizeof(U), tag_);
409 p->~U();
410
411 // Work around MSVC buggy unused parameter warning.
412 ignore_variable(&p);
413 }
414#else
415 private:
416 // I'm going to claim in the documentation that construct/destroy
417 // is never used when C++11 support isn't available, so might as
418 // well check that in the text.
419 // TODO: Or maybe just disallow them for values?
420 template <typename U> void construct(U* p);
421 template <typename U, typename A0> void construct(U* p, A0 const&);
422 template <typename U, typename A0, typename A1>
423 void construct(U* p, A0 const&, A1 const&);
424 template <typename U, typename A0, typename A1, typename A2>
425 void construct(U* p, A0 const&, A1 const&, A2 const&);
426 template <typename U> void destroy(U* p);
427
428 public:
429#endif
430
431 bool operator==(allocator1 const& x) const { return tag_ == x.tag_; }
432
433 bool operator!=(allocator1 const& x) const { return tag_ != x.tag_; }
434
435 enum
436 {
437 is_select_on_copy = false,
438 is_propagate_on_swap = false,
439 is_propagate_on_assign = false,
440 is_propagate_on_move = false
441 };
442 };
443
444 template <class T> class ptr;
445 template <class T> class const_ptr;
446
447 struct void_ptr
448 {
7c673cae 449#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
b32b8144
FG
450 template <typename T> friend class ptr;
451
452 private:
7c673cae
FG
453#endif
454
b32b8144 455 void* ptr_;
7c673cae 456
b32b8144
FG
457 public:
458 void_ptr() : ptr_(0) {}
7c673cae 459
b32b8144 460 template <typename T> explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
7c673cae 461
b32b8144
FG
462 // I'm not using the safe bool idiom because the containers should be
463 // able to cope with bool conversions.
464 operator bool() const { return !!ptr_; }
7c673cae 465
b32b8144
FG
466 bool operator==(void_ptr const& x) const { return ptr_ == x.ptr_; }
467 bool operator!=(void_ptr const& x) const { return ptr_ != x.ptr_; }
468 };
7c673cae 469
b32b8144
FG
470 class void_const_ptr
471 {
7c673cae 472#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
b32b8144
FG
473 template <typename T> friend class const_ptr;
474
475 private:
7c673cae
FG
476#endif
477
b32b8144
FG
478 void* ptr_;
479
480 public:
481 void_const_ptr() : ptr_(0) {}
7c673cae 482
b32b8144
FG
483 template <typename T>
484 explicit void_const_ptr(const_ptr<T> const& x) : ptr_(x.ptr_)
485 {
486 }
7c673cae 487
b32b8144
FG
488 // I'm not using the safe bool idiom because the containers should be
489 // able to cope with bool conversions.
490 operator bool() const { return !!ptr_; }
7c673cae 491
b32b8144
FG
492 bool operator==(void_const_ptr const& x) const { return ptr_ == x.ptr_; }
493 bool operator!=(void_const_ptr const& x) const { return ptr_ != x.ptr_; }
494 };
7c673cae 495
b32b8144
FG
496 template <class T> class ptr
497 {
498 friend class allocator2<T>;
499 friend class const_ptr<T>;
500 friend struct void_ptr;
7c673cae 501
b32b8144 502 T* ptr_;
7c673cae 503
b32b8144
FG
504 ptr(T* x) : ptr_(x) {}
505
506 public:
507 ptr() : ptr_(0) {}
508 explicit ptr(void_ptr const& x) : ptr_((T*)x.ptr_) {}
509
510 T& operator*() const { return *ptr_; }
511 T* operator->() const { return ptr_; }
512 ptr& operator++()
513 {
514 ++ptr_;
515 return *this;
516 }
517 ptr operator++(int)
518 {
519 ptr tmp(*this);
520 ++ptr_;
521 return tmp;
522 }
523 ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
524 friend ptr operator+(std::ptrdiff_t s, ptr p) { return ptr<T>(s + p.ptr_); }
525 T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
526 bool operator!() const { return !ptr_; }
527
528 // I'm not using the safe bool idiom because the containers should be
529 // able to cope with bool conversions.
530 operator bool() const { return !!ptr_; }
531
532 bool operator==(ptr const& x) const { return ptr_ == x.ptr_; }
533 bool operator!=(ptr const& x) const { return ptr_ != x.ptr_; }
534 bool operator<(ptr const& x) const { return ptr_ < x.ptr_; }
535 bool operator>(ptr const& x) const { return ptr_ > x.ptr_; }
536 bool operator<=(ptr const& x) const { return ptr_ <= x.ptr_; }
537 bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; }
538 };
539
540 template <class T> class const_ptr
541 {
542 friend class allocator2<T>;
543 friend struct const_void_ptr;
544
545 T const* ptr_;
546
547 const_ptr(T const* ptr) : ptr_(ptr) {}
548
549 public:
550 const_ptr() : ptr_(0) {}
551 const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
552 explicit const_ptr(void_const_ptr const& x) : ptr_((T const*)x.ptr_) {}
553
554 T const& operator*() const { return *ptr_; }
555 T const* operator->() const { return ptr_; }
556 const_ptr& operator++()
557 {
558 ++ptr_;
559 return *this;
560 }
561 const_ptr operator++(int)
562 {
563 const_ptr tmp(*this);
564 ++ptr_;
565 return tmp;
566 }
567 const_ptr operator+(std::ptrdiff_t s) const { return const_ptr(ptr_ + s); }
568 friend const_ptr operator+(std::ptrdiff_t s, const_ptr p)
569 {
570 return ptr<T>(s + p.ptr_);
571 }
572 T const& operator[](int s) const { return ptr_[s]; }
573 bool operator!() const { return !ptr_; }
574 operator bool() const { return !!ptr_; }
575
576 bool operator==(const_ptr const& x) const { return ptr_ == x.ptr_; }
577 bool operator!=(const_ptr const& x) const { return ptr_ != x.ptr_; }
578 bool operator<(const_ptr const& x) const { return ptr_ < x.ptr_; }
579 bool operator>(const_ptr const& x) const { return ptr_ > x.ptr_; }
580 bool operator<=(const_ptr const& x) const { return ptr_ <= x.ptr_; }
581 bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; }
582 };
583
584 template <class T> class allocator2
585 {
586#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
587 public:
588#else
589 template <class> friend class allocator2;
590#endif
591 int tag_;
592
593 public:
594 typedef std::size_t size_type;
595 typedef std::ptrdiff_t difference_type;
596 typedef void_ptr void_pointer;
597 typedef void_const_ptr const_void_pointer;
598 typedef ptr<T> pointer;
599 typedef const_ptr<T> const_pointer;
600 typedef T& reference;
601 typedef T const& const_reference;
602 typedef T value_type;
603
604 template <class U> struct rebind
605 {
606 typedef allocator2<U> other;
7c673cae
FG
607 };
608
11fdf7f2
TL
609 allocator2() : tag_(0) { detail::tracker.allocator_ref(); }
610
611 explicit allocator2(int t) : tag_(t) { detail::tracker.allocator_ref(); }
b32b8144
FG
612
613 template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_)
614 {
615 detail::tracker.allocator_ref();
616 }
617
618 allocator2(allocator2 const& x) : tag_(x.tag_)
619 {
620 detail::tracker.allocator_ref();
621 }
622
623 ~allocator2() { detail::tracker.allocator_unref(); }
624
625 pointer address(reference r) { return pointer(&r); }
626
627 const_pointer address(const_reference r) { return const_pointer(&r); }
628
629 pointer allocate(size_type n)
630 {
631 pointer p(static_cast<T*>(::operator new(n * sizeof(T))));
632 detail::tracker.track_allocate((void*)p.ptr_, n, sizeof(T), tag_);
633 return p;
634 }
635
636 pointer allocate(size_type n, void const*)
637 {
638 pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
639 detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
640 return ptr;
641 }
642
643 void deallocate(pointer p, size_type n)
644 {
645 detail::tracker.track_deallocate((void*)p.ptr_, n, sizeof(T), tag_);
646 ::operator delete((void*)p.ptr_);
647 }
648
649 void construct(T* p, T const& t)
650 {
651 detail::tracker.track_construct((void*)p, sizeof(T), tag_);
652 new (p) T(t);
653 }
7c673cae
FG
654
655#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
b32b8144
FG
656 template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
657 {
658 detail::tracker.track_construct((void*)p, sizeof(T), tag_);
659 new (p) T(boost::forward<Args>(args)...);
660 }
7c673cae
FG
661#endif
662
b32b8144 663 void destroy(T* p)
7c673cae 664 {
b32b8144
FG
665 detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
666 p->~T();
7c673cae
FG
667 }
668
b32b8144 669 size_type max_size() const
7c673cae 670 {
b32b8144 671 return (std::numeric_limits<size_type>::max)();
7c673cae 672 }
b32b8144
FG
673
674 bool operator==(allocator2 const& x) const { return tag_ == x.tag_; }
675
676 bool operator!=(allocator2 const& x) const { return tag_ != x.tag_; }
677
678 enum
679 {
680 is_select_on_copy = false,
681 is_propagate_on_swap = false,
682 is_propagate_on_assign = false,
683 is_propagate_on_move = false
684 };
685 };
686
687 template <class T>
688 bool equivalent_impl(
689 allocator1<T> const& x, allocator1<T> const& y, test::derived_type)
690 {
691 return x == y;
692 }
693
694 template <class T>
695 bool equivalent_impl(
696 allocator2<T> const& x, allocator2<T> const& y, test::derived_type)
697 {
698 return x == y;
699 }
7c673cae
FG
700}
701
702#endif