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