PageRenderTime 92ms CodeModel.GetById 54ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/libs/unordered/test/objects/test.hpp

http://hadesmem.googlecode.com/
C++ Header | 311 lines | 249 code | 52 blank | 10 comment | 20 complexity | 86bd892aedabacd0aa95aecba685a68d MD5 | raw file
  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
  9#include <boost/config.hpp>
 10#include <boost/limits.hpp>
 11#include <cstddef>
 12#include <iostream>
 13#include "../helpers/fwd.hpp"
 14#include "../helpers/count.hpp"
 15#include "../helpers/memory.hpp"
 16#include <map>
 17
 18namespace test
 19{
 20    // Note that the default hash function will work for any equal_to (but not
 21    // very well).
 22    class object;
 23    class implicitly_convertible;
 24    class hash;
 25    class less;
 26    class equal_to;
 27    template <class T> class allocator;
 28    object generate(object const*);
 29    implicitly_convertible generate(implicitly_convertible const*);
 30
 31    class object : globally_counted_object
 32    {
 33        friend class hash;
 34        friend class equal_to;
 35        friend class less;
 36        int tag1_, tag2_;
 37    public:
 38        explicit object(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
 39
 40        ~object() {
 41            tag1_ = -1;
 42            tag2_ = -1;
 43        }
 44
 45        friend bool operator==(object const& x1, object const& x2) {
 46            return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
 47        }
 48
 49        friend bool operator!=(object const& x1, object const& x2) {
 50            return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_;
 51        }
 52
 53        friend bool operator<(object const& x1, object const& x2) {
 54            return x1.tag1_ < x2.tag1_ ||
 55                (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
 56        }
 57
 58        friend object generate(object const*) {
 59            int* x = 0;
 60            return object(generate(x), generate(x));
 61        }
 62
 63        friend std::ostream& operator<<(std::ostream& out, object const& o)
 64        {
 65            return out<<"("<<o.tag1_<<","<<o.tag2_<<")";
 66        }
 67    };
 68
 69    class implicitly_convertible : globally_counted_object
 70    {
 71        int tag1_, tag2_;
 72    public:
 73
 74        explicit implicitly_convertible(int t1 = 0, int t2 = 0)
 75            : tag1_(t1), tag2_(t2)
 76            {}
 77
 78        operator object() const
 79        {
 80            return object(tag1_, tag2_);
 81        }
 82
 83        friend implicitly_convertible generate(implicitly_convertible const*) {
 84            int* x = 0;
 85            return implicitly_convertible(generate(x), generate(x));
 86        }
 87
 88        friend std::ostream& operator<<(std::ostream& out, implicitly_convertible const& o)
 89        {
 90            return out<<"("<<o.tag1_<<","<<o.tag2_<<")";
 91        }
 92    };
 93
 94    class hash
 95    {
 96        int type_;
 97    public:
 98        explicit hash(int t = 0) : type_(t) {}
 99
100        std::size_t operator()(object const& x) const {
101            switch(type_) {
102            case 1:
103                return x.tag1_;
104            case 2:
105                return x.tag2_;
106            default:
107                return x.tag1_ + x.tag2_; 
108            }
109        }
110
111        std::size_t operator()(int x) const {
112            return x;
113        }
114
115        friend bool operator==(hash const& x1, hash const& x2) {
116            return x1.type_ == x2.type_;
117        }
118
119        friend bool operator!=(hash const& x1, hash const& x2) {
120            return x1.type_ != x2.type_;
121        }
122    };
123    
124    std::size_t hash_value(test::object const& x) {
125        return hash()(x);
126    }
127
128    class less
129    {
130        int type_;
131    public:
132        explicit less(int t = 0) : type_(t) {}
133
134        bool operator()(object const& x1, object const& x2) const {
135            switch(type_) {
136            case 1:
137                return x1.tag1_ < x2.tag1_;
138            case 2:
139                return x1.tag2_ < x2.tag2_;
140            default:
141                return x1 < x2;
142            }
143        }
144
145        std::size_t operator()(int x1, int x2) const {
146            return x1 < x2;
147        }
148
149        friend bool operator==(less const& x1, less const& x2) {
150            return x1.type_ == x2.type_;
151        }
152    };
153
154    class equal_to
155    {
156        int type_;
157    public:
158        explicit equal_to(int t = 0) : type_(t) {}
159
160        bool operator()(object const& x1, object const& x2) const {
161            switch(type_) {
162            case 1:
163                return x1.tag1_ == x2.tag1_;
164            case 2:
165                return x1.tag2_ == x2.tag2_;
166            default:
167                return x1 == x2;
168            }
169        }
170
171        std::size_t operator()(int x1, int x2) const {
172            return x1 == x2;
173        }
174
175        friend bool operator==(equal_to const& x1, equal_to const& x2) {
176            return x1.type_ == x2.type_;
177        }
178
179        friend bool operator!=(equal_to const& x1, equal_to const& x2) {
180            return x1.type_ != x2.type_;
181        }
182
183        friend less create_compare(equal_to x) {
184            return less(x.type_);
185        }
186    };
187
188    namespace detail
189    {
190        // This won't be a problem as I'm only using a single compile unit
191        // in each test (this is actually require by the minimal test
192        // framework).
193        // 
194        // boostinspect:nounnamed
195        namespace {
196            test::detail::memory_tracker<std::allocator<int> > tracker;
197        }
198    }
199
200    template <class T>
201    class allocator
202    {
203# ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
204    public:
205# else
206        template <class> friend class allocator;
207# endif
208        int tag_;
209    public:
210        typedef std::size_t size_type;
211        typedef std::ptrdiff_t difference_type;
212        typedef T* pointer;
213        typedef T const* const_pointer;
214        typedef T& reference;
215        typedef T const& const_reference;
216        typedef T value_type;
217
218        template <class U> struct rebind { typedef allocator<U> other; };
219
220        explicit allocator(int t = 0) : tag_(t)
221        {
222            detail::tracker.allocator_ref();
223        }
224        
225        template <class Y> allocator(allocator<Y> const& x)
226            : tag_(x.tag_)
227        {
228            detail::tracker.allocator_ref();
229        }
230
231        allocator(allocator const& x)
232            : tag_(x.tag_)
233        {
234            detail::tracker.allocator_ref();
235        }
236
237        ~allocator()
238        {
239            detail::tracker.allocator_unref();
240        }
241
242        pointer address(reference r)
243        {
244            return pointer(&r);
245        }
246
247        const_pointer address(const_reference r)
248        {
249            return const_pointer(&r);
250        }
251
252        pointer allocate(size_type n) {
253            pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
254            detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
255            return ptr;
256        }
257
258        pointer allocate(size_type n, void const* u)
259        {
260            pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
261            detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
262            return ptr;
263        }
264
265        void deallocate(pointer p, size_type n)
266        {
267            detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_);
268            ::operator delete((void*) p);
269        }
270
271        void construct(pointer p, T const& t) {
272            detail::tracker.track_construct((void*) p, sizeof(T), tag_);
273            new(p) T(t);
274        }
275
276#if defined(BOOST_UNORDERED_STD_FORWARD)
277        template<class... Args> void construct(pointer p, Args&&... args) {
278            detail::tracker.track_construct((void*) p, sizeof(T), tag_);
279            new(p) T(std::forward<Args>(args)...);
280        }
281#endif
282
283        void destroy(pointer p) {
284            detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
285            p->~T();
286        }
287
288        size_type max_size() const {
289            return (std::numeric_limits<size_type>::max)();
290        }
291
292        bool operator==(allocator const& x) const
293        {
294            return tag_ == x.tag_;
295        }
296
297        bool operator!=(allocator const& x) const
298        {
299            return tag_ != x.tag_;
300        }
301    };
302
303    template <class T>
304    bool equivalent_impl(allocator<T> const& x, allocator<T> const& y,
305        test::derived_type)
306    {
307        return x == y;
308    }
309}
310
311#endif