/** * memory.h: Memory templates. * * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team * Rights to this code are documented in doc/pod/gplicense.pod. * * $Id: memory.h,v 1.6 2007/09/22 14:27:26 pippijn dead $ */ #ifndef ERMYTH_MEMORY_H #define ERMYTH_MEMORY_H #include #include namespace impl { inline void * smalloc (size_t n) throw (std::bad_alloc) { void *ptr = malloc (n); if (!ptr) throw std::bad_alloc (); return ptr; } inline void * smalloc (size_t n, void const * const src) throw (std::bad_alloc) { void *ptr = smalloc (n); if (src) memcpy (ptr, src, n); else memset (ptr, 0, n); return ptr; } // safe and slow version of above: never tries to copy more than len from src inline void * smalloc (size_t n, void *src, size_t len) throw (std::bad_alloc) { size_t max = n >= len ? n : len; void *ptr = smalloc (max); if (src) { memcpy (ptr, src, len); memset (((char *)(ptr)) + len, 0, max - len); // XXX: hack to allow pointer arithmetic } else memset (ptr, 0, max); return ptr; } } template inline T * salloc (size_t n = 1) throw (std::bad_alloc) { return (T *) impl::smalloc (n * sizeof (T)); } template inline T * salloc (size_t n, T const * const src) throw (std::bad_alloc) { return (T *) impl::smalloc (n * sizeof (T), src); } // template counterpart of the safe copying allocator template inline T * salloc (size_t n, T *src, size_t len) throw (std::bad_alloc) { return (T *) impl::smalloc (n * sizeof (T), src, len); } template inline T * salloc (size_t n, char c) throw (std::bad_alloc) { T *ptr = (T *) impl::smalloc (n * sizeof (T)); return memset (ptr, c, n * sizeof (T)); } template inline void sfree (T *ptr) throw () { free (ptr); } template inline void sfree (T *ptr, size_t n) throw () { free (ptr); } // makes dynamically allocated objects zero-initialised struct zero_initialised { void *operator new (size_t s) { void *p = impl::smalloc (s); memset (p, 0, s); return p; } void *operator new[] (size_t s) { void *p = impl::smalloc (s); memset (p, 0, s); return p; } void operator delete (void *p, size_t s) { free (p); } void operator delete[] (void *p, size_t s) { free (p); } }; E char *sstrdup (char const * const s); E char *sstrndup (char const * const s, size_t len); template inline char * sstrndup (char const (&s)[N]) { return sstrndup (s, N); } struct garbage_collector { void insert (void *p) { mortals.push_back (p); } void collect () { while (!mortals.empty ()) { sfree (mortals.back ()); mortals.pop_back (); } } private: std::vector mortals; }; E garbage_collector gc; #endif