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