#ifndef MG_UTIL_WEAK_KEY_MAP_H #define MG_UTIL_WEAK_KEY_MAP_H #include #include #include #include "dependent_ptr.h" namespace mgd { template class weak_key_map { struct value_remover { void const* _key_ptr; weak_key_map* _owner_map; //_values_storage.find(_key_ptr); if (it != _owner_map->_values_storage.end()) { _owner_map->_values_storage.erase(it); } } void reset() { _owner_map = NULL; } }; friend struct value_remover; typedef std::map< void const*, value > storage_t; typedef std::vector< boost::weak_ptr > cleaners_t; storage_t _values_storage; cleaners_t _values_removers; public: typedef typename storage_t::iterator iterator; iterator begin() { return _values_storage.begin(); } iterator end() { return _values_storage.end(); } public: weak_key_map() { } ~weak_key_map() { clear(); } value& operator[](key const* k) { storage_t::iterator it = _values_storage.find( k ); if (it == _values_storage.end()) { boost::weak_ptr cleaner = make_dependent_ptr( k, std::auto_ptr( new value_remover(k, *this) ) ); _values_removers.push_back( cleaner ); } return _values_storage[ k ]; } iterator find(key const* k) { return _values_storage.find( k ); } void clear() { // reset the 'value_remover' objects that refer to this map cleaners_t::iterator it = _values_removers.begin(); cleaners_t::iterator const end = _values_removers.end(); while (it != end) { boost::shared_ptr cleaner = it->lock(); if (cleaner) { cleaner->reset(); } ++it; } // release values stored in this map _values_storage.clear(); } }; }; #endif