CrystalSpace

Public API Reference

csutil/strset.h
Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2001 by Martin Geisse <mgeisse@gmx.net>
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public
00015     License along with this library; if not, write to the Free
00016     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 */
00018 
00019 #ifndef __CS_STRSET_H__
00020 #define __CS_STRSET_H__
00021 
00022 #include "csextern.h"
00023 #include "csutil/strhash.h"
00024 
00029 namespace CS
00030 {
00031 namespace Utility
00032 {
00047 template<typename Tag, bool Locked = false>
00048 class StringSet
00049 {
00050  private:
00051   typedef CS::Threading::OptionalMutex<Locked> MutexType;
00052   StringHash<Tag> registry;
00053   csHash<const char*, CS::StringID<Tag> > reverse; // ID to string mapping.
00054   /* Inherit from OptionalMutex<> to avoid spending extra memory if locking
00055      is disabled */
00056   struct LockAndId : public MutexType
00057   {
00058     unsigned int next_id;
00059 
00060     LockAndId() : next_id (0) {}
00061   };
00062   mutable LockAndId lockAndId;
00063 
00064   void Copy(StringSet const& s)
00065   {
00066     if (&s != this)
00067     {
00068       CS::Threading::ScopedLock<MutexType> l1 (lockAndId);
00069       CS::Threading::ScopedLock<MutexType> l2 (s.lockAndId);
00070       registry = s.registry;
00071       reverse  = s.reverse;
00072       lockAndId.next_id  = s.lockAndId.next_id;
00073     }
00074   }
00075 
00076 public:
00077   typedef csStringHash::GlobalIterator GlobalIterator;
00078 
00079 public:
00081   StringSet (size_t size = 23) : registry(size), reverse(size) {}
00083   StringSet (StringSet const& s) { Copy(s); }
00085   ~StringSet () {}
00087   StringSet& operator=(StringSet const& s) { Copy(s); return *this; }
00088 
00095   CS::StringID<Tag> Request (const char* s)
00096   {
00097     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00098     CS::StringID<Tag> id = registry.Request(s);
00099     if (id == CS::InvalidStringID<Tag> ())
00100     {
00101       const char* t = registry.Register(s, lockAndId.next_id);
00102       id = lockAndId.next_id++;
00103       reverse.Put (id, t);
00104     }
00105     return id;
00106   }
00107 
00113   char const* Request (CS::StringID<Tag> id) const
00114   {
00115     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00116     return reverse.Get(id, 0);
00117   }
00118 
00122   bool Contains(char const* s) const
00123   {
00124     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00125     return registry.Request(s) != CS::InvalidStringID<Tag> ();
00126   }
00127 
00133   bool Contains(CS::StringID<Tag> id) const
00134   { 
00135     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00136     return Request(id) != 0; 
00137   }
00138 
00143   bool Delete(char const* s)
00144   {
00145     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00146     CS::StringID<Tag> const id = registry.Request(s);
00147     bool const ok = (id != csInvalidStringID);
00148     if (ok)
00149     {
00150       registry.Delete(s);
00151       reverse.DeleteAll(id);
00152     }
00153     return ok;
00154   }
00155 
00160   bool Delete(CS::StringID<Tag> id)
00161   {
00162     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00163     char const* s = reverse.Get(id,0);
00164     bool const ok = (s != 0);
00165     if (ok)
00166     {
00167       registry.Delete(s);
00168       reverse.DeleteAll(id);
00169     }
00170     return ok;
00171   }
00172 
00177   void Empty ()
00178   {
00179     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00180     registry.Empty();
00181     reverse.Empty();
00182   }
00183 
00188   CS_DEPRECATED_METHOD_MSG("Use Empty() instead.")
00189   void Clear ()
00190   { Empty(); }
00191 
00193   size_t GetSize () const
00194   { 
00195     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00196     return registry.GetSize (); 
00197   }
00198 
00204   bool IsEmpty() const
00205   { 
00206     CS::Threading::ScopedLock<MutexType> lock (lockAndId);
00207     return GetSize() == 0; 
00208   }
00209 
00216   GlobalIterator GetIterator () const
00217   { return registry.GetIterator(); }
00218 };
00219 } // namespace Utility
00220 } // namespace CS
00221 
00222 typedef CS::Utility::StringSet<CS::StringSetTag::General> csStringSet;
00223 
00224 #endif // __CS_STRSET_H__

Generated for Crystal Space 2.0 by doxygen 1.7.6.1