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