OSDN Git Service

2005-12-28 Chris Jefferson <chris@bubblescope.net>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / testsuite / testsuite_allocator.h
1 // -*- C++ -*-
2 // Testing allocator for the C++ library testsuite.
3 //
4 // Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
21 //
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 // This file provides an test instrumentation allocator that can be
32 // used to verify allocation functionality of standard library
33 // containers.  2002.11.25 smw
34
35 #ifndef _GLIBCXX_TESTSUITE_ALLOCATOR_H
36 #define _GLIBCXX_TESTSUITE_ALLOCATOR_H
37
38 #include <cstddef>
39 #include <limits>
40
41 namespace 
42 {
43   bool new_called = false;
44   bool delete_called = false;
45 };
46
47 namespace __gnu_test
48 {
49   class allocation_tracker
50   {
51   public:
52     typedef std::size_t    size_type; 
53     
54     static void*
55     allocate(size_type blocksize)
56     {
57       allocationTotal_ += blocksize;
58       return ::operator new(blocksize);
59     }
60     
61     static void
62     construct() { constructCount_++; }
63
64     static void
65     destroy() { destructCount_++; }
66
67     static void
68     deallocate(void* p, size_type blocksize)
69     {
70       ::operator delete(p);
71       deallocationTotal_ += blocksize;
72     }
73     
74     static size_type
75     allocationTotal() { return allocationTotal_; }
76     
77     static size_type
78     deallocationTotal() { return deallocationTotal_; }
79     
80     static int
81     constructCount() { return constructCount_; }
82
83     static int
84     destructCount() { return destructCount_; }
85     
86     static void
87     resetCounts()
88     {
89       allocationTotal_ = 0;
90       deallocationTotal_ = 0;
91       constructCount_ = 0;
92     destructCount_ = 0;
93     }
94
95  private:
96     static size_type  allocationTotal_;
97     static size_type  deallocationTotal_;
98     static int        constructCount_;
99     static int        destructCount_;
100   };
101
102   // A simple basic allocator that just forwards to the
103   // allocation_tracker to fulfill memory requests.  This class is
104   // templated on the target object type, but tracker isn't.
105   template<class T>
106   class tracker_alloc
107   {
108   public:
109     typedef T              value_type;
110     typedef T*             pointer;
111     typedef const T*       const_pointer;
112     typedef T&             reference;
113     typedef const T&       const_reference;
114     typedef std::size_t    size_type; 
115     typedef std::ptrdiff_t difference_type; 
116     
117     template<class U> struct rebind { typedef tracker_alloc<U> other; };
118     
119     pointer
120     address(reference value) const
121     { return &value; }
122     
123     const_pointer
124     address(const_reference value) const
125     { return &value; }
126     
127     tracker_alloc() throw()
128     { }
129
130     tracker_alloc(const tracker_alloc&) throw()
131     { }
132
133     template<class U>
134       tracker_alloc(const tracker_alloc<U>&) throw()
135       { }
136
137     ~tracker_alloc() throw()
138     { }
139
140     size_type
141     max_size() const throw()
142     { return std::numeric_limits<std::size_t>::max() / sizeof(T); }
143
144     pointer
145     allocate(size_type n, const void* = 0)
146     { 
147       return static_cast<pointer>(allocation_tracker::allocate(n * sizeof(T)));
148     }
149
150     void
151     construct(pointer p, const T& value)
152     {
153       new (p) T(value);
154       allocation_tracker::construct();
155     }
156
157     void
158     destroy(pointer p)
159     {
160       p->~T();
161       allocation_tracker::destroy();
162     }
163
164     void
165     deallocate(pointer p, size_type num)
166     { allocation_tracker::deallocate(p, num * sizeof(T)); }
167   };
168
169   template<class T1, class T2>
170     bool
171     operator==(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
172     { return true; }
173
174   template<class T1, class T2>
175     bool
176     operator!=(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
177     { return false; }
178
179   bool
180   check_construct_destroy(const char* tag, int expected_c, int expected_d);
181
182   template<typename Alloc, bool uses_global_new>
183     bool 
184     check_new(Alloc a = Alloc())
185     {
186       bool test __attribute__((unused)) = true;
187       a.allocate(10);
188       test &= ( new_called == uses_global_new );
189       return test;
190     }
191
192   template<typename Alloc, bool uses_global_delete>
193     bool 
194     check_delete(Alloc a = Alloc())
195     {
196       bool test __attribute__((unused)) = true;
197       typename Alloc::pointer p = a.allocate(10);
198       a.deallocate(p, 10);
199       test &= ( delete_called == uses_global_delete );
200       return test;
201     }
202
203   template<typename Alloc>
204     bool
205     check_deallocate_null()
206     {
207       // Let's not core here...
208       Alloc  a;
209       a.deallocate(NULL, 1);
210       a.deallocate(NULL, 10);
211       return true;
212     }
213
214   template<typename Alloc>
215     bool 
216     check_allocate_max_size()
217     {
218       Alloc a;
219       try
220         {
221           a.allocate(a.max_size() + 1);
222         }
223       catch(std::bad_alloc&)
224         {
225           return true;
226         }
227       catch(...)
228         {
229           throw;
230         }
231       throw;
232     }
233
234   template<typename Tp>
235     class throw_allocator
236     {
237     public:
238       typedef std::size_t                         size_type;
239       typedef std::ptrdiff_t                      difference_type;
240       typedef Tp*                                 pointer;
241       typedef const Tp*                           const_pointer;
242       typedef Tp&                                 reference;
243       typedef const Tp&                           const_reference;
244       typedef Tp                                  value_type;
245       
246       template<typename Tp1>
247         struct rebind
248         { typedef throw_allocator<Tp1> other; };
249
250       throw_allocator() throw()
251       : count(size_type(-1)) { }
252
253       throw_allocator(size_type c) throw()
254       : count(c) { }
255       
256       template<typename Tp1>
257         throw_allocator(const throw_allocator<Tp1>& b) throw()
258         : count(b.get_count()) { }
259
260       size_type get_count() const { return count; }
261       
262       pointer
263       address(reference x) const { return &x; }
264     
265       const_pointer
266       address(const_reference x) const { return &x; }
267     
268       pointer
269       allocate(size_type n, const void* = 0)
270       {
271         if (count == 0)
272           throw std::bad_alloc();
273         
274         if (count != size_type(-1))
275           --count;
276         
277         return static_cast<Tp*>(::operator new(n * sizeof(Tp)));
278       }
279       
280       void
281       deallocate(pointer p, size_type)
282       { ::operator delete(p); }
283       
284       size_type
285       max_size() const throw() 
286       { return size_type(-1) / sizeof(Tp); }
287       
288       void 
289       construct(pointer p, const Tp& val) 
290       { ::new(p) Tp(val); }
291     
292       void 
293       destroy(pointer p) { p->~Tp(); }
294
295     private:
296       template<typename Tp1>
297         friend inline bool
298         operator==(const throw_allocator&, const throw_allocator<Tp1>&)
299         { return true; }
300
301       template<typename Tp1>
302         friend inline bool
303         operator!=(const throw_allocator&, const throw_allocator<Tp1>&)
304         { return false; }
305       
306       size_type count;
307     };
308 }; // namespace __gnu_test
309
310 #endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H