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 19 namespace mcld 20 { 21 22 /** \class UniqueGCFactoryBase 23 * \brief UniqueGCFactories are unique associative factories, meaning that 24 * no two elements have the same key. 25 */ 26 template<typename KeyType, typename DataType, size_t ChunkSize> 27 class UniqueGCFactoryBase : public GCFactoryBase<LinearAllocator<DataType, ChunkSize> > 28 { 29 protected: 30 typedef GCFactoryBase<LinearAllocator<DataType, ChunkSize> > Alloc; 31 typedef std::map<KeyType, DataType*> KeyMap; 32 33 protected: 34 UniqueGCFactoryBase() 35 : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >() 36 { } 37 38 UniqueGCFactoryBase(size_t pNum) 39 : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum) 40 { } 41 42 public: 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 86 protected: 87 KeyMap f_KeyMap; 88 89 }; 90 91 } // namespace of mcld 92 93 #endif 94 95