~ubuntu-branches/ubuntu/natty/libgc/natty-updates

« back to all changes in this revision

Viewing changes to include/gc_allocator.h

  • Committer: Bazaar Package Importer
  • Author(s): Ryan Murray
  • Date: 2002-03-25 20:27:15 UTC
  • Revision ID: james.westby@ubuntu.com-20020325202715-terff7kao1wrwok5
Tags: upstream-6.0+6.1alpha4
ImportĀ upstreamĀ versionĀ 6.0+6.1alpha4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1996-1997
 
3
 * Silicon Graphics Computer Systems, Inc.
 
4
 *
 
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.
 
12
 *
 
13
 * Copyright (c) 2002
 
14
 * Hewlett-Packard Company
 
15
 *
 
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.
 
23
 */
 
24
 
 
25
/*
 
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.
 
33
 *
 
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.
 
36
 */
 
37
 
 
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.
 
42
 */
 
43
 
 
44
struct GC_true_type {};
 
45
struct GC_false_type {};
 
46
 
 
47
template <class GC_tp>
 
48
struct GC_type_traits {
 
49
  GC_false_type GC_is_ptr_free;
 
50
};
 
51
 
 
52
# define GC_DECLARE_PTRFREE(T) \
 
53
template<> struct GC_type_traits<T> { GC_true_type GC_is_ptr_free; }
 
54
 
 
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.   */
 
66
 
 
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) {
 
71
    return GC_MALLOC(n);
 
72
}
 
73
 
 
74
template <>
 
75
inline void * GC_selective_alloc<GC_true_type>(size_t n, GC_true_type) {
 
76
    return GC_MALLOC_ATOMIC(n);
 
77
}
 
78
 
 
79
/* Now the public gc_allocator<T> class:
 
80
 */
 
81
template <class GC_Tp>
 
82
class gc_allocator {
 
83
public:
 
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;
 
91
 
 
92
  template <class GC_Tp1> struct rebind {
 
93
    typedef gc_allocator<GC_Tp1> other;
 
94
  };
 
95
 
 
96
  gc_allocator()  {}
 
97
# ifndef _MSC_VER
 
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
 
100
    // it.      -HB
 
101
    gc_allocator(const gc_allocator&) throw() {}
 
102
# endif
 
103
  template <class GC_Tp1> gc_allocator(const gc_allocator<GC_Tp1>&) throw() {}
 
104
  ~gc_allocator() throw() {}
 
105
 
 
106
  pointer address(reference GC_x) const { return &GC_x; }
 
107
  const_pointer address(const_reference GC_x) const { return &GC_x; }
 
108
 
 
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));
 
116
  }
 
117
 
 
118
  // __p is not permitted to be a null pointer.
 
119
  void deallocate(pointer __p, size_type GC_n)
 
120
    { GC_FREE(__p); }
 
121
 
 
122
  size_type max_size() const throw()
 
123
    { return size_t(-1) / sizeof(GC_Tp); }
 
124
 
 
125
  void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
 
126
  void destroy(pointer __p) { __p->~GC_Tp(); }
 
127
};
 
128
 
 
129
template<>
 
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;
 
136
 
 
137
  template <class GC_Tp1> struct rebind {
 
138
    typedef gc_allocator<GC_Tp1> other;
 
139
  };
 
140
};
 
141
 
 
142
 
 
143
template <class GC_T1, class GC_T2>
 
144
inline bool operator==(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
 
145
{
 
146
  return true;
 
147
}
 
148
 
 
149
template <class GC_T1, class GC_T2>
 
150
inline bool operator!=(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
 
151
{
 
152
  return false;
 
153
}
 
154
 
 
155
/*
 
156
 * And the public traceable_allocator class.
 
157
 */
 
158
 
 
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 {
 
164
public:
 
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;
 
172
 
 
173
  template <class GC_Tp1> struct rebind {
 
174
    typedef traceable_allocator<GC_Tp1> other;
 
175
  };
 
176
 
 
177
  traceable_allocator() throw() {}
 
178
# ifndef _MSC_VER
 
179
    traceable_allocator(const traceable_allocator&) throw() {}
 
180
# endif
 
181
  template <class GC_Tp1> traceable_allocator
 
182
          (const traceable_allocator<GC_Tp1>&) throw() {}
 
183
  ~traceable_allocator() throw() {}
 
184
 
 
185
  pointer address(reference GC_x) const { return &GC_x; }
 
186
  const_pointer address(const_reference GC_x) const { return &GC_x; }
 
187
 
 
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)));
 
192
  }
 
193
 
 
194
  // __p is not permitted to be a null pointer.
 
195
  void deallocate(pointer __p, size_type GC_n)
 
196
    { GC_FREE(__p); }
 
197
 
 
198
  size_type max_size() const throw()
 
199
    { return size_t(-1) / sizeof(GC_Tp); }
 
200
 
 
201
  void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
 
202
  void destroy(pointer __p) { __p->~GC_Tp(); }
 
203
};
 
204
 
 
205
template<>
 
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;
 
212
 
 
213
  template <class GC_Tp1> struct rebind {
 
214
    typedef traceable_allocator<GC_Tp1> other;
 
215
  };
 
216
};
 
217
 
 
218
 
 
219
template <class GC_T1, class GC_T2>
 
220
inline bool operator==(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&)
 
221
{
 
222
  return true;
 
223
}
 
224
 
 
225
template <class GC_T1, class GC_T2>
 
226
inline bool operator!=(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&)
 
227
{
 
228
  return false;
 
229
}
 
230