• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Define some minimal classes which provide the bare minimum concepts to
7 // test that the containers don't rely on something that they shouldn't.
8 // They are not intended to be good examples of how to implement the concepts.
9 
10 #if !defined(BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER)
11 #define BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER
12 
13 #include <boost/move/move.hpp>
14 #include <cstddef>
15 #include <utility>
16 
17 #if defined(BOOST_MSVC)
18 #pragma warning(push)
19 #pragma warning(disable : 4100) // unreferenced formal parameter
20 #endif
21 
22 #if !BOOST_WORKAROUND(BOOST_MSVC, == 1500)
23 #define BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED 1
24 #else
25 #define BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED 0
26 #endif
27 
28 namespace test {
29   namespace minimal {
30     class destructible;
31     class copy_constructible;
32     class copy_constructible_equality_comparable;
33     class default_assignable;
34     class assignable;
35 
36     struct ampersand_operator_used
37     {
ampersand_operator_usedtest::minimal::ampersand_operator_used38       ampersand_operator_used() { BOOST_TEST(false); }
39     };
40 
41     template <class T> class hash;
42     template <class T> class equal_to;
43     template <class T> class ptr;
44     template <class T> class const_ptr;
45     template <class T> class allocator;
46     template <class T> class cxx11_allocator;
47 
48     struct constructor_param
49     {
operator inttest::minimal::constructor_param50       operator int() const { return 0; }
51     };
52 
53     class destructible
54     {
55     public:
destructible(constructor_param const &)56       destructible(constructor_param const&) {}
~destructible()57       ~destructible() {}
dummy_member() const58       void dummy_member() const {}
59 
60     private:
61       destructible(destructible const&);
62       destructible& operator=(destructible const&);
63     };
64 
65     class copy_constructible
66     {
67     public:
copy_constructible(constructor_param const &)68       copy_constructible(constructor_param const&) {}
copy_constructible(copy_constructible const &)69       copy_constructible(copy_constructible const&) {}
~copy_constructible()70       ~copy_constructible() {}
dummy_member() const71       void dummy_member() const {}
72 
73     private:
74       copy_constructible& operator=(copy_constructible const&);
copy_constructible()75       copy_constructible() {}
76     };
77 
78     class copy_constructible_equality_comparable
79     {
80     public:
copy_constructible_equality_comparable(constructor_param const &)81       copy_constructible_equality_comparable(constructor_param const&) {}
82 
copy_constructible_equality_comparable(copy_constructible_equality_comparable const &)83       copy_constructible_equality_comparable(
84         copy_constructible_equality_comparable const&)
85       {
86       }
87 
~copy_constructible_equality_comparable()88       ~copy_constructible_equality_comparable() {}
89 
dummy_member() const90       void dummy_member() const {}
91 
92     private:
93       copy_constructible_equality_comparable& operator=(
94         copy_constructible_equality_comparable const&);
copy_constructible_equality_comparable()95       copy_constructible_equality_comparable() {}
96 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const97       ampersand_operator_used operator&() const
98       {
99         return ampersand_operator_used();
100       }
101 #endif
102     };
103 
operator ==(copy_constructible_equality_comparable,copy_constructible_equality_comparable)104     bool operator==(copy_constructible_equality_comparable,
105       copy_constructible_equality_comparable)
106     {
107       return true;
108     }
109 
operator !=(copy_constructible_equality_comparable,copy_constructible_equality_comparable)110     bool operator!=(copy_constructible_equality_comparable,
111       copy_constructible_equality_comparable)
112     {
113       return false;
114     }
115 
116     class default_assignable
117     {
118     public:
default_assignable(constructor_param const &)119       default_assignable(constructor_param const&) {}
120 
default_assignable()121       default_assignable() {}
122 
default_assignable(default_assignable const &)123       default_assignable(default_assignable const&) {}
124 
operator =(default_assignable const &)125       default_assignable& operator=(default_assignable const&) { return *this; }
126 
~default_assignable()127       ~default_assignable() {}
128 
dummy_member() const129       void dummy_member() const {}
130 
131 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const132       ampersand_operator_used operator&() const
133       {
134         return ampersand_operator_used();
135       }
136 #endif
137     };
138 
139     class assignable
140     {
141     public:
assignable(constructor_param const &)142       assignable(constructor_param const&) {}
assignable(assignable const &)143       assignable(assignable const&) {}
operator =(assignable const &)144       assignable& operator=(assignable const&) { return *this; }
~assignable()145       ~assignable() {}
dummy_member() const146       void dummy_member() const {}
147 
148     private:
assignable()149       assignable() {}
150 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const151       ampersand_operator_used operator&() const
152       {
153         return ampersand_operator_used();
154       }
155 #endif
156     };
157 
158     struct movable_init
159     {
160     };
161 
162     class movable1
163     {
164       BOOST_MOVABLE_BUT_NOT_COPYABLE(movable1)
165 
166     public:
movable1(constructor_param const &)167       movable1(constructor_param const&) {}
movable1()168       movable1() {}
movable1(movable_init)169       explicit movable1(movable_init) {}
movable1(BOOST_RV_REF (movable1))170       movable1(BOOST_RV_REF(movable1)) {}
operator =(BOOST_RV_REF (movable1))171       movable1& operator=(BOOST_RV_REF(movable1)) { return *this; }
~movable1()172       ~movable1() {}
dummy_member() const173       void dummy_member() const {}
174     };
175 
176 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
177     class movable2
178     {
179     public:
movable2(constructor_param const &)180       movable2(constructor_param const&) {}
movable2(movable_init)181       explicit movable2(movable_init) {}
movable2(movable2 &&)182       movable2(movable2&&) {}
~movable2()183       ~movable2() {}
operator =(movable2 &&)184       movable2& operator=(movable2&&) { return *this; }
dummy_member() const185       void dummy_member() const {}
186 
187     private:
movable2()188       movable2() {}
189       movable2(movable2 const&);
190       movable2& operator=(movable2 const&);
191     };
192 #else
193     typedef movable1 movable2;
194 #endif
195 
196     template <class T> class hash
197     {
198     public:
hash(constructor_param const &)199       hash(constructor_param const&) {}
hash()200       hash() {}
hash(hash const &)201       hash(hash const&) {}
operator =(hash const &)202       hash& operator=(hash const&) { return *this; }
~hash()203       ~hash() {}
204 
operator ()(T const &) const205       std::size_t operator()(T const&) const { return 0; }
206 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const207       ampersand_operator_used operator&() const
208       {
209         return ampersand_operator_used();
210       }
211 #endif
212     };
213 
214     template <class T> class equal_to
215     {
216     public:
equal_to(constructor_param const &)217       equal_to(constructor_param const&) {}
equal_to()218       equal_to() {}
equal_to(equal_to const &)219       equal_to(equal_to const&) {}
operator =(equal_to const &)220       equal_to& operator=(equal_to const&) { return *this; }
~equal_to()221       ~equal_to() {}
222 
operator ()(T const &,T const &) const223       bool operator()(T const&, T const&) const { return true; }
224 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const225       ampersand_operator_used operator&() const
226       {
227         return ampersand_operator_used();
228       }
229 #endif
230     };
231 
232     template <class T> class ptr;
233     template <class T> class const_ptr;
234 
235     struct void_ptr
236     {
237 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
238       template <typename T> friend class ptr;
239 
240     private:
241 #endif
242 
243       void* ptr_;
244 
245     public:
void_ptrtest::minimal::void_ptr246       void_ptr() : ptr_(0) {}
247 
void_ptrtest::minimal::void_ptr248       template <typename T> explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
249 
250       // I'm not using the safe bool idiom because the containers should be
251       // able to cope with bool conversions.
operator booltest::minimal::void_ptr252       operator bool() const { return !!ptr_; }
253 
operator ==test::minimal::void_ptr254       bool operator==(void_ptr const& x) const { return ptr_ == x.ptr_; }
operator !=test::minimal::void_ptr255       bool operator!=(void_ptr const& x) const { return ptr_ != x.ptr_; }
256     };
257 
258     class void_const_ptr
259     {
260 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
261       template <typename T> friend class const_ptr;
262 
263     private:
264 #endif
265 
266       void* ptr_;
267 
268     public:
void_const_ptr()269       void_const_ptr() : ptr_(0) {}
270 
271       template <typename T>
void_const_ptr(const_ptr<T> const & x)272       explicit void_const_ptr(const_ptr<T> const& x) : ptr_(x.ptr_)
273       {
274       }
275 
276       // I'm not using the safe bool idiom because the containers should be
277       // able to cope with bool conversions.
operator bool() const278       operator bool() const { return !!ptr_; }
279 
operator ==(void_const_ptr const & x) const280       bool operator==(void_const_ptr const& x) const { return ptr_ == x.ptr_; }
operator !=(void_const_ptr const & x) const281       bool operator!=(void_const_ptr const& x) const { return ptr_ != x.ptr_; }
282     };
283 
284     template <class T> class ptr
285     {
286       friend class allocator<T>;
287       friend class const_ptr<T>;
288       friend struct void_ptr;
289 
290       T* ptr_;
291 
ptr(T * x)292       ptr(T* x) : ptr_(x) {}
293 
294     public:
ptr()295       ptr() : ptr_(0) {}
ptr(void_ptr const & x)296       explicit ptr(void_ptr const& x) : ptr_((T*)x.ptr_) {}
297 
operator *() const298       T& operator*() const { return *ptr_; }
operator ->() const299       T* operator->() const { return ptr_; }
operator ++()300       ptr& operator++()
301       {
302         ++ptr_;
303         return *this;
304       }
operator ++(int)305       ptr operator++(int)
306       {
307         ptr tmp(*this);
308         ++ptr_;
309         return tmp;
310       }
operator +(std::ptrdiff_t s) const311       ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
operator +(std::ptrdiff_t s,ptr p)312       friend ptr operator+(std::ptrdiff_t s, ptr p)
313       {
314         return ptr<T>(s + p.ptr_);
315       }
operator [](std::ptrdiff_t s) const316       T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
operator !() const317       bool operator!() const { return !ptr_; }
318 
319       // I'm not using the safe bool idiom because the containers should be
320       // able to cope with bool conversions.
operator bool() const321       operator bool() const { return !!ptr_; }
322 
operator ==(ptr const & x) const323       bool operator==(ptr const& x) const { return ptr_ == x.ptr_; }
operator !=(ptr const & x) const324       bool operator!=(ptr const& x) const { return ptr_ != x.ptr_; }
operator <(ptr const & x) const325       bool operator<(ptr const& x) const { return ptr_ < x.ptr_; }
operator >(ptr const & x) const326       bool operator>(ptr const& x) const { return ptr_ > x.ptr_; }
operator <=(ptr const & x) const327       bool operator<=(ptr const& x) const { return ptr_ <= x.ptr_; }
operator >=(ptr const & x) const328       bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; }
329 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const330       ampersand_operator_used operator&() const
331       {
332         return ampersand_operator_used();
333       }
334 #endif
335     };
336 
337     template <class T> class const_ptr
338     {
339       friend class allocator<T>;
340       friend struct const_void_ptr;
341 
342       T const* ptr_;
343 
const_ptr(T const * ptr)344       const_ptr(T const* ptr) : ptr_(ptr) {}
345 
346     public:
const_ptr()347       const_ptr() : ptr_(0) {}
const_ptr(ptr<T> const & x)348       const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
const_ptr(void_const_ptr const & x)349       explicit const_ptr(void_const_ptr const& x) : ptr_((T const*)x.ptr_) {}
350 
operator *() const351       T const& operator*() const { return *ptr_; }
operator ->() const352       T const* operator->() const { return ptr_; }
operator ++()353       const_ptr& operator++()
354       {
355         ++ptr_;
356         return *this;
357       }
operator ++(int)358       const_ptr operator++(int)
359       {
360         const_ptr tmp(*this);
361         ++ptr_;
362         return tmp;
363       }
operator +(std::ptrdiff_t s) const364       const_ptr operator+(std::ptrdiff_t s) const
365       {
366         return const_ptr(ptr_ + s);
367       }
operator +(std::ptrdiff_t s,const_ptr p)368       friend const_ptr operator+(std::ptrdiff_t s, const_ptr p)
369       {
370         return ptr<T>(s + p.ptr_);
371       }
operator [](int s) const372       T const& operator[](int s) const { return ptr_[s]; }
operator !() const373       bool operator!() const { return !ptr_; }
operator bool() const374       operator bool() const { return !!ptr_; }
375 
operator ==(const_ptr const & x) const376       bool operator==(const_ptr const& x) const { return ptr_ == x.ptr_; }
operator !=(const_ptr const & x) const377       bool operator!=(const_ptr const& x) const { return ptr_ != x.ptr_; }
operator <(const_ptr const & x) const378       bool operator<(const_ptr const& x) const { return ptr_ < x.ptr_; }
operator >(const_ptr const & x) const379       bool operator>(const_ptr const& x) const { return ptr_ > x.ptr_; }
operator <=(const_ptr const & x) const380       bool operator<=(const_ptr const& x) const { return ptr_ <= x.ptr_; }
operator >=(const_ptr const & x) const381       bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; }
382 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const383       ampersand_operator_used operator&() const
384       {
385         return ampersand_operator_used();
386       }
387 #endif
388     };
389 
390     template <class T> class allocator
391     {
392     public:
393       typedef std::size_t size_type;
394       typedef std::ptrdiff_t difference_type;
395       typedef void_ptr void_pointer;
396       typedef void_const_ptr const_void_pointer;
397       typedef ptr<T> pointer;
398       typedef const_ptr<T> const_pointer;
399       typedef T& reference;
400       typedef T const& const_reference;
401       typedef T value_type;
402 
403       template <class U> struct rebind
404       {
405         typedef allocator<U> other;
406       };
407 
allocator()408       allocator() {}
allocator(allocator<Y> const &)409       template <class Y> allocator(allocator<Y> const&) {}
allocator(allocator const &)410       allocator(allocator const&) {}
~allocator()411       ~allocator() {}
412 
address(reference r)413       pointer address(reference r) { return pointer(&r); }
address(const_reference r)414       const_pointer address(const_reference r) { return const_pointer(&r); }
415 
allocate(size_type n)416       pointer allocate(size_type n)
417       {
418         return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
419       }
420 
allocate(size_type n,const_ptr<Y>)421       template <class Y> pointer allocate(size_type n, const_ptr<Y>)
422       {
423         return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
424       }
425 
deallocate(pointer p,size_type)426       void deallocate(pointer p, size_type)
427       {
428         ::operator delete((void*)p.ptr_);
429       }
430 
construct(T * p,T const & t)431       void construct(T* p, T const& t) { new ((void*)p) T(t); }
432 
433 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
construct(T * p,BOOST_FWD_REF (Args)...args)434       template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
435       {
436         new ((void*)p) T(boost::forward<Args>(args)...);
437       }
438 #endif
439 
destroy(T * p)440       void destroy(T* p) { p->~T(); }
441 
max_size() const442       size_type max_size() const { return 1000; }
443 
444 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) ||                             \
445   BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
446     public:
operator =(allocator const &)447       allocator& operator=(allocator const&) { return *this; }
448 #else
449     private:
450       allocator& operator=(allocator const&);
451 #endif
452 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const453       ampersand_operator_used operator&() const
454       {
455         return ampersand_operator_used();
456       }
457 #endif
458     };
459 
460     template <class T> class allocator<T const>
461     {
462     public:
463       typedef std::size_t size_type;
464       typedef std::ptrdiff_t difference_type;
465       typedef void_ptr void_pointer;
466       typedef void_const_ptr const_void_pointer;
467       // Maybe these two should be const_ptr<T>
468       typedef ptr<T const> pointer;
469       typedef const_ptr<T const> const_pointer;
470       typedef T const& reference;
471       typedef T const& const_reference;
472       typedef T const value_type;
473 
474       template <class U> struct rebind
475       {
476         typedef allocator<U> other;
477       };
478 
allocator()479       allocator() {}
allocator(allocator<Y> const &)480       template <class Y> allocator(allocator<Y> const&) {}
allocator(allocator const &)481       allocator(allocator const&) {}
~allocator()482       ~allocator() {}
483 
address(const_reference r)484       const_pointer address(const_reference r) { return const_pointer(&r); }
485 
allocate(size_type n)486       pointer allocate(size_type n)
487       {
488         return pointer(static_cast<T const*>(::operator new(n * sizeof(T))));
489       }
490 
allocate(size_type n,const_ptr<Y>)491       template <class Y> pointer allocate(size_type n, const_ptr<Y>)
492       {
493         return pointer(static_cast<T const*>(::operator new(n * sizeof(T))));
494       }
495 
deallocate(pointer p,size_type)496       void deallocate(pointer p, size_type)
497       {
498         ::operator delete((void*)p.ptr_);
499       }
500 
construct(T const * p,T const & t)501       void construct(T const* p, T const& t) { new ((void*)p) T(t); }
502 
503 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
504       template <class... Args>
construct(T const * p,BOOST_FWD_REF (Args)...args)505       void construct(T const* p, BOOST_FWD_REF(Args)... args)
506       {
507         new ((void*)p) T(boost::forward<Args>(args)...);
508       }
509 #endif
510 
destroy(T const * p)511       void destroy(T const* p) { p->~T(); }
512 
max_size() const513       size_type max_size() const { return 1000; }
514 
515 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) ||                             \
516   BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
517     public:
operator =(allocator const &)518       allocator& operator=(allocator const&) { return *this; }
519 #else
520     private:
521       allocator& operator=(allocator const&);
522 #endif
523 #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
operator &() const524       ampersand_operator_used operator&() const
525       {
526         return ampersand_operator_used();
527       }
528 #endif
529     };
530 
531     template <class T>
operator ==(allocator<T> const &,allocator<T> const &)532     inline bool operator==(allocator<T> const&, allocator<T> const&)
533     {
534       return true;
535     }
536 
537     template <class T>
operator !=(allocator<T> const &,allocator<T> const &)538     inline bool operator!=(allocator<T> const&, allocator<T> const&)
539     {
540       return false;
541     }
542 
swap(allocator<T> &,allocator<T> &)543     template <class T> void swap(allocator<T>&, allocator<T>&) {}
544 
545     // C++11 allocator
546     //
547     // Not a fully minimal C++11 allocator, just what I support. Hopefully will
548     // cut down further in the future.
549 
550     template <class T> class cxx11_allocator
551     {
552     public:
553       typedef T value_type;
554       // template <class U> struct rebind { typedef cxx11_allocator<U> other; };
555 
cxx11_allocator()556       cxx11_allocator() {}
cxx11_allocator(cxx11_allocator<Y> const &)557       template <class Y> cxx11_allocator(cxx11_allocator<Y> const&) {}
cxx11_allocator(cxx11_allocator const &)558       cxx11_allocator(cxx11_allocator const&) {}
~cxx11_allocator()559       ~cxx11_allocator() {}
560 
address(T & r)561       T* address(T& r) { return &r; }
address(T const & r)562       T const* address(T const& r) { return &r; }
563 
allocate(std::size_t n)564       T* allocate(std::size_t n)
565       {
566         return static_cast<T*>(::operator new(n * sizeof(T)));
567       }
568 
allocate(std::size_t n,const_ptr<Y>)569       template <class Y> T* allocate(std::size_t n, const_ptr<Y>)
570       {
571         return static_cast<T*>(::operator new(n * sizeof(T)));
572       }
573 
deallocate(T * p,std::size_t)574       void deallocate(T* p, std::size_t) { ::operator delete((void*)p); }
575 
construct(T * p,T const & t)576       void construct(T* p, T const& t) { new ((void*)p) T(t); }
577 
578 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
construct(T * p,BOOST_FWD_REF (Args)...args)579       template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
580       {
581         new ((void*)p) T(boost::forward<Args>(args)...);
582       }
583 #endif
584 
destroy(T * p)585       void destroy(T* p) { p->~T(); }
586 
max_size() const587       std::size_t max_size() const { return 1000u; }
588     };
589 
590     template <class T>
operator ==(cxx11_allocator<T> const &,cxx11_allocator<T> const &)591     inline bool operator==(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
592     {
593       return true;
594     }
595 
596     template <class T>
operator !=(cxx11_allocator<T> const &,cxx11_allocator<T> const &)597     inline bool operator!=(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
598     {
599       return false;
600     }
601 
swap(cxx11_allocator<T> &,cxx11_allocator<T> &)602     template <class T> void swap(cxx11_allocator<T>&, cxx11_allocator<T>&) {}
603   }
604 }
605 
606 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
607 namespace boost {
608 #else
609 namespace test {
610   namespace minimal {
611 #endif
hash_value(test::minimal::copy_constructible_equality_comparable)612   std::size_t hash_value(test::minimal::copy_constructible_equality_comparable)
613   {
614     return 1;
615   }
616 #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
617 }
618 }
619 #else
620   }
621 #endif
622 
623 #if defined(BOOST_MSVC)
624 #pragma warning(pop)
625 #endif
626 
627 #endif
628