2
* Copyright (c) 1996-1997
3
* Silicon Graphics Computer Systems, Inc.
5
* Permission to use, copy, modify, distribute and sell this software
6
* and its documentation for any purpose is hereby granted without fee,
7
* provided that the above copyright notice appear in all copies and
8
* that both that copyright notice and this permission notice appear
9
* in supporting documentation. Silicon Graphics makes no
10
* representations about the suitability of this software for any
11
* purpose. It is provided "as is" without express or implied warranty.
14
* Hewlett-Packard Company
16
* Permission to use, copy, modify, distribute and sell this software
17
* and its documentation for any purpose is hereby granted without fee,
18
* provided that the above copyright notice appear in all copies and
19
* that both that copyright notice and this permission notice appear
20
* in supporting documentation. Hewlett-Packard Company makes no
21
* representations about the suitability of this software for any
22
* purpose. It is provided "as is" without express or implied warranty.
26
* This implements standard-conforming allocators that interact with
27
* the garbage collector. Gc_alloctor<T> allocates garbage-collectable
28
* objects of type T. Traceable_allocator<T> allocates objects that
29
* are not temselves garbage collected, but are scanned by the
30
* collector for pointers to collectable objects. Traceable_alloc
31
* should be used for explicitly managed STL containers that may
32
* point to collectable objects.
34
* This code was derived from an earlier version of the GNU C++ standard
35
* library, which itself was derived from the SGI STL implementation.
38
/* First some helpers to allow us to dispatch on whether or not a type
39
* is known to be pointerfree.
40
* These are private, except that the client may invoke the
41
* GC_DECLARE_PTRFREE macro.
44
struct GC_true_type {};
45
struct GC_false_type {};
47
template <class GC_tp>
48
struct GC_type_traits {
49
GC_false_type GC_is_ptr_free;
52
# define GC_DECLARE_PTRFREE(T) \
53
template<> struct GC_type_traits<T> { GC_true_type GC_is_ptr_free; }
55
GC_DECLARE_PTRFREE(signed char);
56
GC_DECLARE_PTRFREE(unsigned char);
57
GC_DECLARE_PTRFREE(signed short);
58
GC_DECLARE_PTRFREE(unsigned short);
59
GC_DECLARE_PTRFREE(signed int);
60
GC_DECLARE_PTRFREE(unsigned int);
61
GC_DECLARE_PTRFREE(signed long);
62
GC_DECLARE_PTRFREE(unsigned long);
63
GC_DECLARE_PTRFREE(float);
64
GC_DECLARE_PTRFREE(double);
65
/* The client may want to add others. */
67
// In the following GC_Tp is GC_true_type iff we are allocating a
68
// pointerfree object.
69
template <class GC_Tp>
70
inline void * GC_selective_alloc(size_t n, GC_Tp) {
75
inline void * GC_selective_alloc<GC_true_type>(size_t n, GC_true_type) {
76
return GC_MALLOC_ATOMIC(n);
79
/* Now the public gc_allocator<T> class:
81
template <class GC_Tp>
84
typedef size_t size_type;
85
typedef ptrdiff_t difference_type;
86
typedef GC_Tp* pointer;
87
typedef const GC_Tp* const_pointer;
88
typedef GC_Tp& reference;
89
typedef const GC_Tp& const_reference;
90
typedef GC_Tp value_type;
92
template <class GC_Tp1> struct rebind {
93
typedef gc_allocator<GC_Tp1> other;
98
// I'm not sure why this is needed here in addition to the following.
99
// The standard specifies it for the standard allocator, but VC++ rejects
101
gc_allocator(const gc_allocator&) throw() {}
103
template <class GC_Tp1> gc_allocator(const gc_allocator<GC_Tp1>&) throw() {}
104
~gc_allocator() throw() {}
106
pointer address(reference GC_x) const { return &GC_x; }
107
const_pointer address(const_reference GC_x) const { return &GC_x; }
109
// GC_n is permitted to be 0. The C++ standard says nothing about what
110
// the return value is when GC_n == 0.
111
GC_Tp* allocate(size_type GC_n, const void* = 0) {
112
GC_type_traits<GC_Tp> traits;
113
return static_cast<GC_Tp *>
114
(GC_selective_alloc(GC_n * sizeof(GC_Tp),
115
traits.GC_is_ptr_free));
118
// __p is not permitted to be a null pointer.
119
void deallocate(pointer __p, size_type GC_n)
122
size_type max_size() const throw()
123
{ return size_t(-1) / sizeof(GC_Tp); }
125
void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
126
void destroy(pointer __p) { __p->~GC_Tp(); }
130
class gc_allocator<void> {
131
typedef size_t size_type;
132
typedef ptrdiff_t difference_type;
133
typedef void* pointer;
134
typedef const void* const_pointer;
135
typedef void value_type;
137
template <class GC_Tp1> struct rebind {
138
typedef gc_allocator<GC_Tp1> other;
143
template <class GC_T1, class GC_T2>
144
inline bool operator==(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
149
template <class GC_T1, class GC_T2>
150
inline bool operator!=(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
156
* And the public traceable_allocator class.
159
// Note that we currently don't specialize the pointer-free case, since a
160
// pointer-free traceable container doesn't make that much sense,
161
// though it could become an issue due to abstraction boundaries.
162
template <class GC_Tp>
163
class traceable_allocator {
165
typedef size_t size_type;
166
typedef ptrdiff_t difference_type;
167
typedef GC_Tp* pointer;
168
typedef const GC_Tp* const_pointer;
169
typedef GC_Tp& reference;
170
typedef const GC_Tp& const_reference;
171
typedef GC_Tp value_type;
173
template <class GC_Tp1> struct rebind {
174
typedef traceable_allocator<GC_Tp1> other;
177
traceable_allocator() throw() {}
179
traceable_allocator(const traceable_allocator&) throw() {}
181
template <class GC_Tp1> traceable_allocator
182
(const traceable_allocator<GC_Tp1>&) throw() {}
183
~traceable_allocator() throw() {}
185
pointer address(reference GC_x) const { return &GC_x; }
186
const_pointer address(const_reference GC_x) const { return &GC_x; }
188
// GC_n is permitted to be 0. The C++ standard says nothing about what
189
// the return value is when GC_n == 0.
190
GC_Tp* allocate(size_type GC_n, const void* = 0) {
191
return static_cast<GC_Tp*>(GC_MALLOC_UNCOLLECTABLE(GC_n * sizeof(GC_Tp)));
194
// __p is not permitted to be a null pointer.
195
void deallocate(pointer __p, size_type GC_n)
198
size_type max_size() const throw()
199
{ return size_t(-1) / sizeof(GC_Tp); }
201
void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
202
void destroy(pointer __p) { __p->~GC_Tp(); }
206
class traceable_allocator<void> {
207
typedef size_t size_type;
208
typedef ptrdiff_t difference_type;
209
typedef void* pointer;
210
typedef const void* const_pointer;
211
typedef void value_type;
213
template <class GC_Tp1> struct rebind {
214
typedef traceable_allocator<GC_Tp1> other;
219
template <class GC_T1, class GC_T2>
220
inline bool operator==(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&)
225
template <class GC_T1, class GC_T2>
226
inline bool operator!=(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&)