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_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:
     31   UniqueGCFactoryBase()
     32       : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >() {}
     33 
     34   explicit UniqueGCFactoryBase(size_t pNum)
     35       : GCFactoryBase<LinearAllocator<DataType, ChunkSize> >(pNum) {}
     36 
     37  public:
     38   virtual ~UniqueGCFactoryBase() { f_KeyMap.clear(); }
     39 
     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 
     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 
     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 
     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