Annotation of parser3/src/lib/gc/include/gc_allocator.h, revision 1.3
1.1 misha 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: #ifndef GC_ALLOCATOR_H
39:
40: #define GC_ALLOCATOR_H
41:
42: #include <new> // for placement new
43:
44: #if defined(__GNUC__)
45: # define GC_ATTR_UNUSED __attribute__((unused))
46: #else
47: # define GC_ATTR_UNUSED
48: #endif
49:
50: /* First some helpers to allow us to dispatch on whether or not a type
51: * is known to be pointerfree.
52: * These are private, except that the client may invoke the
53: * GC_DECLARE_PTRFREE macro.
54: */
55:
56: struct GC_true_type {};
57: struct GC_false_type {};
58:
59: template <class GC_tp>
60: struct GC_type_traits {
61: GC_false_type GC_is_ptr_free;
62: };
63:
64: # define GC_DECLARE_PTRFREE(T) \
65: template<> struct GC_type_traits<T> { GC_true_type GC_is_ptr_free; }
66:
67: GC_DECLARE_PTRFREE(char);
68: GC_DECLARE_PTRFREE(signed char);
69: GC_DECLARE_PTRFREE(unsigned char);
70: GC_DECLARE_PTRFREE(signed short);
71: GC_DECLARE_PTRFREE(unsigned short);
72: GC_DECLARE_PTRFREE(signed int);
73: GC_DECLARE_PTRFREE(unsigned int);
74: GC_DECLARE_PTRFREE(signed long);
75: GC_DECLARE_PTRFREE(unsigned long);
76: GC_DECLARE_PTRFREE(float);
77: GC_DECLARE_PTRFREE(double);
78: GC_DECLARE_PTRFREE(long double);
79: /* The client may want to add others. */
80:
81: // In the following GC_Tp is GC_true_type iff we are allocating a
82: // pointerfree object.
83: template <class GC_Tp>
84: inline void * GC_selective_alloc(size_t n, GC_Tp) {
85: return GC_MALLOC(n);
86: }
87:
88: template <>
89: inline void * GC_selective_alloc<GC_true_type>(size_t n, GC_true_type) {
90: return GC_MALLOC_ATOMIC(n);
91: }
92:
93: /* Now the public gc_allocator<T> class:
94: */
95: template <class GC_Tp>
96: class gc_allocator {
97: public:
98: typedef size_t size_type;
99: typedef ptrdiff_t difference_type;
100: typedef GC_Tp* pointer;
101: typedef const GC_Tp* const_pointer;
102: typedef GC_Tp& reference;
103: typedef const GC_Tp& const_reference;
104: typedef GC_Tp value_type;
105:
106: template <class GC_Tp1> struct rebind {
107: typedef gc_allocator<GC_Tp1> other;
108: };
109:
110: gc_allocator() {}
111: gc_allocator(const gc_allocator&) throw() {}
112: # if !(GC_NO_MEMBER_TEMPLATES || 0 < _MSC_VER && _MSC_VER <= 1200)
113: // MSVC++ 6.0 do not support member templates
114: template <class GC_Tp1> gc_allocator(const gc_allocator<GC_Tp1>&) throw() {}
115: # endif
116: ~gc_allocator() throw() {}
117:
118: pointer address(reference GC_x) const { return &GC_x; }
119: const_pointer address(const_reference GC_x) const { return &GC_x; }
120:
121: // GC_n is permitted to be 0. The C++ standard says nothing about what
122: // the return value is when GC_n == 0.
123: GC_Tp* allocate(size_type GC_n, const void* = 0) {
124: GC_type_traits<GC_Tp> traits;
1.3 ! moko 125: return static_cast<GC_Tp *> (GC_selective_alloc(GC_n * sizeof(GC_Tp), traits.GC_is_ptr_free));
1.1 misha 126: }
127:
128: // __p is not permitted to be a null pointer.
1.2 moko 129: void deallocate(pointer __p, size_type GC_ATTR_UNUSED)
1.1 misha 130: { GC_FREE(__p); }
131:
132: size_type max_size() const throw()
133: { return size_t(-1) / sizeof(GC_Tp); }
134:
135: void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
136: void destroy(pointer __p) { __p->~GC_Tp(); }
137: };
138:
139: template<>
140: class gc_allocator<void> {
141: typedef size_t size_type;
142: typedef ptrdiff_t difference_type;
143: typedef void* pointer;
144: typedef const void* const_pointer;
145: typedef void value_type;
146:
147: template <class GC_Tp1> struct rebind {
148: typedef gc_allocator<GC_Tp1> other;
149: };
150: };
151:
152:
153: template <class GC_T1, class GC_T2>
154: inline bool operator==(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
155: {
156: return true;
157: }
158:
159: template <class GC_T1, class GC_T2>
160: inline bool operator!=(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
161: {
162: return false;
163: }
164:
165: #endif /* GC_ALLOCATOR_H */
E-mail: