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