Home | History | Annotate | Download | only in Support
      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