KeyEntryMap.h revision 37b74a387bb3993387029859c2d9d051c41c724e
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
15namespace mcld {
16
17/** \class KeyEntryMap
18 *  \brief KeyEntryMap is a <const KeyType*, ENTRY*> map.
19 */
20template <typename KEY, typename ENTRY>
21class KeyEntryMap {
22 public:
23  typedef KEY KeyType;
24  typedef ENTRY EntryType;
25
26 private:
27  struct EntryPair {
28    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
70  bool empty() const { return m_Pool.empty(); }
71  size_t size() const { return m_Pool.size(); }
72
73  const_iterator begin() const { return m_Pool.begin(); }
74  iterator begin() { return m_Pool.begin(); }
75  const_iterator end() const { return m_Pool.end(); }
76  iterator end() { return m_Pool.end(); }
77
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
87template <typename KeyType, typename EntryType>
88const 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
100template <typename KeyType, typename EntryType>
101EntryType* 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
112template <typename KeyType, typename EntryType>
113const 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
125template <typename KeyType, typename EntryType>
126EntryType* 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
138template <typename KeyType, typename EntryType>
139const 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
151template <typename KeyType, typename EntryType>
152EntryType* 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
164template <typename KeyType, typename EntryType>
165void 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
173template <typename KeyType, typename EntryType>
174void 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