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