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