精選文章

SmallBurger Asset Home

  SmallBurger

2013年10月15日 星期二

About the bidirectional boost bimap implementation

Use for ID To name and name to ID.
The source code is here:
//-----------------------------------------------------------------------------------------------------------
//IDToUniqueName.h : Class Declaration
//-----------------------------------------------------------------------------------------------------------
#pragma once
#include < string >

class CIDToUniqueName
{
public:
  CIDToUniqueName(void);
  virtual ~CIDToUniqueName(void);
  bool AppendElement(unsigned long ulID, const std::string& strName);
  bool AppendElement(const std::string& strName, unsigned long ulID);
  bool RemoveElementByID(unsigned long ulID);
  bool RemoveElementByName(const std::string& strName);
  void ClearALLElement(void);
  bool GetID(const std::string& strName, unsigned long& ulID) const;
  bool GetName(unsigned long ulID, std::string& strOutName) const;
  size_t GetNumElements(void) const;
protected:
  class CIDToUniqueNameImpl* m_pImpl;
};
//-----------------------------------------------------------------------------------------------------------
//IDToUniqueName.cpp : Class Implementation
//-----------------------------------------------------------------------------------------------------------
#include < boost/bimap.hpp >
#include "IDToUniqueName.h"

typedef boost::bimap biamp_IDToName;

class CIDToUniqueNameImpl
{
public:
  biamp_IDToName m_bimapIDToName;
};

CIDToUniqueName::CIDToUniqueName(void):m_pImpl(NULL)
{
  m_pImpl = new CIDToUniqueNameImpl;
}
CIDToUniqueName::~CIDToUniqueName(void)
{
  delete m_pImpl;
  m_pImpl = NULL;
}

inline bool DoAppendElement(biamp_IDToName& bimapIDToName, unsigned long ulID, const std::string& strName)
{
  biamp_IDToName::left_const_iterator LeftIt = bimapIDToName.left.find(ulID);
  if(LeftIt != bimapIDToName.left.end())
    return false;
  biamp_IDToName::right_const_iterator RightIt = bimapIDToName.right.find(strName);
  if(RightIt != bimapIDToName.right.end())
    return false;
  bimapIDToName.insert(biamp_IDToName::value_type(ulID, strName));
  return true;
}

bool CIDToUniqueName::AppendElement(unsigned long ulID, const std::string& strName)
{
  return DoAppendElement(m_pImpl->m_bimapIDToName, ulID, strName);
}
bool CIDToUniqueName::AppendElement(const std::string& strName, unsigned long ulID)
{
  return DoAppendElement(m_pImpl->m_bimapIDToName, ulID, strName);
}
bool CIDToUniqueName::RemoveElementByID(unsigned long ulID)
{
  biamp_IDToName::left_iterator LeftIt = m_pImpl->m_bimapIDToName.left.find(ulID);
  if(LeftIt != m_pImpl->m_bimapIDToName.left.end())
  {
    m_pImpl->m_bimapIDToName.left.erase(LeftIt);
    return true;
  }
  return false;
}
bool CIDToUniqueName::RemoveElementByName(const std::string& strName)
{
  biamp_IDToName::right_iterator RightIt = m_pImpl->m_bimapIDToName.right.find(strName);
  if(RightIt != m_pImpl->m_bimapIDToName.right.end())
  {
    m_pImpl->m_bimapIDToName.right.erase(RightIt);
    return true;
  }
  return false;
}
void CIDToUniqueName::ClearALLElement(void)
{
  m_pImpl->m_bimapIDToName.clear();
}
bool CIDToUniqueName::GetID(const std::string& strName, unsigned long& ulID) const
{
  biamp_IDToName::right_iterator RightIt = m_pImpl->m_bimapIDToName.right.find(strName);
  if(RightIt != m_pImpl->m_bimapIDToName.right.end())
  {
    ulID = RightIt->second;
    return true;
  }
  return false;
}
bool CIDToUniqueName::GetName(unsigned long ulID, std::string& strOutName) const
{
  biamp_IDToName::left_iterator LeftIt = m_pImpl->m_bimapIDToName.left.find(ulID);
  if(LeftIt != m_pImpl->m_bimapIDToName.left.end())
  {
    strOutName = LeftIt->second;
    return true;
  }
  return false;
}
size_t CIDToUniqueName::GetNumElements(void) const
{
  return m_pImpl->m_bimapIDToName.size();
}
//-----------------------------------------------------------------------------------------------------------
//main.cpp : Sample Code
//-----------------------------------------------------------------------------------------------------------
#include < iostream >
#include "IDToUniqueName.h"

enum CAMP_TYPE
{
  CAMP_TYPE_PLAYER,
  CAMP_TYPE_BOSS,
  CAMP_TYPE_MONSTER,
  CAMP_TYPE_NPC,
  CAMP_TYPE_PARTNER,
  CAMP_TYPE_DRAGON,
  CAMP_TYPE_MAX
};

void main(void)
{
  CIDToUniqueName MyIDToName;
  MyIDToName.AppendElement("Player", CAMP_TYPE_PLAYER);
  MyIDToName.AppendElement(CAMP_TYPE_BOSS, "Boss");
  MyIDToName.AppendElement("Monster", CAMP_TYPE_MONSTER);
  MyIDToName.AppendElement(CAMP_TYPE_NPC, "NPC");
  MyIDToName.AppendElement("Partner", CAMP_TYPE_PARTNER);
  MyIDToName.AppendElement(CAMP_TYPE_DRAGON, "Dragon");

  size_t szCount = MyIDToName.GetNumElements();
  std::cout << "NumElements:" << szCount << std::endl;

  std::string Name;
  unsigned long ulID;

  MyIDToName.GetName(CAMP_TYPE_MONSTER, Name);
  std::cout << "CAMP_TYPE_MONSTER:" << Name << std::endl;
  MyIDToName.GetID(Name, ulID);
  std::cout << Name+":" << ulID << std::endl;


  MyIDToName.GetName(CAMP_TYPE_BOSS, Name);
  std::cout << "CAMP_TYPE_BOSS:" << Name << std::endl;
  MyIDToName.GetID(Name, ulID);
  std::cout << Name+":" << ulID << std::endl;

  system("pause");
}
//-----------------------------------------------------------------------------------------------------------

The reference link:
Boost.Bimap

Dream continues in...

3 則留言:

  1. 我個人覺得enum的顯示處理對bimap來說就是一個不錯的範例,一般程式常常會使用enum來儲存狀態(通常是為了效能或有運算的需求),然而enum畢竟是數字,雖然對程式辨識處理還不錯用,但對程式或工具使用者來說就不是很方便,可以用bimap來做雙向查找,顯示的時候用字串,當使用者選完選項後再轉回enum,這樣應該不錯用。

    回覆刪除
  2. 感覺map跟enum合在一起會顯得enum沒什麼用
    能舉些應該使用enum的例子嗎?

    回覆刪除
  3. 狀態吧!比方像AI的狀態,WALK_STATE, JUMP_STATE, RUN_STATE...等.

    回覆刪除