OSDN Git Service

2004-10-29 Benjamin Kosnik <bkoz@redhat.com>
[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 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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       typename Alloc::pointer p = 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     }
212
213   template<typename Alloc>
214     bool 
215     check_allocate_max_size()
216     {
217       Alloc a;
218       try
219         {
220           a.allocate(a.max_size() + 1);
221         }
222       catch(std::bad_alloc&)
223         {
224           return true;
225         }
226       catch(...)
227         {
228           throw;
229         }
230       throw;
231     }
232
233 }; // namespace __gnu_test
234
235 #endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H