GCFactory.h revision 5460a1f25d9ddecb5c70667267d66d51af177a99
1//===- GCFactory.h --------------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#ifndef MCLD_GC_FACTORY_H 10#define MCLD_GC_FACTORY_H 11#ifdef ENABLE_UNITTEST 12#include <gtest.h> 13#endif 14#include "mcld/ADT/TypeTraits.h" 15#include "mcld/Support/Allocators.h" 16 17#include <assert.h> 18#include <iterator> 19 20namespace mcld 21{ 22 23/** \class DataIteratorBase 24 * \brief DataIteratorBase provides the basic functions of DataIterator 25 * @see DataIterator 26 */ 27template<typename ChunkType> 28struct DataIteratorBase 29{ 30public: 31 ChunkType* m_pChunk; 32 unsigned int m_Pos; 33 34public: 35 DataIteratorBase(ChunkType* X, unsigned int pPos) 36 : m_pChunk(X), m_Pos(pPos) 37 { } 38 39 inline void advance() { 40 ++m_Pos; 41 if ((m_Pos == m_pChunk->bound) && (0 == m_pChunk->next)) 42 return; 43 if (m_Pos == m_pChunk->bound) { 44 m_pChunk = m_pChunk->next; 45 m_Pos = 0; 46 } 47 } 48 49 bool operator==(const DataIteratorBase& y) const 50 { return ((this->m_pChunk == y.m_pChunk) && (this->m_Pos == y.m_Pos)); } 51 52 bool operator!=(const DataIteratorBase& y) const 53 { return ((this->m_pChunk != y.m_pChunk) || (this->m_Pos != y.m_Pos)); } 54}; 55 56/** \class DataIterator 57 * \brief DataIterator provides STL compatible iterator for allocators 58 */ 59template<typename ChunkType, class Traits> 60class DataIterator : public DataIteratorBase<ChunkType> 61{ 62public: 63 typedef typename ChunkType::value_type value_type; 64 typedef Traits traits; 65 typedef typename traits::pointer pointer; 66 typedef typename traits::reference reference; 67 typedef DataIterator<ChunkType, Traits> Self; 68 typedef DataIteratorBase<ChunkType> Base; 69 70 typedef typename traits::nonconst_traits nonconst_traits; 71 typedef DataIterator<ChunkType, nonconst_traits> iterator; 72 typedef typename traits::const_traits const_traits; 73 typedef DataIterator<ChunkType, const_traits> const_iterator; 74 typedef std::forward_iterator_tag iterator_category; 75 typedef size_t size_type; 76 typedef ptrdiff_t difference_type; 77 78public: 79 DataIterator() 80 : Base(0, 0) 81 { } 82 83 DataIterator(ChunkType* pChunk, unsigned int pPos) 84 : Base(pChunk, pPos) 85 { } 86 87 DataIterator(const DataIterator& pCopy) 88 : Base(pCopy.m_pChunk, pCopy.m_Pos) 89 { } 90 91 ~DataIterator() 92 { } 93 94 // ----- operators ----- // 95 reference operator*() { 96 if (0 == this->m_pChunk) 97 assert(0 && "data iterator goes to a invalid position"); 98 return this->m_pChunk->data[Base::m_Pos]; 99 } 100 101 Self& operator++() { 102 this->Base::advance(); 103 return *this; 104 } 105 106 Self operator++(int) { 107 Self tmp = *this; 108 this->Base::advance(); 109 return tmp; 110 } 111}; 112 113template<typename Alloc> 114class GCFactoryBase : public Alloc 115{ 116public: 117 typedef DataIterator<typename Alloc::chunk_type, 118 NonConstTraits< 119 typename Alloc::value_type> > iterator; 120 typedef DataIterator<typename Alloc::chunk_type, 121 ConstTraits< 122 typename Alloc::value_type> > const_iterator; 123 124 typedef typename Alloc::value_type value_type; 125 typedef typename Alloc::pointer pointer; 126 typedef typename Alloc::reference reference; 127 typedef typename Alloc::size_type size_type; 128 129protected: 130 GCFactoryBase() 131 : Alloc(), m_NumAllocData(0) 132 { } 133 134 GCFactoryBase(size_t pNum) 135 : Alloc(pNum), m_NumAllocData(0) 136 { } 137 138public: 139 virtual ~GCFactoryBase() 140 { Alloc::clear(); } 141 142 // ----- modifiers ----- // 143 value_type* allocate(size_t N) { 144 value_type* result = Alloc::allocate(N); 145 if (0 != result) 146 m_NumAllocData += N; 147 return result; 148 } 149 150 value_type* allocate() { 151 ++m_NumAllocData; 152 return Alloc::allocate(); 153 } 154 155 void deallocate(pointer &pPtr, size_type N) { 156 Alloc::deallocate(pPtr, N); 157 if (0 == pPtr) 158 m_NumAllocData -= N; 159 } 160 161 void deallocate(pointer &pPtr) { 162 Alloc::deallocate(pPtr); 163 if (0 == pPtr) 164 --m_NumAllocData; 165 } 166 167 void reset() { 168 Alloc::reset(); 169 m_NumAllocData = 0; 170 } 171 172 // ----- iterators ----- // 173 iterator begin() 174 { return iterator(Alloc::m_pRoot, 0); } 175 176 const_iterator begin() const 177 { return const_iterator(Alloc::m_pRoot, 0); } 178 179 iterator end() { 180 return (0 == Alloc::m_pCurrent)? 181 begin(): 182 iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound); 183 } 184 185 const_iterator end() const { 186 return (0 == Alloc::m_pCurrent)? 187 begin(): 188 const_iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound); 189 } 190 191 // ----- observers ----- // 192 bool empty() const 193 { return Alloc::empty(); } 194 195 unsigned int capacity() const 196 { return Alloc::max_size(); } 197 198 unsigned int size() const 199 { return m_NumAllocData; } 200 201protected: 202 unsigned int m_NumAllocData; 203}; 204 205/** \class GCFactory 206 * \brief GCFactory provides a factory that guaratees to remove all allocated 207 * data. 208 */ 209template<typename DataType, size_t ChunkSize> 210class GCFactory : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> > 211{ 212public: 213 GCFactory() 214 : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >() 215 { } 216}; 217 218template<typename DataType> 219class GCFactory<DataType, 0> : public GCFactoryBase<LinearAllocator<DataType, 0> > 220{ 221public: 222 GCFactory(size_t pNum) 223 : GCFactoryBase<LinearAllocator<DataType, 0> >(pNum) 224 { } 225}; 226 227} // namespace of mcld 228 229#endif 230 231