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