Google

Main Page   Class Hierarchy   Compound List   File List   Compound Members  

typedvec.h

00001 /*
00002     Crystal Space utility library: type-safe extension of data vectors
00003     Copyright (C) 2000 by Martin Geisse (mgeisse@gmx.net)
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 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     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public
00016     License along with this library; if not, write to the Free
00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 #ifndef __TYPEDVEC_H__
00021 #define __TYPEDVEC_H__
00022 
00023 #include "csutil/scf.h"
00024 #include "csutil/csvector.h"
00025 
00064 #define CS_DECLARE_TYPED_VECTOR(NAME,TYPE)                              \
00065   CS_PRIVATE_DECLARE_TYPED_VECTOR (NAME, TYPE)
00066 
00071 #define CS_DECLARE_TYPED_VECTOR_NODELETE(NAME,TYPE)                     \
00072   CS_PRIVATE_DECLARE_TYPED_VECTOR_NODELETE (NAME, TYPE)
00073 
00079 #define CS_DECLARE_TYPED_VECTOR_DECREF(NAME, TYPE) \
00080  CS_PRIVATE_DECLARE_TYPED_VECTOR_DECREF(NAME, TYPE)
00081 
00091 #define CS_DECLARE_TYPED_IBASE_VECTOR(NAME,TYPE)                        \
00092   CS_PRIVATE_DECLARE_TYPED_IBASE_VECTOR (NAME, TYPE)
00093 
00100 #define CS_DECLARE_TYPED_RESTRICTED_ACCESS_VECTOR(NAME,TYPE)            \
00101   CS_PRIVATE_DECLARE_TYPED_RESTRICTED_ACCESS_VECTOR (NAME, TYPE)
00102 
00103 //----------------------------------------------------------------------------
00104 //--- implementation of the above macros follows -----------------------------
00105 //----------------------------------------------------------------------------
00106 
00115 class csRestrictedAccessVector : public csVector
00116 {
00117 public:
00118   virtual bool PrepareItem (csSome )
00119   { return true; }
00120   virtual bool FreeItem (csSome )
00121   { return true; }
00122 
00123   inline csRestrictedAccessVector (int lim, int thr) : csVector (lim, thr) {}
00124   inline bool Delete (int n)
00125   {
00126     return csVector::Delete (n, true);
00127   }
00128   inline bool Delete (csSome what)
00129   {
00130     return csVector::Delete (what, true);
00131   }
00132   inline void DeleteAll ()
00133   {
00134     csVector::DeleteAll (true);
00135   }
00136   inline int Push (csSome what)
00137   {
00138     if (!PrepareItem (what)) return -1;
00139     return csVector::Push(what);
00140   }
00141   inline int PushSmart (csSome what)
00142   {
00143     int n = Find (what);
00144     if (n != -1) return n;
00145 
00146     if (!PrepareItem (what)) return -1;
00147     return csVector::Push(what);
00148   }
00149   inline bool Insert (int n, csSome Item)
00150   {
00151     if (!PrepareItem (Item)) return false;
00152     return csVector::Insert (n, Item);
00153   }
00154   inline int InsertSorted (csSome Item, int *oEqual = NULL, int Mode = 0)
00155   {
00156     if (!PrepareItem (Item)) return -1;
00157     return csVector::InsertSorted (Item, oEqual, Mode);
00158   }
00159   inline bool Replace (int n, csSome what)
00160   {
00161     if (!PrepareItem (what)) return false;
00162     return csVector::Replace (n, what, true);
00163   }
00164   inline csSome Pop ()
00165   {
00166     if (FreeItem (Top ()))
00167       return csVector::Pop ();
00168     else
00169       return NULL;
00170   }
00171 };
00172 
00173 /*
00174  * Helper class for vectors that contain 'iBase' objects. It assumes that
00175  * the contained objects may be cast to 'iBase'. Note that it does not
00176  * take parameters of type 'iBase'. This way it overrides the methods of
00177  * csVector and makes them unaccessible. Using csVector's methods
00178  * directly is unsafe. <p>
00179  *
00180  * Also, this means that CS_DECLARE_IBASE_VECTOR only has to cast from and to
00181  * (void*), which is always possible.  Theoretically, casting from and to iBase
00182  * is also always possible because the contained objects *must* be derived from
00183  * iBase. However, at the time CS_DECLARE_IBASE_VECTOR is used, this
00184  * inheritance may be unknown to the compiler because the class definition of
00185  * the contained class did not yet appear. <p>
00186  *
00187  * iBase vectors handle the Pop() method specially in the way that they do not
00188  * DecRef items removed with Pop().
00189  */
00190 class csIBaseVector : public csRestrictedAccessVector
00191 {
00192 public:
00193   inline csIBaseVector (int lim, int thr) : csRestrictedAccessVector (lim, thr) {}
00194 
00195   virtual bool PrepareItem (csSome Item)
00196   {
00197     ((iBase*)Item)->IncRef ();
00198     return true;
00199   }
00200   virtual bool FreeItem (csSome Item)
00201   {
00202     ((iBase*)Item)->DecRef ();
00203     return true;
00204   }
00205   inline csSome Pop ()
00206   {
00207     // Items that are removed with Pop() should not be DecRef'ed. To keep
00208     // the code simple, we just IncRef them before.
00209     csSome item = Top ();
00210     ((iBase*)item)->IncRef ();
00211 
00212     if (FreeItem (item)) {
00213       // We also have to bypass csRestrictedAccessVector::Pop ().
00214       return csVector::Pop ();
00215     } else {
00216       // Removal failed, so we have to release our reference again.
00217       ((iBase*)item)->DecRef ();
00218       return NULL;
00219     }
00220   }
00221 };
00222 
00223 /*
00224  * This is a helper macro for typed vectors. It defines all methods that are
00225  * valid for usual typed vectors and typed SCF vectors. This basically
00226  * excludes all methods that have a 'DeleteIt' parameter for
00227  * usual typed vectors and methods that return 'insecure' references. <p>
00228  *
00229  * This macro assumes that the type 'superclass' is defined to the superclass
00230  * of the typed vector.
00231  */
00232 #define CS_PRIVATE_DECLARE_TYPED_VECTOR_HELPER(NAME,TYPE)               \
00233     inline NAME (int ilimit = 16, int ithreshold = 16) :                \
00234       superclass (ilimit, ithreshold) {}                                \
00235     virtual ~NAME ()                                                    \
00236     { DeleteAll (); }                                                   \
00237     inline void SetLength (int n)                                       \
00238     { superclass::SetLength(n); }                                       \
00239     inline int Length () const                                          \
00240     { return count; }                                                   \
00241     inline int Limit () const                                           \
00242     { return limit; }                                                   \
00243     inline void Exchange (int n1, int n2)                               \
00244     { superclass::Exchange (n1, n2); }                                  \
00245     inline void QuickSort (int Left, int Right, int Mode = 0)           \
00246     { superclass::QuickSort (Left, Right, Mode); }                      \
00247     inline void QuickSort (int Mode = 0)                                \
00248     { superclass::QuickSort (Mode); }                                   \
00249     inline int Find (TYPE *which) const                                 \
00250     { return superclass::Find ((csSome)which); }                        \
00251     inline int FindKey (csConstSome Key, int Mode = 0) const            \
00252     { return superclass::FindKey (Key, Mode); }                         \
00253     inline int FindSortedKey (csConstSome Key, int Mode = 0) const      \
00254     { return superclass::FindSortedKey (Key, Mode); }                   \
00255     inline int Push (TYPE *obj)                                         \
00256     { return superclass::Push ((csSome)obj); }                          \
00257     inline int PushSmart (TYPE *obj)                                    \
00258     { return superclass::PushSmart ((csSome)obj); }                     \
00259     inline TYPE *Pop ()                                                 \
00260     { return (TYPE *)superclass::Pop(); }                               \
00261     inline TYPE *Top () const                                           \
00262     { return (TYPE *)superclass::Top(); }                               \
00263     inline bool Insert (int n, TYPE *Item)                              \
00264     { return superclass::Insert (n, (csSome)Item); }                    \
00265     inline int InsertSorted (TYPE *Item, int *oEqual = NULL, int Mode = 0) \
00266     { return superclass::InsertSorted ((csSome)Item, oEqual, Mode); }
00267 
00268 /*
00269  * Declares a new vector type NAME as a subclass of csVector.
00270  * Elements of this vector are of type TYPE. The elements are
00271  * automatically given to FreeTypedItem() on either Delete() or
00272  * DeleteAll() or upon vector destruction. However, you must define
00273  * FreeTypedItem() yourself. <p>
00274  *
00275  * Be careful with user-defined methods in typed vectors. Though the
00276  * vectors are type-safe to the outside, it is still possible to access
00277  * csVector members (type-unsafe!) from the inside, i.e. from your own methods.
00278  *
00279  * Usage (all features):
00280  *   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME, TYPE)
00281  *     user-defined FreeTypedItem() here
00282  *     any other user-defined methods
00283  *   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00284  *
00285  * or (no user-defined members, contained objects are correctly deleted):
00286  *   CS_PRIVATE_DECLARE_TYPED_VECTOR (NAME, TYPE)
00287  *
00288  * or (no user-defined members, contained objects are not deleted):
00289  *   CS_PRIVATE_DECLARE_TYPED_VECTOR_NODELETE (NAME, TYPE)
00290  *
00291  * or (no user-defined members, user has to define FreeTypedItem):
00292  *   CS_PRIVATE_DECLARE_TYPED_VECTOR_NODELETE (NAME, TYPE)
00293  *
00294  * Parameters:
00295  *   NAME - Name of the new vector class.
00296  *   TYPE - Data type to which this vector refer.
00297  *          The TYPE should be possible to cast to (void *) and back.
00298  */
00299 #define CS_PRIVATE_BEGIN_TYPED_VECTOR(NAME,TYPE)                        \
00300   class NAME : private csVector                                         \
00301   {                                                                     \
00302     typedef csVector superclass;                                        \
00303   public:                                                               \
00304     inline bool Delete (int n, bool FreeIt = true)                      \
00305     { return superclass::Delete (n, FreeIt); }                          \
00306     inline bool Delete (TYPE *Item, bool FreeIt = true)                 \
00307     { return superclass::Delete ((csSome)Item, FreeIt); }               \
00308     inline void DeleteAll (bool FreeThem = true)                        \
00309     { superclass::DeleteAll (FreeThem); }                               \
00310     CS_PRIVATE_DECLARE_TYPED_VECTOR_HELPER (NAME, TYPE)                 \
00311     inline TYPE *& operator [] (int n)                                  \
00312     { return (TYPE *&)superclass::operator [] (n); }                    \
00313     inline TYPE *& operator [] (int n) const                            \
00314     { return (TYPE *&)superclass::operator [] (n); }                    \
00315     inline TYPE *& Get (int n) const                                    \
00316     { return (TYPE *&)superclass::Get(n); }                             \
00317     inline TYPE **GetArray ()                                           \
00318     { return (TYPE**)root; }                                            \
00319     inline bool Replace (int n, TYPE *what, bool FreePrevious = true)   \
00320     { return superclass::Replace(n, (csSome)what, FreePrevious); }
00321 
00322 // Finish the class definition of a typed vector
00323 #define CS_PRIVATE_FINISH_TYPED_VECTOR(TYPE)                            \
00324     virtual bool FreeItem (csSome Item)                                 \
00325     { return FreeTypedItem ((TYPE *)Item); }                            \
00326   }
00327 
00328 /*
00329  * Declares a new vector type NAME as a subclass of csVector. Elements
00330  * of this vector are of type TYPE. The elements are automatically deleted
00331  * on either Delete() or DeleteAll() or upon vector destruction.
00332  */
00333 #define CS_PRIVATE_DECLARE_TYPED_VECTOR(NAME,TYPE)                      \
00334   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME,TYPE)                             \
00335     inline bool FreeTypedItem (TYPE* obj)                               \
00336     { delete obj; return true; }                                        \
00337   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00338 
00343 #define CS_PRIVATE_DECLARE_TYPED_VECTOR_NODELETE(NAME,TYPE)             \
00344   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME,TYPE)                             \
00345     inline bool FreeTypedItem (TYPE*)                                   \
00346     { return true; }                                                    \
00347   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00348 
00353 #define CS_PRIVATE_DECLARE_TYPED_VECTOR_USERDELETE(NAME,TYPE)           \
00354   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME,TYPE)                             \
00355     bool FreeTypedItem (TYPE*);                                         \
00356   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00357 
00358 #define CS_PRIVATE_DECLARE_TYPED_VECTOR_DECREF(NAME,TYPE)  \
00359   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME,TYPE)                \
00360     inline bool FreeTypedItem (TYPE *Item)                 \
00361     { Item->DecRef(); Item = NULL; return true; }          \
00362   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00363 
00369 #define CS_PRIVATE_DECLARE_TYPED_RESTR_ACC_VECTOR(NAME,TYPE,sclass)     \
00370   class NAME : private sclass                                           \
00371   {                                                                     \
00372   protected:                                                            \
00373     typedef sclass superclass;                                          \
00374     virtual bool PrepareItem (csSome item)                              \
00375     { return superclass::PrepareItem (item); }                          \
00376     virtual bool FreeItem (csSome item)                                 \
00377     { return superclass::FreeItem (item); }                             \
00378   public:                                                               \
00379     inline bool Delete (int n)                                          \
00380     { return superclass::Delete (n); }                                  \
00381     inline bool Delete (TYPE *Item)                                     \
00382     { return superclass::Delete ((csSome)Item); }                       \
00383     inline void DeleteAll ()                                            \
00384     { superclass::DeleteAll (); }                                       \
00385     CS_PRIVATE_DECLARE_TYPED_VECTOR_HELPER (NAME, TYPE)                 \
00386     inline TYPE *operator [] (int n) const                              \
00387     { return (TYPE *)superclass::operator [] (n); }                     \
00388     inline TYPE *Get (int n) const                                      \
00389     { return (TYPE *)superclass::Get(n); }                              \
00390     inline bool Replace (int n, TYPE *what)                             \
00391     { return superclass::Replace(n, (csSome)what); }                    \
00392   }
00393 
00394 #define CS_PRIVATE_DECLARE_TYPED_RESTRICTED_ACCESS_VECTOR(NAME,TYPE)    \
00395   CS_PRIVATE_DECLARE_TYPED_RESTR_ACC_VECTOR (NAME, TYPE, csRestrictedAccessVector)
00396 
00397 #define CS_PRIVATE_DECLARE_TYPED_IBASE_VECTOR(NAME,TYPE)                \
00398   CS_PRIVATE_DECLARE_TYPED_RESTR_ACC_VECTOR (NAME, TYPE, csIBaseVector)
00399 
00400 /*
00401  * This is a special version of typed vectors that contain SCF objects. The
00402  * vector will correctly IncRef all added objects and DecRef all removed
00403  * objects. There is only one exeption: The Pop() function does not DecRef
00404  * the object, so you should do that yourself. The reason is that at the time
00405  * you call Pop(), you do usually not have a pointer to the object, so you can
00406  * not IncRef() it before. <p>
00407  *
00408  * Usage:
00409  *   CS_PRIVATE_DECLARE_TYPED_RESTR_ACC_VECTOR (superclass, NAME, TYPE)
00410  *
00411  * Parameters:
00412  *   superclass - The parent class. May be either csIBaseVector or
00413  *                csRestrictedAccessVector.
00414  *   NAME - Name of the new vector class.
00415  *   TYPE - Data type to which this vector refer.
00416  *          The TYPE should be possible to cast to (void *) and back.
00417  */
00418 
00419 #define CS_PRIVATE_IMPLEMENT_TYPED_VECTOR_DELETE(NAME,TYPE)             \
00420   bool NAME::FreeTypedItem (TYPE *Item)                                 \
00421   { delete Item; return true; }
00422 
00423 #define CS_PRIVATE_BEGIN_USER_VECTOR(MACRO,NAME,TYPE)                   \
00424   MACRO (NAME##_Helper, TYPE);                                          \
00425   class NAME : public NAME##_Helper                                     \
00426   {                                                                     \
00427   public:
00428 
00429 #define CS_PRIVATE_FINISH_USER_VECTOR                                   \
00430   }
00431 
00432 #define CS_PRIVATE_TYPED_VECTOR_CONSTRUCTOR(NAME)                       \
00433   NAME (int ilimit = 8, int ithreshold = 16) :                          \
00434     NAME##_Helper (ilimit, ithreshold) {}
00435 
00436 #endif // __TYPEDVEC_H__

Generated for Crystal Space by doxygen 1.2.5 written by Dimitri van Heesch, ©1997-2000