//===- 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 <assert.h>
#include <cstddef>
#include <iterator>

namespace mcld
{

/** \class DataIteratorBase
 *  \brief DataIteratorBase provides the basic functions of DataIterator
 *  @see DataIterator
 */
template<typename ChunkType>
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<typename ChunkType, class Traits>
class DataIterator : public DataIteratorBase<ChunkType>
{
public:
  typedef typename ChunkType::value_type  value_type;
  typedef Traits                          traits;
  typedef typename traits::pointer        pointer;
  typedef typename traits::reference      reference;
  typedef DataIterator<ChunkType, Traits> Self;
  typedef DataIteratorBase<ChunkType>     Base;

  typedef typename traits::nonconst_traits         nonconst_traits;
  typedef DataIterator<ChunkType, nonconst_traits> iterator;
  typedef typename traits::const_traits            const_traits;
  typedef DataIterator<ChunkType, const_traits>    const_iterator;
  typedef std::forward_iterator_tag                iterator_category;
  typedef size_t                                   size_type;
  typedef ptrdiff_t                                difference_type;

public:
  DataIterator()
  : Base(0, 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*() {
    if (0 == this->m_pChunk)
      assert(0 && "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<typename Alloc>
class GCFactoryBase : public Alloc
{
public:
  typedef DataIterator<typename Alloc::chunk_type,
                       NonConstTraits<
                         typename Alloc::value_type> > iterator;
  typedef DataIterator<typename Alloc::chunk_type,
                       ConstTraits<
                         typename Alloc::value_type> > 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)
  { }

  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 (0 != result)
      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 (0 == pPtr)
      m_NumAllocData -= N;
  }

  void deallocate(pointer &pPtr) {
    Alloc::deallocate(pPtr);
    if (0 == pPtr)
      --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 (0 == Alloc::m_pCurrent)?
             begin():
             iterator(Alloc::m_pCurrent, Alloc::m_pCurrent->bound);
  }

  const_iterator end() const {
    return (0 == Alloc::m_pCurrent)?
             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<typename DataType, size_t ChunkSize>
class GCFactory : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> >
{
public:
  GCFactory()
  : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >()
  { }
};

template<typename DataType>
class GCFactory<DataType, 0> : public GCFactoryBase<LinearAllocator<DataType, 0> >
{
public:
  GCFactory(size_t pNum)
  : GCFactoryBase<LinearAllocator<DataType, 0> >(pNum)
  { }
};

} // namespace of mcld

#endif

