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