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