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 {
EntryPairEntryPair29 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
empty()74 bool empty() const { return m_Pool.empty(); }
size()75 size_t size () const { return m_Pool.size(); }
76
begin()77 const_iterator begin() const { return m_Pool.begin(); }
begin()78 iterator begin() { return m_Pool.begin(); }
end()79 const_iterator end () const { return m_Pool.end(); }
end()80 iterator end () { return m_Pool.end(); }
81
reserve(size_t pSize)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*
lookUp(const KeyType & pKey)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*
lookUp(const KeyType & pKey)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*
lookUpFirstEntry(const KeyType & pKey)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*
lookUpFirstEntry(const KeyType & pKey)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*
lookUpSecondEntry(const KeyType & pKey)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*
lookUpSecondEntry(const KeyType & pKey)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
record(const KeyType & pKey,EntryType & pEntry)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
record(const KeyType & pKey,EntryType & pEntry1,EntryType & pEntry2)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