• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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