list_map.h
#pragma once
#include <unordered_map>
#include <list>
#include <algorithm>
template<typename T, typename Key>
class ListMap {
public:
typedef std::list<T> NodeList;
typedef typename NodeList::iterator NodeLIt;
typedef typename NodeList::reverse_iterator NodeLRIt;
typedef std::unordered_map<Key, NodeLIt> NodeMap;
typedef std::pair<const Key, NodeLIt> NodePair;
typedef typename NodeMap::iterator NodeMIt;
typedef Key (*KeyFunc)(const T& node);
ListMap(KeyFunc func, NodeMap* pMap = nullptr): _list(), _tmap(), _pMap(pMap) {
_func = func;
}
~ListMap() {}
void AddNode(const T& node);
void DelNode(const T& node);
void DelNode(const Key& key);
T* GetNode(const Key& key);
void Clear() {
NodeMap& tmap = _map();
for (auto node : _list) {
tmap.erase(_func(node));
}
_list.clear();
_tmap.clear();
}
template<typename Cb>
void TraverseList(Cb func) {
for_each(rbegin(_list), rend(_list), [func](T& node) {
func(node);
});
}
template<typename Cb>
void TraverseMap(Cb func) {
for (auto& kvp : _map()) {
func(kvp);
}
}
inline NodeMap& _map() {
if (_pMap == NULL) {
return _tmap;
}
return *_pMap;
}
private:
NodeList _list;
NodeMap _tmap;
KeyFunc _func;
NodeMap* _pMap;
};
template<typename T, typename Key>
void ListMap<T, Key>::AddNode(const T& node) {
Key key = _func(node);
T* pNode = GetNode(key);
if (pNode != NULL) {
*pNode = node;
} else {
_list.push_front(node);
_map().insert(make_pair(key, _list.begin()));
}
}
template<typename T, typename Key>
void ListMap<T, Key>::DelNode(const T& node) {
DelNode(_func(node));
}
template<typename T, typename Key>
void ListMap<T, Key>::DelNode(const Key& key) {
NodeMap& tmap = _map();
NodeMIt it = tmap.find(key);
if (it != tmap.end()) {
_list.erase(it->second);
tmap.erase(it);
}
}
template<typename T, typename Key>
T* ListMap<T, Key>::GetNode(const Key& key) {
NodeMap& tmap = _map();
NodeMIt it = tmap.find(key);
if (it == tmap.end()) {
return NULL;
}
return &(*it->second);
}
main.cpp
#include <iostream>
#include "list_map.h"
using namespace std;
class Node {
public:
Node(int key = 0, int value = 0): nKey(key), nValue(value) {}
~Node() {}
void Show() {
cout << nKey << ":" << nValue << ";";
}
int nKey;
int nValue;
};
int main() {
typedef ListMap<Node, int> nodeList;
nodeList::NodeMap outMap;
nodeList nList([](const Node& node) { return node.nKey;}, &outMap);
for (int i = 0; i < 10; i++) {
nList.AddNode(Node(i, i*10));
}
nList.TraverseList([](Node& node) {
node.Show();
});
cout << endl;
for (auto node : outMap) {
node.second->Show();
}
cout << endl;
nList.DelNode(9);
for (auto node : outMap) {
node.second->Show();
}
cout << endl;
nList.Clear();
for (auto node : outMap) {
node.second->Show();
}
cout << endl;
nList.TraverseList([](Node& node) {
node.Show();
});
cout << endl;
return 0;
}