Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | Related Pages

ref_map.h

00001 /*
00002   libwftk - Worldforge Toolkit - a widget library
00003   Copyright (C) 2003 Ron Steinke <rsteinke@w-link.net>
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009   
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014   
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the
00017   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018   Boston, MA  02111-1307, SA.
00019 */
00020 
00021 #ifndef _REF_MAP_H_
00022 #define _REF_MAP_H_
00023 
00024 #include <map>
00025 #include <cassert>
00026 
00027 namespace wftk {
00028 
00029 // This is a map which keeps single instances of its value
00030 // type available for refcounted keys. You write the create()
00031 // function which is used when an unknown key is ref'ed
00032 // for the first time.
00033 
00034 template<class Key, class T, class Cmp = std::less<Key> >
00035 class RefMap
00036 {
00037  public:
00038   RefMap(bool autodelete = true) : autodelete_(autodelete) {}
00039   virtual ~RefMap()
00040   {
00041     // We can't delete elements from the map if other things
00042     // still have references to them. The best we can do
00043     // is assert that all references have been dropped, and
00044     // rely on the users of this class to handle that.
00045     assert(map_.empty());
00046   }
00047 
00048   T* ref(const Key& key)
00049   {
00050     ValType& val = map_[key]; // find, and create if not already present
00051     if(!val.value) // must be newly created element, from new key
00052       val.value = create(key);
00053     ++val.refcount;
00054     return val.value;
00055   }
00056 
00057   void unref(const Key& key)
00058   {
00059     typename MapType::iterator I = map_.find(key);
00060     assert(I != map_.end());
00061     if(--I->second.refcount == 0) {
00062       delete I->second.value;
00063       map_.erase(I);
00064       if(autodelete_ && map_.empty())
00065         delete this;
00066     }
00067   }
00068 
00069   bool empty() const {return map_.empty();}
00070 
00071  private:
00072   virtual T* create(const Key&) = 0;
00073 
00074   struct ValType
00075   {
00076     ValType() : value(0), refcount(0) {}
00077 
00078     T* value;
00079     unsigned long refcount;
00080   };
00081   typedef std::map<Key, ValType, Cmp> MapType;
00082   MapType map_;
00083 
00084   bool autodelete_;
00085 };
00086 
00087 } // namespace
00088 
00089 #endif

Generated Tue Apr 12 22:48:51 2005.
Copyright © 1998-2003 by the respective authors.

This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.