KeyEntryMap.h revision 533eae20118036f425f27bf0536ef0ccbb090b65
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
15namespace mcld {
16
17/** \class KeyEntryMap
18 *  \brief KeyEntryMap is a <const KeyType*, ENTRY*> map.
19 */
20template<typename KEY, typename ENTRY>
21class KeyEntryMap
22{
23public:
24  typedef KEY   KeyType;
25  typedef ENTRY EntryType;
26
27private:
28  struct EntryPair {
29    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
52public:
53  typedef typename KeyEntryPool::iterator iterator;
54  typedef typename KeyEntryPool::const_iterator const_iterator;
55
56public:
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
74  bool   empty() const { return m_Pool.empty(); }
75  size_t size () const { return m_Pool.size(); }
76
77  const_iterator begin() const { return m_Pool.begin(); }
78  iterator       begin()       { return m_Pool.begin(); }
79  const_iterator end  () const { return m_Pool.end();   }
80  iterator       end  ()       { return m_Pool.end();   }
81
82  void reserve(size_t pSize) { m_Pool.reserve(pSize); }
83
84private:
85  KeyEntryPool m_Pool;
86
87  /// m_Pairs - the EntryPairs
88  PairListType m_Pairs;
89};
90
91template<typename KeyType, typename EntryType>
92const EntryType*
93KeyEntryMap<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
105template<typename KeyType, typename EntryType>
106EntryType*
107KeyEntryMap<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
119template<typename KeyType, typename EntryType>
120const EntryType*
121KeyEntryMap<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
133template<typename KeyType, typename EntryType>
134EntryType*
135KeyEntryMap<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
147template<typename KeyType, typename EntryType>
148const EntryType*
149KeyEntryMap<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
161template<typename KeyType, typename EntryType>
162EntryType*
163KeyEntryMap<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
175template<typename KeyType, typename EntryType>
176void
177KeyEntryMap<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
185template<typename KeyType, typename EntryType>
186void
187KeyEntryMap<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