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