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:
UniqueGCFactoryBase()31   UniqueGCFactoryBase()
32       : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >() {}
33 
UniqueGCFactoryBase(size_t pNum)34   explicit UniqueGCFactoryBase(size_t pNum)
35       : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum) {}
36 
37  public:
~UniqueGCFactoryBase()38   virtual ~UniqueGCFactoryBase() { f_KeyMap.clear(); }
39 
find(const KeyType & pKey)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 
find(const KeyType & pKey)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 
produce(const KeyType & pKey,bool & pExist)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 
produce(const KeyType & pKey,const DataType & pValue,bool & pExist)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