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 {
EntryPairEntryPair28 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
empty()70 bool empty() const { return m_Pool.empty(); }
size()71 size_t size() const { return m_Pool.size(); }
72
begin()73 const_iterator begin() const { return m_Pool.begin(); }
begin()74 iterator begin() { return m_Pool.begin(); }
end()75 const_iterator end() const { return m_Pool.end(); }
end()76 iterator end() { return m_Pool.end(); }
77
reserve(size_t pSize)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>
lookUp(const KeyType & pKey)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>
lookUp(const KeyType & pKey)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>
lookUpFirstEntry(const KeyType & pKey)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>
lookUpFirstEntry(const KeyType & pKey)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>
lookUpSecondEntry(const KeyType & pKey)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>
lookUpSecondEntry(const KeyType & pKey)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>
record(const KeyType & pKey,EntryType & pEntry)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>
record(const KeyType & pKey,EntryType & pEntry1,EntryType & pEntry2)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