list_map.hnode
#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.cppios
#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; }