libmoost
/home/mhx/git/github/libmoost/include/moost/container/index_translator.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #ifndef MOOST_CONTAINER_INDEX_TRANSLATOR_HPP
00029 #define MOOST_CONTAINER_INDEX_TRANSLATOR_HPP
00030 
00031 #include "policies/dense_hash_map.hpp"
00032 #include <vector>
00033 
00034 #include <google/dense_hash_map>
00035 
00036 namespace moost { namespace container {
00037 
00045 template < typename TFrom = int,
00046            typename TTo = int,
00047            typename TMap = google::dense_hash_map<TFrom, TTo> >
00048 class index_translator
00049 {
00050 public:
00051 
00052    typedef typename policies::map_policy_selector<TFrom, TTo, TMap>::policy_type map_policy_t;
00053 
00054 public:
00055 
00056    index_translator()
00057    {
00058       map_policy_t defPolicy;
00059       defPolicy.init(m_item_index);
00060    }
00061 
00062    index_translator(const map_policy_t& mapInitPolicy )
00063    {
00064       mapInitPolicy.init(m_item_index);
00065    }
00066 
00067    int add(const TFrom& id)
00068    {
00069       typename TMap::const_iterator it = m_item_index.find(id);
00070       if ( it != m_item_index.end() )
00071          return it->second;
00072       else
00073       {
00074          TTo index = static_cast<TTo>(m_ids.size());
00075          m_item_index[id] = index;
00076          m_ids.push_back(id);
00077          return index;
00078       }
00079    }
00080 
00081    TTo find_index(const TFrom& id) const
00082    {
00083       typename TMap::const_iterator it = m_item_index.find(id);
00084       if (it == m_item_index.end())
00085          return -1;
00086 
00087       return it->second;
00088    }
00089 
00090    bool find_index( const TFrom& id,
00091                     TTo& result_index ) const
00092    {
00093       result_index = find_index(id);
00094       if ( result_index < 0 )
00095          return false;
00096       else
00097          return true;
00098    }
00099 
00100    TFrom get_id(TTo index) const
00101    {
00102       assert( index >= 0 );
00103       return m_ids[index];
00104    }
00105 
00106    TFrom safe_get_id(TTo index) const
00107    {
00108       if ( index >= static_cast<int>(this->size()) )
00109          throw std::runtime_error("index_translator: index out of range");
00110       return get_id(index);
00111    }
00112 
00113    size_t size() const
00114    {
00115       return m_ids.size();
00116    }
00117 
00118    bool empty() const
00119    {
00120       return m_ids.empty();
00121    }
00122 
00123 public:
00124 
00125    bool operator()(const TFrom& id, TTo& result_index) const
00126    { return find_index(id, result_index); }
00127 
00128 private:
00129 
00130    TMap                 m_item_index; // id -> index
00131    std::vector<TFrom>   m_ids;        // index -> id
00132 
00133 };
00134 
00135 }} // moost::container
00136 
00137 #endif // MOOST_CONTAINER_INDEX_TRANSLATOR_HPP