Wiselib
|
00001 00002 #ifndef __WISELIB_UTIL_ALLOCATORS_NEW_DELETE_ALLOCATOR_H 00003 #define __WISELIB_UTIL_ALLOCATORS_NEW_DELETE_ALLOCATOR_H 00004 00005 #define KEEP_STATS 1 00006 00007 namespace wiselib { 00008 00015 template< 00016 typename OsModel_P 00017 > 00018 class NewDeleteAllocator { 00019 public: 00020 typedef OsModel_P OsModel; 00021 typedef NewDeleteAllocator<OsModel_P> self_type; 00022 typedef self_type* self_pointer_t; 00023 00024 enum { SUCCESS = OsModel::SUCCESS, ERR_UNSPEC = OsModel::ERR_UNSPEC }; 00025 00026 template<typename T> 00027 struct Ref { 00028 // The following struct is mostly equivalent to the typedef but 00029 // allows auto-initialization to 0 00030 struct pointer_t { 00031 pointer_t() : p_(0) { } 00032 pointer_t(T* p) : p_(p) { } 00033 pointer_t(const pointer_t& other) : p_(other.p_) { } 00034 T& operator*() const { return *p_; } 00035 T* operator->() const { return p_; } 00036 T& operator[](size_t idx) { return p_[idx]; } 00037 const T& operator[](size_t idx) const { return p_[idx]; } 00038 bool operator==(const pointer_t& other) const { return p_ == other.p_; } 00039 bool operator!=(const pointer_t& other) const { return p_ != other.p_; } 00040 operator bool() const { return p_ != 0; } 00041 pointer_t& operator++() { ++p_; return *this; } 00042 pointer_t& operator--() { --p_; return *this; } 00043 T* raw() { return p_; } 00044 T* p_; 00045 }; 00046 }; 00047 00048 NewDeleteAllocator() 00049 #if KEEP_STATS 00050 : allocated_(0), news_(0), deletes_(0) 00051 #endif 00052 { 00053 } 00054 00055 template<typename T> 00056 typename Ref<T>::pointer_t allocate() { 00057 #if KEEP_STATS 00058 allocated_ += sizeof(T); 00059 news_++; 00060 #endif 00061 typename Ref<T>::pointer_t r = new T; 00062 return r; 00063 } 00064 00065 template<typename T> 00066 typename Ref<T>::pointer_t allocate_array(typename OsModel::size_t n) { 00067 #if KEEP_STATS 00068 allocated_ += sizeof(T[n]); 00069 news_++; 00070 #endif 00071 return new T[n]; 00072 } 00073 00074 template<typename T> 00075 int free(typename Ref<T>::pointer_t p) { 00076 #if KEEP_STATS 00077 allocated_ -= sizeof(T); 00078 deletes_++; 00079 #endif 00080 delete p.p_; 00081 return SUCCESS; 00082 } 00083 00084 template<typename T> 00085 int free_array(typename Ref<T>::pointer_t p) { 00086 #if KEEP_STATS 00087 allocated_ -= sizeof(*p.p_); 00088 deletes_++; 00089 #endif 00090 delete[] p.p_; 00091 return SUCCESS; 00092 } 00093 00094 template<typename Debug_P> 00095 void print_stats(Debug_P* d) { 00096 #if KEEP_STATS 00097 d->debug("\nnew/delete allocator statistics\n"); 00098 d->debug("-------------------------------\n"); 00099 // theres currently no way to know the size of an array by its 00100 // pointer so a correct allocated_ counting would be more involved 00101 //d->debug("allocated bytes: %14lu\n", allocated_); 00102 d->debug("allocations : %14lu\n", news_); 00103 d->debug("frees : %14lu\n", deletes_); 00104 d->debug("\n"); 00105 #endif 00106 } 00107 00108 private: 00109 #if KEEP_STATS 00110 unsigned long allocated_, news_, deletes_; 00111 #endif 00112 }; 00113 00114 00115 } // namespace wiselib 00116 00117 #endif // NEW_DELETE_ALLOCATOR_H 00118 00119