Home | History | Annotate | Download | only in Target
      1 //===- KeyEntryMap.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_TARGET_KEYENTRYMAP_H_
     10 #define MCLD_TARGET_KEYENTRYMAP_H_
     11 
     12 #include <list>
     13 #include <vector>
     14 
     15 namespace mcld {
     16 
     17 /** \class KeyEntryMap
     18  *  \brief KeyEntryMap is a <const KeyType*, ENTRY*> map.
     19  */
     20 template <typename KEY, typename ENTRY>
     21 class KeyEntryMap {
     22  public:
     23   typedef KEY KeyType;
     24   typedef ENTRY EntryType;
     25 
     26  private:
     27   struct EntryPair {
     28     EntryPair(EntryType* pEntry1, EntryType* pEntry2)
     29         : entry1(pEntry1), entry2(pEntry2) {}
     30 
     31     EntryType* entry1;
     32     EntryType* entry2;
     33   };
     34 
     35   /// EntryOrPair - A key may mapping to a signal entry or a pair of entries,
     36   /// user is responsible for the type of Mapping.entry
     37   union EntryOrPair {
     38     EntryType* entry_ptr;
     39     EntryPair* pair_ptr;
     40   };
     41 
     42   struct Mapping {
     43     const KeyType* key;
     44     EntryOrPair entry;
     45   };
     46 
     47   typedef std::vector<Mapping> KeyEntryPool;
     48   typedef std::list<EntryPair> PairListType;
     49 
     50  public:
     51   typedef typename KeyEntryPool::iterator iterator;
     52   typedef typename KeyEntryPool::const_iterator const_iterator;
     53 
     54  public:
     55   /// lookUp - look up the entry mapping to pKey
     56   const EntryType* lookUp(const KeyType& pKey) const;
     57   EntryType* lookUp(const KeyType& pKey);
     58 
     59   /// lookUpFirstEntry - look up the first entry mapping to pKey
     60   const EntryType* lookUpFirstEntry(const KeyType& pKey) const;
     61   EntryType* lookUpFirstEntry(const KeyType& pKey);
     62 
     63   /// lookUpSecondEntry - look up the second entry mapping to pKey
     64   const EntryType* lookUpSecondEntry(const KeyType& pKey) const;
     65   EntryType* lookUpSecondEntry(const KeyType& pKey);
     66 
     67   void record(const KeyType& pKey, EntryType& pEntry);
     68   void record(const KeyType& pKey, EntryType& pEntry1, EntryType& pEntry2);
     69 
     70   bool empty() const { return m_Pool.empty(); }
     71   size_t size() const { return m_Pool.size(); }
     72 
     73   const_iterator begin() const { return m_Pool.begin(); }
     74   iterator begin() { return m_Pool.begin(); }
     75   const_iterator end() const { return m_Pool.end(); }
     76   iterator end() { return m_Pool.end(); }
     77 
     78   void reserve(size_t pSize) { m_Pool.reserve(pSize); }
     79 
     80  private:
     81   KeyEntryPool m_Pool;
     82 
     83   /// m_Pairs - the EntryPairs
     84   PairListType m_Pairs;
     85 };
     86 
     87 template <typename KeyType, typename EntryType>
     88 const EntryType* KeyEntryMap<KeyType, EntryType>::lookUp(
     89     const KeyType& pKey) const {
     90   const_iterator mapping, mEnd = m_Pool.end();
     91   for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
     92     if (mapping->key == &pKey) {
     93       return mapping->entry.entry_ptr;
     94     }
     95   }
     96 
     97   return NULL;
     98 }
     99 
    100 template <typename KeyType, typename EntryType>
    101 EntryType* KeyEntryMap<KeyType, EntryType>::lookUp(const KeyType& pKey) {
    102   iterator mapping, mEnd = m_Pool.end();
    103   for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
    104     if (mapping->key == &pKey) {
    105       return mapping->entry.entry_ptr;
    106     }
    107   }
    108 
    109   return NULL;
    110 }
    111 
    112 template <typename KeyType, typename EntryType>
    113 const EntryType* KeyEntryMap<KeyType, EntryType>::lookUpFirstEntry(
    114     const KeyType& pKey) const {
    115   const_iterator mapping, mEnd = m_Pool.end();
    116   for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
    117     if (mapping->key == &pKey) {
    118       return mapping->entry.pair_ptr->entry1;
    119     }
    120   }
    121 
    122   return NULL;
    123 }
    124 
    125 template <typename KeyType, typename EntryType>
    126 EntryType* KeyEntryMap<KeyType, EntryType>::lookUpFirstEntry(
    127     const KeyType& pKey) {
    128   const_iterator mapping, mEnd = m_Pool.end();
    129   for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
    130     if (mapping->key == &pKey) {
    131       return mapping->entry.pair_ptr->entry1;
    132     }
    133   }
    134 
    135   return NULL;
    136 }
    137 
    138 template <typename KeyType, typename EntryType>
    139 const EntryType* KeyEntryMap<KeyType, EntryType>::lookUpSecondEntry(
    140     const KeyType& pKey) const {
    141   const_iterator mapping, mEnd = m_Pool.end();
    142   for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
    143     if (mapping->key == &pKey) {
    144       return mapping->entry.pair_ptr->entry2;
    145     }
    146   }
    147 
    148   return NULL;
    149 }
    150 
    151 template <typename KeyType, typename EntryType>
    152 EntryType* KeyEntryMap<KeyType, EntryType>::lookUpSecondEntry(
    153     const KeyType& pKey) {
    154   const_iterator mapping, mEnd = m_Pool.end();
    155   for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) {
    156     if (mapping->key == &pKey) {
    157       return mapping->entry.pair_ptr->entry2;
    158     }
    159   }
    160 
    161   return NULL;
    162 }
    163 
    164 template <typename KeyType, typename EntryType>
    165 void KeyEntryMap<KeyType, EntryType>::record(const KeyType& pKey,
    166                                              EntryType& pEntry) {
    167   Mapping mapping;
    168   mapping.key = &pKey;
    169   mapping.entry.entry_ptr = &pEntry;
    170   m_Pool.push_back(mapping);
    171 }
    172 
    173 template <typename KeyType, typename EntryType>
    174 void KeyEntryMap<KeyType, EntryType>::record(const KeyType& pKey,
    175                                              EntryType& pEntry1,
    176                                              EntryType& pEntry2) {
    177   Mapping mapping;
    178   mapping.key = &pKey;
    179   m_Pairs.push_back(EntryPair(&pEntry1, &pEntry2));
    180   mapping.entry.pair_ptr = &m_Pairs.back();
    181   m_Pool.push_back(mapping);
    182 }
    183 
    184 }  // namespace mcld
    185 
    186 #endif  // MCLD_TARGET_KEYENTRYMAP_H_
    187