//===- GCFactory.h --------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_GC_FACTORY_H
#define MCLD_GC_FACTORY_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#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

