//===- GCFactory.h --------------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_SUPPORT_GCFACTORY_H_ #define MCLD_SUPPORT_GCFACTORY_H_ #include "mcld/ADT/TypeTraits.h" #include "mcld/Support/Allocators.h" #include #include #include namespace mcld { /** \class DataIteratorBase * \brief DataIteratorBase provides the basic functions of DataIterator * @see DataIterator */ template struct DataIteratorBase { public: ChunkType* m_pChunk; unsigned int m_Pos; public: DataIteratorBase(ChunkType* X, unsigned int pPos) : m_pChunk(X), m_Pos(pPos) {} inline void advance() { ++m_Pos; if ((m_Pos == m_pChunk->bound) && (0 == m_pChunk->next)) return; if (m_Pos == m_pChunk->bound) { m_pChunk = m_pChunk->next; m_Pos = 0; } } bool operator==(const DataIteratorBase& y) const { return ((this->m_pChunk == y.m_pChunk) && (this->m_Pos == y.m_Pos)); } bool operator!=(const DataIteratorBase& y) const { return ((this->m_pChunk != y.m_pChunk) || (this->m_Pos != y.m_Pos)); } }; /** \class DataIterator * \brief DataIterator provides STL compatible iterator for allocators */ template class DataIterator : public DataIteratorBase { public: typedef typename ChunkType::value_type value_type; typedef Traits traits; typedef typename traits::pointer pointer; typedef typename traits::reference reference; typedef DataIterator Self; typedef DataIteratorBase Base; typedef typename traits::nonconst_traits nonconst_traits; typedef DataIterator iterator; typedef typename traits::const_traits const_traits; typedef DataIterator const_iterator; typedef std::forward_iterator_tag iterator_category; typedef size_t size_type; typedef ptrdiff_t difference_type; public: DataIterator() : Base(NULL, 0) {} DataIterator(ChunkType* pChunk, unsigned int pPos) : Base(pChunk, pPos) {} DataIterator(const DataIterator& pCopy) : Base(pCopy.m_pChunk, pCopy.m_Pos) {} ~DataIterator() {} // ----- operators ----- // reference operator*() { assert(this->m_pChunk != NULL && "data iterator goes to a invalid position"); return this->m_pChunk->data[Base::m_Pos]; } Self& operator++() { this->Base::advance(); return *this; } Self operator++(int) { Self tmp = *this; this->Base::advance(); return tmp; } }; template class GCFactoryBase : public Alloc { public: typedef DataIterator > iterator; typedef DataIterator > const_iterator; typedef typename Alloc::value_type value_type; typedef typename Alloc::pointer pointer; typedef typename Alloc::reference reference; typedef typename Alloc::size_type size_type; protected: GCFactoryBase() : Alloc(), m_NumAllocData(0) {} explicit GCFactoryBase(size_t pNum) : Alloc(pNum), m_NumAllocData(0) {} public: virtual ~GCFactoryBase() { Alloc::clear(); } // ----- modifiers ----- // value_type* allocate(size_t N) { value_type* result = Alloc::allocate(N); if (result != NULL) m_NumAllocData += N; return result; } value_type* allocate() { ++m_NumAllocData; return Alloc::allocate(); } void deallocate(pointer& pPtr, size_type N) { Alloc::deallocate(pPtr, N); if (pPtr == NULL) m_NumAllocData -= N; } void deallocate(pointer& pPtr) { Alloc::deallocate(pPtr); if (pPtr == NULL) --m_NumAllocData; } void reset() { Alloc::reset(); m_NumAllocData = 0; } // ----- iterators ----- // iterator begin() { return iterator(Alloc::m_pRoot, 0); } const_iterator begin() const { return const_iterator(Alloc::m_pRoot, 0); } iterator end() { return (Alloc::m_pCurrent) == 0 ? begin() : iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound); } const_iterator end() const { return (Alloc::m_pCurrent) == 0 ? begin() : const_iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound); } // ----- observers ----- // bool empty() const { return Alloc::empty(); } unsigned int capacity() const { return Alloc::max_size(); } unsigned int size() const { return m_NumAllocData; } protected: unsigned int m_NumAllocData; }; /** \class GCFactory * \brief GCFactory provides a factory that guaratees to remove all allocated * data. */ template class GCFactory : public GCFactoryBase > { public: GCFactory() : GCFactoryBase >() {} }; template class GCFactory : public GCFactoryBase > { public: explicit GCFactory(size_t pNum) : GCFactoryBase >(pNum) {} }; } // namespace mcld #endif // MCLD_SUPPORT_GCFACTORY_H_