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