1//===- UniqueGCFactory.h --------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#ifndef MCLD_UNIQUE_GCFACTORY_H 10#define MCLD_UNIQUE_GCFACTORY_H 11#ifdef ENABLE_UNITTEST 12#include <gtest.h> 13#endif 14 15#include "mcld/Support/GCFactory.h" 16#include <map> 17#include <utility> 18 19namespace mcld 20{ 21 22/** \class UniqueGCFactoryBase 23 * \brief UniqueGCFactories are unique associative factories, meaning that 24 * no two elements have the same key. 25 */ 26template<typename KeyType, typename DataType, size_t ChunkSize> 27class UniqueGCFactoryBase : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> > 28{ 29protected: 30 typedef GCFactoryBase<LinearAllocator<DataType, ChunkSize> > Alloc; 31 typedef std::map<KeyType, DataType*> KeyMap; 32 33protected: 34 UniqueGCFactoryBase() 35 : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >() 36 { } 37 38 UniqueGCFactoryBase(size_t pNum) 39 : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum) 40 { } 41 42public: 43 virtual ~UniqueGCFactoryBase() 44 { f_KeyMap.clear(); } 45 46 DataType* find(const KeyType& pKey) { 47 typename KeyMap::iterator dataIter = f_KeyMap.find(pKey); 48 if (dataIter != f_KeyMap.end()) 49 return dataIter->second; 50 return 0; 51 } 52 53 const DataType* find(const KeyType& pKey) const { 54 typename KeyMap::const_iterator dataIter = f_KeyMap.find(pKey); 55 if (dataIter != f_KeyMap.end()) 56 return dataIter->second; 57 return 0; 58 } 59 60 DataType* produce(const KeyType& pKey, bool& pExist) { 61 typename KeyMap::iterator dataIter = f_KeyMap.find(pKey); 62 if (dataIter != f_KeyMap.end()) { 63 pExist = true; 64 return dataIter->second; 65 } 66 DataType* data = Alloc::allocate(); 67 construct(data); 68 f_KeyMap.insert(std::make_pair(pKey, data)); 69 pExist = false; 70 return data; 71 } 72 73 DataType* produce(const KeyType& pKey, const DataType& pValue, bool& pExist) { 74 typename KeyMap::iterator dataIter = f_KeyMap.find(pKey); 75 if (dataIter != f_KeyMap.end()) { 76 pExist = true; 77 return dataIter->second; 78 } 79 DataType* data = Alloc::allocate(); 80 construct(data, pValue); 81 f_KeyMap.insert(std::make_pair(pKey, data)); 82 pExist = false; 83 return data; 84 } 85 86protected: 87 KeyMap f_KeyMap; 88 89}; 90 91} // namespace of mcld 92 93#endif 94 95