15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- GCFactory.h --------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_SUPPORT_GCFACTORY_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_SUPPORT_GCFACTORY_H_
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "mcld/ADT/TypeTraits.h"
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "mcld/Support/Allocators.h"
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <assert.h>
15f767be5432ccac097334be48698e48621d730190Shih-wei Liao#include <cstddef>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <iterator>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class DataIteratorBase
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief DataIteratorBase provides the basic functions of DataIterator
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  @see DataIterator
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
2437b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename ChunkType>
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstruct DataIteratorBase {
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ChunkType* m_pChunk;
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int m_Pos;
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  DataIteratorBase(ChunkType* X, unsigned int pPos)
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      : m_pChunk(X), m_Pos(pPos) {}
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  inline void advance() {
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++m_Pos;
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if ((m_Pos == m_pChunk->bound) && (0 == m_pChunk->next))
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return;
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (m_Pos == m_pChunk->bound) {
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_pChunk = m_pChunk->next;
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_Pos = 0;
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool operator==(const DataIteratorBase& y) const {
4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return ((this->m_pChunk == y.m_pChunk) && (this->m_Pos == y.m_Pos));
4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool operator!=(const DataIteratorBase& y) const {
4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return ((this->m_pChunk != y.m_pChunk) || (this->m_Pos != y.m_Pos));
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class DataIterator
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief DataIterator provides STL compatible iterator for allocators
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
5637b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename ChunkType, class Traits>
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass DataIterator : public DataIteratorBase<ChunkType> {
5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef typename ChunkType::value_type value_type;
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef Traits traits;
6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef typename traits::pointer pointer;
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef typename traits::reference reference;
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef DataIterator<ChunkType, Traits> Self;
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef DataIteratorBase<ChunkType> Base;
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef typename traits::nonconst_traits nonconst_traits;
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef DataIterator<ChunkType, nonconst_traits> iterator;
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef typename traits::const_traits const_traits;
6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef DataIterator<ChunkType, const_traits> const_iterator;
7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef std::forward_iterator_tag iterator_category;
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef size_t size_type;
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef ptrdiff_t difference_type;
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  DataIterator() : Base(NULL, 0) {}
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  DataIterator(ChunkType* pChunk, unsigned int pPos) : Base(pChunk, pPos) {}
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  DataIterator(const DataIterator& pCopy) : Base(pCopy.m_pChunk, pCopy.m_Pos) {}
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ~DataIterator() {}
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  operators  ----- //
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  reference operator*() {
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    assert(this->m_pChunk != NULL &&
8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines           "data iterator goes to a invalid position");
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return this->m_pChunk->data[Base::m_Pos];
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Self& operator++() {
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    this->Base::advance();
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return *this;
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Self operator++(int) {
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Self tmp = *this;
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    this->Base::advance();
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return tmp;
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename Alloc>
10337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass GCFactoryBase : public Alloc {
10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef DataIterator<typename Alloc::chunk_type,
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                       NonConstTraits<typename Alloc::value_type> > iterator;
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef DataIterator<typename Alloc::chunk_type,
10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                       ConstTraits<typename Alloc::value_type> > const_iterator;
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef typename Alloc::value_type value_type;
11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef typename Alloc::pointer pointer;
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef typename Alloc::reference reference;
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef typename Alloc::size_type size_type;
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  GCFactoryBase() : Alloc(), m_NumAllocData(0) {}
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  explicit GCFactoryBase(size_t pNum) : Alloc(pNum), m_NumAllocData(0) {}
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual ~GCFactoryBase() { Alloc::clear(); }
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  modifiers  ----- //
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  value_type* allocate(size_t N) {
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    value_type* result = Alloc::allocate(N);
12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (result != NULL)
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_NumAllocData += N;
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  value_type* allocate() {
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++m_NumAllocData;
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return Alloc::allocate();
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  void deallocate(pointer& pPtr, size_type N) {
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::deallocate(pPtr, N);
13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (pPtr == NULL)
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_NumAllocData -= N;
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  void deallocate(pointer& pPtr) {
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::deallocate(pPtr);
14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (pPtr == NULL)
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      --m_NumAllocData;
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void reset() {
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Alloc::reset();
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_NumAllocData = 0;
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  iterators  ----- //
15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  iterator begin() { return iterator(Alloc::m_pRoot, 0); }
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const_iterator begin() const { return const_iterator(Alloc::m_pRoot, 0); }
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  iterator end() {
15937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return (Alloc::m_pCurrent) == 0
16037b74a387bb3993387029859c2d9d051c41c724eStephen Hines               ? begin()
16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines               : iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound);
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const_iterator end() const {
16537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return (Alloc::m_pCurrent) == 0
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines               ? begin()
16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines               : const_iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound);
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  observers  ----- //
17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool empty() const { return Alloc::empty(); }
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  unsigned int capacity() const { return Alloc::max_size(); }
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  unsigned int size() const { return m_NumAllocData; }
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int m_NumAllocData;
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class GCFactory
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief GCFactory provides a factory that guaratees to remove all allocated
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  data.
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
18537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename DataType, size_t ChunkSize>
18637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass GCFactory : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> > {
18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
18837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  GCFactory() : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >() {}
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
19137b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <typename DataType>
19237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass GCFactory<DataType, 0>
19337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : public GCFactoryBase<LinearAllocator<DataType, 0> > {
19437b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
19537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  explicit GCFactory(size_t pNum)
19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines     : GCFactoryBase<LinearAllocator<DataType, 0> >(pNum) {}
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
19937b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
20137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_SUPPORT_GCFACTORY_H_
202