Annotation of parser3/src/lib/gc/include/gc_allocator.h, revision 1.1
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 "gc.h"
! 43: #include <new> // for placement new
! 44:
! 45: #if defined(__GNUC__)
! 46: # define GC_ATTR_UNUSED __attribute__((unused))
! 47: #else
! 48: # define GC_ATTR_UNUSED
! 49: #endif
! 50:
! 51: /* First some helpers to allow us to dispatch on whether or not a type
! 52: * is known to be pointerfree.
! 53: * These are private, except that the client may invoke the
! 54: * GC_DECLARE_PTRFREE macro.
! 55: */
! 56:
! 57: struct GC_true_type {};
! 58: struct GC_false_type {};
! 59:
! 60: template <class GC_tp>
! 61: struct GC_type_traits {
! 62: GC_false_type GC_is_ptr_free;
! 63: };
! 64:
! 65: # define GC_DECLARE_PTRFREE(T) \
! 66: template<> struct GC_type_traits<T> { GC_true_type GC_is_ptr_free; }
! 67:
! 68: GC_DECLARE_PTRFREE(char);
! 69: GC_DECLARE_PTRFREE(signed char);
! 70: GC_DECLARE_PTRFREE(unsigned char);
! 71: GC_DECLARE_PTRFREE(signed short);
! 72: GC_DECLARE_PTRFREE(unsigned short);
! 73: GC_DECLARE_PTRFREE(signed int);
! 74: GC_DECLARE_PTRFREE(unsigned int);
! 75: GC_DECLARE_PTRFREE(signed long);
! 76: GC_DECLARE_PTRFREE(unsigned long);
! 77: GC_DECLARE_PTRFREE(float);
! 78: GC_DECLARE_PTRFREE(double);
! 79: GC_DECLARE_PTRFREE(long double);
! 80: /* The client may want to add others. */
! 81:
! 82: // In the following GC_Tp is GC_true_type iff we are allocating a
! 83: // pointerfree object.
! 84: template <class GC_Tp>
! 85: inline void * GC_selective_alloc(size_t n, GC_Tp) {
! 86: return GC_MALLOC(n);
! 87: }
! 88:
! 89: template <>
! 90: inline void * GC_selective_alloc<GC_true_type>(size_t n, GC_true_type) {
! 91: return GC_MALLOC_ATOMIC(n);
! 92: }
! 93:
! 94: /* Now the public gc_allocator<T> class:
! 95: */
! 96: template <class GC_Tp>
! 97: class gc_allocator {
! 98: public:
! 99: typedef size_t size_type;
! 100: typedef ptrdiff_t difference_type;
! 101: typedef GC_Tp* pointer;
! 102: typedef const GC_Tp* const_pointer;
! 103: typedef GC_Tp& reference;
! 104: typedef const GC_Tp& const_reference;
! 105: typedef GC_Tp value_type;
! 106:
! 107: template <class GC_Tp1> struct rebind {
! 108: typedef gc_allocator<GC_Tp1> other;
! 109: };
! 110:
! 111: gc_allocator() {}
! 112: gc_allocator(const gc_allocator&) throw() {}
! 113: # if !(GC_NO_MEMBER_TEMPLATES || 0 < _MSC_VER && _MSC_VER <= 1200)
! 114: // MSVC++ 6.0 do not support member templates
! 115: template <class GC_Tp1> gc_allocator(const gc_allocator<GC_Tp1>&) throw() {}
! 116: # endif
! 117: ~gc_allocator() throw() {}
! 118:
! 119: pointer address(reference GC_x) const { return &GC_x; }
! 120: const_pointer address(const_reference GC_x) const { return &GC_x; }
! 121:
! 122: // GC_n is permitted to be 0. The C++ standard says nothing about what
! 123: // the return value is when GC_n == 0.
! 124: GC_Tp* allocate(size_type GC_n, const void* = 0) {
! 125: GC_type_traits<GC_Tp> traits;
! 126: return static_cast<GC_Tp *>
! 127: (GC_selective_alloc(GC_n * sizeof(GC_Tp),
! 128: traits.GC_is_ptr_free));
! 129: }
! 130:
! 131: // __p is not permitted to be a null pointer.
! 132: void deallocate(pointer __p, size_type GC_ATTR_UNUSED GC_n)
! 133: { GC_FREE(__p); }
! 134:
! 135: size_type max_size() const throw()
! 136: { return size_t(-1) / sizeof(GC_Tp); }
! 137:
! 138: void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
! 139: void destroy(pointer __p) { __p->~GC_Tp(); }
! 140: };
! 141:
! 142: template<>
! 143: class gc_allocator<void> {
! 144: typedef size_t size_type;
! 145: typedef ptrdiff_t difference_type;
! 146: typedef void* pointer;
! 147: typedef const void* const_pointer;
! 148: typedef void value_type;
! 149:
! 150: template <class GC_Tp1> struct rebind {
! 151: typedef gc_allocator<GC_Tp1> other;
! 152: };
! 153: };
! 154:
! 155:
! 156: template <class GC_T1, class GC_T2>
! 157: inline bool operator==(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
! 158: {
! 159: return true;
! 160: }
! 161:
! 162: template <class GC_T1, class GC_T2>
! 163: inline bool operator!=(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
! 164: {
! 165: return false;
! 166: }
! 167:
! 168: /*
! 169: * And the public traceable_allocator class.
! 170: */
! 171:
! 172: // Note that we currently don't specialize the pointer-free case, since a
! 173: // pointer-free traceable container doesn't make that much sense,
! 174: // though it could become an issue due to abstraction boundaries.
! 175: template <class GC_Tp>
! 176: class traceable_allocator {
! 177: public:
! 178: typedef size_t size_type;
! 179: typedef ptrdiff_t difference_type;
! 180: typedef GC_Tp* pointer;
! 181: typedef const GC_Tp* const_pointer;
! 182: typedef GC_Tp& reference;
! 183: typedef const GC_Tp& const_reference;
! 184: typedef GC_Tp value_type;
! 185:
! 186: template <class GC_Tp1> struct rebind {
! 187: typedef traceable_allocator<GC_Tp1> other;
! 188: };
! 189:
! 190: traceable_allocator() throw() {}
! 191: traceable_allocator(const traceable_allocator&) throw() {}
! 192: # if !(GC_NO_MEMBER_TEMPLATES || 0 < _MSC_VER && _MSC_VER <= 1200)
! 193: // MSVC++ 6.0 do not support member templates
! 194: template <class GC_Tp1> traceable_allocator
! 195: (const traceable_allocator<GC_Tp1>&) throw() {}
! 196: # endif
! 197: ~traceable_allocator() throw() {}
! 198:
! 199: pointer address(reference GC_x) const { return &GC_x; }
! 200: const_pointer address(const_reference GC_x) const { return &GC_x; }
! 201:
! 202: // GC_n is permitted to be 0. The C++ standard says nothing about what
! 203: // the return value is when GC_n == 0.
! 204: GC_Tp* allocate(size_type GC_n, const void* = 0) {
! 205: return static_cast<GC_Tp*>(GC_MALLOC_UNCOLLECTABLE(GC_n * sizeof(GC_Tp)));
! 206: }
! 207:
! 208: // __p is not permitted to be a null pointer.
! 209: void deallocate(pointer __p, size_type GC_ATTR_UNUSED GC_n)
! 210: { GC_FREE(__p); }
! 211:
! 212: size_type max_size() const throw()
! 213: { return size_t(-1) / sizeof(GC_Tp); }
! 214:
! 215: void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
! 216: void destroy(pointer __p) { __p->~GC_Tp(); }
! 217: };
! 218:
! 219: template<>
! 220: class traceable_allocator<void> {
! 221: typedef size_t size_type;
! 222: typedef ptrdiff_t difference_type;
! 223: typedef void* pointer;
! 224: typedef const void* const_pointer;
! 225: typedef void value_type;
! 226:
! 227: template <class GC_Tp1> struct rebind {
! 228: typedef traceable_allocator<GC_Tp1> other;
! 229: };
! 230: };
! 231:
! 232:
! 233: template <class GC_T1, class GC_T2>
! 234: inline bool operator==(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&)
! 235: {
! 236: return true;
! 237: }
! 238:
! 239: template <class GC_T1, class GC_T2>
! 240: inline bool operator!=(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&)
! 241: {
! 242: return false;
! 243: }
! 244:
! 245: #endif /* GC_ALLOCATOR_H */
E-mail: