LINUX.ORG.RU

История изменений

Исправление Dudraug, (текущая версия) :

template<class TKey, class TValue1, class TValue2>
class MyBMap
{
  typedef std::pair<TValue1, TValue2> DPair;
  typedef std::pair<TKey, DPair> TPair;
  std::set<TPair> storage;

  std::unordered_map<TKey, TPair*> key_map;
  std::unordered_map<TValue1, TPair*> value_map;

public:
  MyBMap() = default;
  void insert(TPair data)
  {
    auto it = storage.emplace(std::move(data));
    if (!it.second)
      throw std::exception("not inserted");
    TKey k = it.first->first;
    TValue1 v1 = it.first->second.first;
    TPair& ref = (TPair&) *it.first;
    key_map.emplace(std::make_pair(std::move(k), &ref));
    value_map.emplace(std::make_pair(std::move(v1), &ref));
  }

  TPair& search_by_first(const TKey& key)
  {
    auto it = key_map.find(key);

    if (it == key_map.end())
      throw std::exception("not found");

    return *it->second;
  }

  TPair& search_by_second(const TValue1& key)
  {
    auto it = value_map.find(key);

    if (it == value_map.end())
      throw std::exception("not found");

    return *it->second;
  }

};

Вот тебе версия без инвалидации указателей и с эмплейсами.

Исправление Dudraug, :

template<class TKey, class TValue1, class TValue2>
class MyBMap
{
  typedef std::pair<TValue1, TValue2> DPair;
  typedef std::pair<TKey, DPair> TPair;
  std::set<TPair> storage;

  std::unordered_map<TKey, TPair*> key_map;
  std::unordered_map<TValue1, TPair*> value_map;

public:
  MyBMap()
  {

  }
  void insert(TPair data)
  {
    auto it = storage.emplace(std::move(data));
    if (!it.second)
      throw std::exception("not inserted");
    TKey k = it.first->first;
    TValue1 v1 = it.first->second.first;
    TPair& ref = (TPair&) *it.first;
    key_map.emplace(std::make_pair(std::move(k), &ref));
    value_map.emplace(std::make_pair(std::move(v1), &ref));
  }

  TPair& search_by_first(const TKey& key)
  {
    auto it = key_map.find(key);

    if (it == key_map.end())
      throw std::exception("not found");

    return *it->second;
  }

  TPair& search_by_second(const TValue1& key)
  {
    auto it = value_map.find(key);

    if (it == value_map.end())
      throw std::exception("not found");

    return *it->second;
  }

};

Вот тебе версия без инвалидации указателей и с эмплейсами.

Исходная версия Dudraug, :

template<class TKey, class TValue1, class TValue2>
class MyBMap
{
  typedef std::pair<TValue1, TValue2> DPair;
  typedef std::pair<TKey, DPair> TPair;
  std::set<TPair> storage;

  std::unordered_map<TKey, TPair*> key_map;
  std::unordered_map<TValue1, TPair*> value_map;

public:
  MyBMap()
  {

  }
  void insert(TPair data)
  {
    auto it = storage.emplace(std::move(data));
    if (!it.second)
      throw std::exception("not inserted");
    TKey k = it.first->first;
    TValue1 v1 = it.first->second.first;
    TPair& ref = (TPair&) *it.first;
    key_map.emplace(std::make_pair(std::move(k), &ref));
    value_map.emplace(std::make_pair(std::move(v1), &ref));
  }

  TPair& search_by_first(const TKey& key)
  {
    auto it = key_map.find(key);

    if (it == key_map.end())
      throw std::exception("not found");

    return *it->second;
  }

  TPair& search_by_second(const TValue1& key)
  {
    auto it = value_map.find(key);

    if (it == value_map.end())
      throw std::exception("not found");

    return *it->second;
  }

};

Вот тебе версия без инвалидации указателей и без эмплейсов.