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 14 #include <map> 15 #include <utility> 16 17 namespace mcld { 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 25 : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> > { 26 protected: 27 typedef GCFactoryBase<LinearAllocator<DataType, ChunkSize> > Alloc; 28 typedef std::map<KeyType, DataType*> KeyMap; 29 30 protected: 31 UniqueGCFactoryBase() 32 : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >() {} 33 34 explicit UniqueGCFactoryBase(size_t pNum) 35 : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum) {} 36 37 public: 38 virtual ~UniqueGCFactoryBase() { f_KeyMap.clear(); } 39 40 DataType* find(const KeyType& pKey) { 41 typename KeyMap::iterator dataIter = f_KeyMap.find(pKey); 42 if (dataIter != f_KeyMap.end()) 43 return dataIter->second; 44 return 0; 45 } 46 47 const DataType* find(const KeyType& pKey) const { 48 typename KeyMap::const_iterator dataIter = f_KeyMap.find(pKey); 49 if (dataIter != f_KeyMap.end()) 50 return dataIter->second; 51 return 0; 52 } 53 54 DataType* produce(const KeyType& pKey, bool& pExist) { 55 typename KeyMap::iterator dataIter = f_KeyMap.find(pKey); 56 if (dataIter != f_KeyMap.end()) { 57 pExist = true; 58 return dataIter->second; 59 } 60 DataType* data = Alloc::allocate(); 61 construct(data); 62 f_KeyMap.insert(std::make_pair(pKey, data)); 63 pExist = false; 64 return data; 65 } 66 67 DataType* produce(const KeyType& pKey, const DataType& pValue, bool& pExist) { 68 typename KeyMap::iterator dataIter = f_KeyMap.find(pKey); 69 if (dataIter != f_KeyMap.end()) { 70 pExist = true; 71 return dataIter->second; 72 } 73 DataType* data = Alloc::allocate(); 74 construct(data, pValue); 75 f_KeyMap.insert(std::make_pair(pKey, data)); 76 pExist = false; 77 return data; 78 } 79 80 protected: 81 KeyMap f_KeyMap; 82 }; 83 84 } // namespace mcld 85 86 #endif // MCLD_SUPPORT_UNIQUEGCFACTORY_H_ 87