OSDN Git Service

2004-10-23 Andrew Pinski <pinskia@physics.uc.edu>
[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   std::size_t  requested = 0;
46 };
47
48 namespace __gnu_test
49 {
50   class allocation_tracker
51   {
52   public:
53     typedef std::size_t    size_type; 
54     
55     static void*
56     allocate(size_type blocksize)
57     {
58       allocationTotal_ += blocksize;
59       return ::operator new(blocksize);
60     }
61     
62     static void
63     construct() { constructCount_++; }
64
65     static void
66     destroy() { destructCount_++; }
67
68     static void
69     deallocate(void* p, size_type blocksize)
70     {
71       ::operator delete(p);
72       deallocationTotal_ += blocksize;
73     }
74     
75     static size_type
76     allocationTotal() { return allocationTotal_; }
77     
78     static size_type
79     deallocationTotal() { return deallocationTotal_; }
80     
81     static int
82     constructCount() { return constructCount_; }
83
84     static int
85     destructCount() { return destructCount_; }
86     
87     static void
88     resetCounts()
89     {
90       allocationTotal_ = 0;
91       deallocationTotal_ = 0;
92       constructCount_ = 0;
93     destructCount_ = 0;
94     }
95
96  private:
97     static size_type  allocationTotal_;
98     static size_type  deallocationTotal_;
99     static int        constructCount_;
100     static int        destructCount_;
101   };
102
103   // A simple basic allocator that just forwards to the
104   // allocation_tracker to fulfill memory requests.  This class is
105   // templated on the target object type, but tracker isn't.
106   template<class T>
107   class tracker_alloc
108   {
109   public:
110     typedef T              value_type;
111     typedef T*             pointer;
112     typedef const T*       const_pointer;
113     typedef T&             reference;
114     typedef const T&       const_reference;
115     typedef std::size_t    size_type; 
116     typedef std::ptrdiff_t difference_type; 
117     
118     template<class U> struct rebind { typedef tracker_alloc<U> other; };
119     
120     pointer
121     address(reference value) const
122     { return &value; }
123     
124     const_pointer
125     address(const_reference value) const
126     { return &value; }
127     
128     tracker_alloc() throw()
129     { }
130
131     tracker_alloc(const tracker_alloc&) throw()
132     { }
133
134     template<class U>
135       tracker_alloc(const tracker_alloc<U>&) throw()
136       { }
137
138     ~tracker_alloc() throw()
139     { }
140
141     size_type
142     max_size() const throw()
143     { return std::numeric_limits<std::size_t>::max() / sizeof(T); }
144
145     pointer
146     allocate(size_type n, const void* = 0)
147     { 
148       return static_cast<pointer>(allocation_tracker::allocate(n * sizeof(T)));
149     }
150
151     void
152     construct(pointer p, const T& value)
153     {
154       new (p) T(value);
155       allocation_tracker::construct();
156     }
157
158     void
159     destroy(pointer p)
160     {
161       p->~T();
162       allocation_tracker::destroy();
163     }
164
165     void
166     deallocate(pointer p, size_type num)
167     { allocation_tracker::deallocate(p, num * sizeof(T)); }
168   };
169
170   template<class T1, class T2>
171     bool
172     operator==(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
173     { return true; }
174
175   template<class T1, class T2>
176     bool
177     operator!=(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
178     { return false; }
179
180   bool
181   check_construct_destroy(const char* tag, int expected_c, int expected_d);
182
183   template<typename Alloc, bool uses_global_new_and_delete>
184     bool 
185     check_new(Alloc a = Alloc())
186     {
187       bool test __attribute__((unused)) = true;
188       typename Alloc::pointer p = a.allocate(10);
189       if (uses_global_new_and_delete)  
190         test &= ( requested >= (10 * 15 * sizeof(long)) );
191       
192       test &= ( new_called == uses_global_new_and_delete );
193       a.deallocate(p, 10);
194       test &= ( delete_called == uses_global_new_and_delete );
195       
196       return test;
197     }
198
199   template<typename Alloc>
200     bool 
201     check_deallocate_null()
202     {
203       // Let's not core here...
204       Alloc  a;
205       a.deallocate(NULL, 1);
206       a.deallocate(NULL, 10);
207     }
208
209   template<typename Alloc>
210     bool 
211     check_allocate_max_size()
212     {
213       Alloc a;
214       try
215         {
216           a.allocate(a.max_size() + 1);
217         }
218       catch(std::bad_alloc&)
219         {
220           return true;
221         }
222       catch(...)
223         {
224           throw;
225         }
226       throw;
227     }
228
229 }; // namespace __gnu_test
230
231 #endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H