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