//===- KeyEntryMap.h ---------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_TARGET_KEYENTRYMAP_H #define MCLD_TARGET_KEYENTRYMAP_H #include <vector> #include <list> namespace mcld { /** \class KeyEntryMap * \brief KeyEntryMap is a <const KeyType*, ENTRY*> map. */ template<typename KEY, typename ENTRY> class KeyEntryMap { public: typedef KEY KeyType; typedef ENTRY EntryType; private: struct EntryPair { EntryPair(EntryType* pEntry1, EntryType* pEntry2) : entry1(pEntry1), entry2(pEntry2) {} EntryType* entry1; EntryType* entry2; }; /// EntryOrPair - A key may mapping to a signal entry or a pair of entries, /// user is responsible for the type of Mapping.entry union EntryOrPair { EntryType* entry_ptr; EntryPair* pair_ptr; }; struct Mapping { const KeyType* key; EntryOrPair entry; }; typedef std::vector<Mapping> KeyEntryPool; typedef std::list<EntryPair> PairListType; public: typedef typename KeyEntryPool::iterator iterator; typedef typename KeyEntryPool::const_iterator const_iterator; public: /// lookUp - look up the entry mapping to pKey const EntryType* lookUp(const KeyType& pKey) const; EntryType* lookUp(const KeyType& pKey); /// lookUpFirstEntry - look up the first entry mapping to pKey const EntryType* lookUpFirstEntry(const KeyType& pKey) const; EntryType* lookUpFirstEntry(const KeyType& pKey); /// lookUpSecondEntry - look up the second entry mapping to pKey const EntryType* lookUpSecondEntry(const KeyType& pKey) const; EntryType* lookUpSecondEntry(const KeyType& pKey); void record(const KeyType& pKey, EntryType& pEntry); void record(const KeyType& pKey, EntryType& pEntry1, EntryType& pEntry2); bool empty() const { return m_Pool.empty(); } size_t size () const { return m_Pool.size(); } const_iterator begin() const { return m_Pool.begin(); } iterator begin() { return m_Pool.begin(); } const_iterator end () const { return m_Pool.end(); } iterator end () { return m_Pool.end(); } void reserve(size_t pSize) { m_Pool.reserve(pSize); } private: KeyEntryPool m_Pool; /// m_Pairs - the EntryPairs PairListType m_Pairs; }; template<typename KeyType, typename EntryType> const EntryType* KeyEntryMap<KeyType, EntryType>::lookUp(const KeyType& pKey) const { const_iterator mapping, mEnd = m_Pool.end(); for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) { if (mapping->key == &pKey) { return mapping->entry.entry_ptr; } } return NULL; } template<typename KeyType, typename EntryType> EntryType* KeyEntryMap<KeyType, EntryType>::lookUp(const KeyType& pKey) { iterator mapping, mEnd = m_Pool.end(); for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) { if (mapping->key == &pKey) { return mapping->entry.entry_ptr; } } return NULL; } template<typename KeyType, typename EntryType> const EntryType* KeyEntryMap<KeyType, EntryType>::lookUpFirstEntry(const KeyType& pKey) const { const_iterator mapping, mEnd = m_Pool.end(); for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) { if (mapping->key == &pKey) { return mapping->entry.pair_ptr->entry1; } } return NULL; } template<typename KeyType, typename EntryType> EntryType* KeyEntryMap<KeyType, EntryType>::lookUpFirstEntry(const KeyType& pKey) { const_iterator mapping, mEnd = m_Pool.end(); for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) { if (mapping->key == &pKey) { return mapping->entry.pair_ptr->entry1; } } return NULL; } template<typename KeyType, typename EntryType> const EntryType* KeyEntryMap<KeyType, EntryType>::lookUpSecondEntry(const KeyType& pKey) const { const_iterator mapping, mEnd = m_Pool.end(); for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) { if (mapping->key == &pKey) { return mapping->entry.pair_ptr->entry2; } } return NULL; } template<typename KeyType, typename EntryType> EntryType* KeyEntryMap<KeyType, EntryType>::lookUpSecondEntry(const KeyType& pKey) { const_iterator mapping, mEnd = m_Pool.end(); for (mapping = m_Pool.begin(); mapping != mEnd; ++mapping) { if (mapping->key == &pKey) { return mapping->entry.pair_ptr->entry2; } } return NULL; } template<typename KeyType, typename EntryType> void KeyEntryMap<KeyType, EntryType>::record(const KeyType& pKey, EntryType& pEntry) { Mapping mapping; mapping.key = &pKey; mapping.entry.entry_ptr = &pEntry; m_Pool.push_back(mapping); } template<typename KeyType, typename EntryType> void KeyEntryMap<KeyType, EntryType>::record(const KeyType& pKey, EntryType& pEntry1, EntryType& pEntry2) { Mapping mapping; mapping.key = &pKey; m_Pairs.push_back(EntryPair(&pEntry1, &pEntry2)); mapping.entry.pair_ptr = &m_Pairs.back(); m_Pool.push_back(mapping); } } // namespace of mcld #endif