1 // -*- C++ -*-
2 // Testing allocator for the C++ library testsuite.
3 //
4 // Copyright (C) 2002, 2003 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 __gnu_test
42 {
43   class allocation_tracker
44   {
45   public:
46     typedef std::size_t    size_type;
47 
48     static void*
allocate(size_type blocksize)49     allocate(size_type blocksize)
50     {
51       allocationTotal_ += blocksize;
52       return ::operator new(blocksize);
53     }
54 
55     static void
construct()56     construct() { constructCount_++; }
57 
58     static void
destroy()59     destroy() { destructCount_++; }
60 
61     static void
deallocate(void * p,size_type blocksize)62     deallocate(void* p, size_type blocksize)
63     {
64       ::operator delete(p);
65       deallocationTotal_ += blocksize;
66     }
67 
68     static size_type
allocationTotal()69     allocationTotal() { return allocationTotal_; }
70 
71     static size_type
deallocationTotal()72     deallocationTotal() { return deallocationTotal_; }
73 
74     static int
constructCount()75     constructCount() { return constructCount_; }
76 
77     static int
destructCount()78     destructCount() { return destructCount_; }
79 
80     static void
resetCounts()81     resetCounts()
82     {
83       allocationTotal_ = 0;
84       deallocationTotal_ = 0;
85       constructCount_ = 0;
86     destructCount_ = 0;
87     }
88 
89  private:
90     static size_type  allocationTotal_;
91     static size_type  deallocationTotal_;
92     static int        constructCount_;
93     static int        destructCount_;
94   };
95 
96   // A simple basic allocator that just forwards to the
97   // allocation_tracker to fulfill memory requests.  This class is
98   // templated on the target object type, but tracker isn't.
99   template<class T>
100   class tracker_alloc
101   {
102   public:
103     typedef T              value_type;
104     typedef T*             pointer;
105     typedef const T*       const_pointer;
106     typedef T&             reference;
107     typedef const T&       const_reference;
108     typedef std::size_t    size_type;
109     typedef std::ptrdiff_t difference_type;
110 
111     template<class U> struct rebind { typedef tracker_alloc<U> other; };
112 
113     pointer
address(reference value)114     address(reference value) const
115     { return &value; }
116 
117     const_pointer
address(const_reference value)118     address(const_reference value) const
119     { return &value; }
120 
throw()121     tracker_alloc() throw()
122     { }
123 
throw()124     tracker_alloc(const tracker_alloc&) throw()
125     { }
126 
127     template<class U>
tracker_alloc(const tracker_alloc<U> &)128       tracker_alloc(const tracker_alloc<U>&) throw()
129       { }
130 
throw()131     ~tracker_alloc() throw()
132     { }
133 
134     size_type
max_size()135     max_size() const throw()
136     { return std::numeric_limits<std::size_t>::max() / sizeof(T); }
137 
138     pointer
139     allocate(size_type n, const void* = 0)
140     {
141       return static_cast<pointer>(allocation_tracker::allocate(n * sizeof(T)));
142     }
143 
144     void
construct(pointer p,const T & value)145     construct(pointer p, const T& value)
146     {
147       new (p) T(value);
148       allocation_tracker::construct();
149     }
150 
151     void
destroy(pointer p)152     destroy(pointer p)
153     {
154       p->~T();
155       allocation_tracker::destroy();
156     }
157 
158     void
deallocate(pointer p,size_type num)159     deallocate(pointer p, size_type num)
160     { allocation_tracker::deallocate(p, num * sizeof(T)); }
161   };
162 
163   template<class T1, class T2>
164     bool
165     operator==(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
166     { return true; }
167 
168   template<class T1, class T2>
169     bool
170     operator!=(const tracker_alloc<T1>&, const tracker_alloc<T2>&) throw()
171     { return false; }
172 }; // namespace __gnu_test
173 
174 #endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H
175 
176