//===- UniqueGCFactory.h --------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_UNIQUE_GCFACTORY_H
#define MCLD_UNIQUE_GCFACTORY_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include "mcld/Support/GCFactory.h"
#include <map>
#include <utility>
namespace mcld
{
/** \class UniqueGCFactoryBase
* \brief UniqueGCFactories are unique associative factories, meaning that
* no two elements have the same key.
*/
template<typename KeyType, typename DataType, size_t ChunkSize>
class UniqueGCFactoryBase : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> >
{
protected:
typedef GCFactoryBase<LinearAllocator<DataType, ChunkSize> > Alloc;
typedef std::map<KeyType, DataType*> KeyMap;
protected:
UniqueGCFactoryBase()
: GCFactoryBase<LinearAllocator<DataType, ChunkSize> >()
{ }
UniqueGCFactoryBase(size_t pNum)
: GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum)
{ }
public:
virtual ~UniqueGCFactoryBase()
{ f_KeyMap.clear(); }
DataType* find(const KeyType& pKey) {
typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
if (dataIter != f_KeyMap.end())
return dataIter->second;
return 0;
}
const DataType* find(const KeyType& pKey) const {
typename KeyMap::const_iterator dataIter = f_KeyMap.find(pKey);
if (dataIter != f_KeyMap.end())
return dataIter->second;
return 0;
}
DataType* produce(const KeyType& pKey, bool& pExist) {
typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
if (dataIter != f_KeyMap.end()) {
pExist = true;
return dataIter->second;
}
DataType* data = Alloc::allocate();
construct(data);
f_KeyMap.insert(std::make_pair(pKey, data));
pExist = false;
return data;
}
DataType* produce(const KeyType& pKey, const DataType& pValue, bool& pExist) {
typename KeyMap::iterator dataIter = f_KeyMap.find(pKey);
if (dataIter != f_KeyMap.end()) {
pExist = true;
return dataIter->second;
}
DataType* data = Alloc::allocate();
construct(data, pValue);
f_KeyMap.insert(std::make_pair(pKey, data));
pExist = false;
return data;
}
protected:
KeyMap f_KeyMap;
};
} // namespace of mcld
#endif