csutil/strset.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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__