C++程序  |  187行  |  5.21 KB

//===- 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 <list>
#include <vector>

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 mcld

#endif  // MCLD_TARGET_KEYENTRYMAP_H_