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