• 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_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:
UniqueGCFactoryBase()34   UniqueGCFactoryBase()
35   : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >()
36   { }
37 
UniqueGCFactoryBase(size_t pNum)38   UniqueGCFactoryBase(size_t pNum)
39   : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum)
40   { }
41 
42 public:
~UniqueGCFactoryBase()43   virtual ~UniqueGCFactoryBase()
44   { f_KeyMap.clear(); }
45 
find(const KeyType & pKey)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 
find(const KeyType & pKey)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 
produce(const KeyType & pKey,bool & pExist)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 
produce(const KeyType & pKey,const DataType & pValue,bool & pExist)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