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 
00081 #define CS_DECLARE_TYPED_VECTOR_USERDELETE(NAME,TYPE)                   \
00082   CS_PRIVATE_DECLARE_TYPED_VECTOR_USERDELETE (NAME, TYPE)
00083 
00088 #define CS_DECLARE_TYPED_VECTOR_DECREF(NAME, TYPE) \
00089  CS_PRIVATE_DECLARE_TYPED_VECTOR_DECREF(NAME, TYPE)
00090 
00097 #define CS_IMPLEMENT_TYPED_VECTOR_DELETE(NAME,TYPE)                     \
00098   CS_PRIVATE_IMPLEMENT_TYPED_VECTOR_DELETE(NAME,TYPE)
00099 
00109 #define CS_DECLARE_TYPED_IBASE_VECTOR(NAME,TYPE)                        \
00110   CS_PRIVATE_DECLARE_TYPED_IBASE_VECTOR (NAME, TYPE)
00111 
00118 #define CS_DECLARE_TYPED_RESTRICTED_ACCESS_VECTOR(NAME,TYPE)            \
00119   CS_PRIVATE_DECLARE_TYPED_RESTRICTED_ACCESS_VECTOR (NAME, TYPE)
00120 
00143 #define CS_BEGIN_TYPED_VECTOR(MACRO,NAME,TYPE)                          \
00144   CS_PRIVATE_BEGIN_USER_VECTOR(MACRO,NAME,TYPE)
00145 
00149 #define CS_FINISH_TYPED_VECTOR                                          \
00150   CS_PRIVATE_FINISH_USER_VECTOR
00151 
00156 #define CS_TYPED_VECTOR_CONSTRUCTOR(NAME)                               \
00157   CS_PRIVATE_TYPED_VECTOR_CONSTRUCTOR (NAME)
00158 
00159 
00160 //----------------------------------------------------------------------------
00161 //--- implementation of the above macros follows -----------------------------
00162 //----------------------------------------------------------------------------
00163 
00172 class csRestrictedAccessVector : public csVector
00173 {
00174 public:
00175   virtual bool PrepareItem (csSome )
00176   { return true; }
00177   virtual bool FreeItem (csSome )
00178   { return true; }
00179 
00180   inline csRestrictedAccessVector (int lim, int thr) : csVector (lim, thr) {}
00181   inline bool Delete (int n)
00182   {
00183     return csVector::Delete (n, true);
00184   }
00185   inline bool Delete (csSome what)
00186   {
00187     return csVector::Delete (what, true);
00188   }
00189   inline void DeleteAll ()
00190   {
00191     csVector::DeleteAll (true);
00192   }
00193   inline int Push (csSome what)
00194   {
00195     if (!PrepareItem (what)) return -1;
00196     return csVector::Push(what); 
00197   }
00198   inline int PushSmart (csSome what)
00199   {
00200     int n = Find (what);
00201     if (n != -1) return n;
00202 
00203     if (!PrepareItem (what)) return -1;
00204     return csVector::Push(what); 
00205   }
00206   inline bool Insert (int n, csSome Item)
00207   {
00208     if (!PrepareItem (Item)) return false;
00209     return csVector::Insert (n, Item);
00210   }
00211   inline int InsertSorted (csSome Item, int *oEqual = NULL, int Mode = 0)
00212   {
00213     if (!PrepareItem (Item)) return -1;
00214     return csVector::InsertSorted (Item, oEqual, Mode); 
00215   }
00216   inline bool Replace (int n, csSome what)
00217   {
00218     if (!PrepareItem (what)) return false;
00219     return csVector::Replace (n, what, true);
00220   }
00221   inline csSome Pop ()
00222   {
00223     if (FreeItem (Top ()))
00224       return csVector::Pop ();
00225     else
00226       return NULL;
00227   }
00228 };
00229 
00230 /*
00231  * Helper class for vectors that contain 'iBase' objects. It assumes that
00232  * the contained objects may be cast to 'iBase'. Note that it does not
00233  * take parameters of type 'iBase'. This way it overrides the methods of
00234  * csVector and makes them unaccessible. Using csVector's methods
00235  * directly is unsafe. <p>
00236  * 
00237  * Also, this means that CS_DECLARE_IBASE_VECTOR only has to cast from and to
00238  * (void*), which is always possible.  Theoretically, casting from and to iBase
00239  * is also always possible because the contained objects *must* be derived from
00240  * iBase. However, at the time CS_DECLARE_IBASE_VECTOR is used, this
00241  * inheritance may be unknown to the compiler because the class definition of
00242  * the contained class did not yet appear. <p>
00243  *
00244  * iBase vectors handle the Pop() method specially in the way that they do not
00245  * DecRef items removed with Pop().
00246  */
00247 class csIBaseVector : public csRestrictedAccessVector
00248 {
00249 public:
00250   inline csIBaseVector (int lim, int thr) : csRestrictedAccessVector (lim, thr) {}
00251 
00252   virtual bool PrepareItem (csSome Item)
00253   {
00254     ((iBase*)Item)->IncRef ();
00255     return true;
00256   }
00257   virtual bool FreeItem (csSome Item)
00258   {
00259     ((iBase*)Item)->DecRef ();
00260     return true;
00261   }
00262   inline csSome Pop ()
00263   {
00264     // Items that are removed with Pop() should not be DecRef'ed. To keep
00265     // the code simple, we just IncRef them before.
00266     csSome item = Top ();
00267     ((iBase*)item)->IncRef ();
00268 
00269     if (FreeItem (item)) {
00270       // We also have to bypass csRestrictedAccessVector::Pop ().
00271       return csVector::Pop ();
00272     } else {
00273       // Removal failed, so we have to release our reference again.
00274       ((iBase*)item)->DecRef ();
00275       return NULL;
00276     }
00277   }
00278 };
00279 
00280 /*
00281  * This is a helper macro for typed vectors. It defines all methods that are
00282  * valid for usual typed vectors and typed SCF vectors. This basically
00283  * excludes all methods that have a 'DeleteIt' parameter for
00284  * usual typed vectors and methods that return 'insecure' references. <p>
00285  *
00286  * This macro assumes that the type 'superclass' is defined to the superclass
00287  * of the typed vector.
00288  */
00289 #define CS_PRIVATE_DECLARE_TYPED_VECTOR_HELPER(NAME,TYPE)               \
00290     inline NAME (int ilimit = 16, int ithreshold = 16) :                \
00291       superclass (ilimit, ithreshold) {}                                \
00292     virtual ~NAME ()                                                    \
00293     { DeleteAll (); }                                                   \
00294     inline void SetLength (int n)                                       \
00295     { superclass::SetLength(n); }                                       \
00296     inline int Length () const                                          \
00297     { return count; }                                                   \
00298     inline int Limit () const                                           \
00299     { return limit; }                                                   \
00300     inline void Exchange (int n1, int n2)                               \
00301     { superclass::Exchange (n1, n2); }                                  \
00302     inline void QuickSort (int Left, int Right, int Mode = 0)           \
00303     { superclass::QuickSort (Left, Right, Mode); }                      \
00304     inline void QuickSort (int Mode = 0)                                \
00305     { superclass::QuickSort (Mode); }                                   \
00306     inline int Find (TYPE *which) const                                 \
00307     { return superclass::Find ((csSome)which); }                        \
00308     inline int FindKey (csConstSome Key, int Mode = 0) const            \
00309     { return superclass::FindKey (Key, Mode); }                         \
00310     inline int FindSortedKey (csConstSome Key, int Mode = 0) const      \
00311     { return superclass::FindSortedKey (Key, Mode); }                   \
00312     inline int Push (TYPE *obj)                                         \
00313     { return superclass::Push ((csSome)obj); }                          \
00314     inline int PushSmart (TYPE *obj)                                    \
00315     { return superclass::PushSmart ((csSome)obj); }                     \
00316     inline TYPE *Pop ()                                                 \
00317     { return (TYPE *)superclass::Pop(); }                               \
00318     inline TYPE *Top () const                                           \
00319     { return (TYPE *)superclass::Top(); }                               \
00320     inline bool Insert (int n, TYPE *Item)                              \
00321     { return superclass::Insert (n, (csSome)Item); }                    \
00322     inline int InsertSorted (TYPE *Item, int *oEqual = NULL, int Mode = 0) \
00323     { return superclass::InsertSorted ((csSome)Item, oEqual, Mode); }
00324 
00325 /*
00326  * Declares a new vector type NAME as a subclass of csVector.
00327  * Elements of this vector are of type TYPE. The elements are
00328  * automatically given to FreeTypedItem() on either Delete() or
00329  * DeleteAll() or upon vector destruction. However, you must define
00330  * FreeTypedItem() yourself. <p>
00331  *
00332  * Be careful with user-defined methods in typed vectors. Though the
00333  * vectors are type-safe to the outside, it is still possible to access
00334  * csVector members (type-unsafe!) from the inside, i.e. from your own methods.
00335  *
00336  * Usage (all features):
00337  *   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME, TYPE)
00338  *     user-defined FreeTypedItem() here
00339  *     any other user-defined methods
00340  *   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00341  *
00342  * or (no user-defined members, contained objects are correctly deleted):
00343  *   CS_PRIVATE_DECLARE_TYPED_VECTOR (NAME, TYPE)
00344  *
00345  * or (no user-defined members, contained objects are not deleted):
00346  *   CS_PRIVATE_DECLARE_TYPED_VECTOR_NODELETE (NAME, TYPE)
00347  *
00348  * or (no user-defined members, user has to define FreeTypedItem):
00349  *   CS_PRIVATE_DECLARE_TYPED_VECTOR_NODELETE (NAME, TYPE)
00350  *
00351  * Parameters:
00352  *   NAME - Name of the new vector class.
00353  *   TYPE - Data type to which this vector refer.
00354  *          The TYPE should be possible to cast to (void *) and back.
00355  */
00356 #define CS_PRIVATE_BEGIN_TYPED_VECTOR(NAME,TYPE)                        \
00357   class NAME : private csVector                                         \
00358   {                                                                     \
00359     typedef csVector superclass;                                        \
00360   public:                                                               \
00361     inline bool Delete (int n, bool FreeIt = true)                      \
00362     { return superclass::Delete (n, FreeIt); }                          \
00363     inline bool Delete (TYPE *Item, bool FreeIt = true)                 \
00364     { return superclass::Delete ((csSome)Item, FreeIt); }               \
00365     inline void DeleteAll (bool FreeThem = true)                        \
00366     { superclass::DeleteAll (FreeThem); }                               \
00367     CS_PRIVATE_DECLARE_TYPED_VECTOR_HELPER (NAME, TYPE)                 \
00368     inline TYPE *& operator [] (int n)                                  \
00369     { return (TYPE *&)superclass::operator [] (n); }                    \
00370     inline TYPE *& operator [] (int n) const                            \
00371     { return (TYPE *&)superclass::operator [] (n); }                    \
00372     inline TYPE *& Get (int n) const                                    \
00373     { return (TYPE *&)superclass::Get(n); }                             \
00374     inline TYPE **GetArray ()                                           \
00375     { return (TYPE**)root; }                                            \
00376     inline bool Replace (int n, TYPE *what, bool FreePrevious = true)   \
00377     { return superclass::Replace(n, (csSome)what, FreePrevious); }
00378 
00379 // Finish the class definition of a typed vector
00380 #define CS_PRIVATE_FINISH_TYPED_VECTOR(TYPE)                            \
00381     virtual bool FreeItem (csSome Item)                                 \
00382     { return FreeTypedItem ((TYPE *)Item); }                            \
00383   }
00384 
00385 /*
00386  * Declares a new vector type NAME as a subclass of csVector. Elements
00387  * of this vector are of type TYPE. The elements are automatically deleted
00388  * on either Delete() or DeleteAll() or upon vector destruction.
00389  */
00390 #define CS_PRIVATE_DECLARE_TYPED_VECTOR(NAME,TYPE)                      \
00391   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME,TYPE)                             \
00392     inline bool FreeTypedItem (TYPE* obj)                               \
00393     { delete obj; return true; }                                        \
00394   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00395 
00400 #define CS_PRIVATE_DECLARE_TYPED_VECTOR_NODELETE(NAME,TYPE)             \
00401   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME,TYPE)                             \
00402     inline bool FreeTypedItem (TYPE*)                                   \
00403     { return true; }                                                    \
00404   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00405 
00410 #define CS_PRIVATE_DECLARE_TYPED_VECTOR_USERDELETE(NAME,TYPE)           \
00411   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME,TYPE)                             \
00412     bool FreeTypedItem (TYPE*);                                         \
00413   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00414 
00415 #define CS_PRIVATE_DECLARE_TYPED_VECTOR_DECREF(NAME,TYPE)  \
00416   CS_PRIVATE_BEGIN_TYPED_VECTOR (NAME,TYPE)                \
00417     inline bool FreeTypedItem (TYPE *Item)                 \
00418     { Item->DecRef(); Item = NULL; return true; }          \
00419   CS_PRIVATE_FINISH_TYPED_VECTOR (TYPE)
00420 
00426 #define CS_PRIVATE_DECLARE_TYPED_RESTR_ACC_VECTOR(NAME,TYPE,sclass)     \
00427   class NAME : private sclass                                           \
00428   {                                                                     \
00429   protected:                                                            \
00430     typedef sclass superclass;                                          \
00431     virtual bool PrepareItem (csSome item)                              \
00432     { return superclass::PrepareItem (item); }                          \
00433     virtual bool FreeItem (csSome item)                                 \
00434     { return superclass::FreeItem (item); }                             \
00435   public:                                                               \
00436     inline bool Delete (int n)                                          \
00437     { return superclass::Delete (n); }                                  \
00438     inline bool Delete (TYPE *Item)                                     \
00439     { return superclass::Delete ((csSome)Item); }                       \
00440     inline void DeleteAll ()                                            \
00441     { superclass::DeleteAll (); }                                       \
00442     CS_PRIVATE_DECLARE_TYPED_VECTOR_HELPER (NAME, TYPE)                 \
00443     inline TYPE *operator [] (int n) const                              \
00444     { return (TYPE *)superclass::operator [] (n); }                     \
00445     inline TYPE *Get (int n) const                                      \
00446     { return (TYPE *)superclass::Get(n); }                              \
00447     inline bool Replace (int n, TYPE *what)                             \
00448     { return superclass::Replace(n, (csSome)what); }                    \
00449   }
00450 
00451 #define CS_PRIVATE_DECLARE_TYPED_RESTRICTED_ACCESS_VECTOR(NAME,TYPE)    \
00452   CS_PRIVATE_DECLARE_TYPED_RESTR_ACC_VECTOR (NAME, TYPE, csRestrictedAccessVector)
00453 
00454 #define CS_PRIVATE_DECLARE_TYPED_IBASE_VECTOR(NAME,TYPE)                \
00455   CS_PRIVATE_DECLARE_TYPED_RESTR_ACC_VECTOR (NAME, TYPE, csIBaseVector)
00456   
00457 /*
00458  * This is a special version of typed vectors that contain SCF objects. The
00459  * vector will correctly IncRef all added objects and DecRef all removed
00460  * objects. There is only one exeption: The Pop() function does not DecRef
00461  * the object, so you should do that yourself. The reason is that at the time
00462  * you call Pop(), you do usually not have a pointer to the object, so you can
00463  * not IncRef() it before. <p>
00464  *
00465  * Usage:
00466  *   CS_PRIVATE_DECLARE_TYPED_RESTR_ACC_VECTOR (superclass, NAME, TYPE)
00467  *
00468  * Parameters:
00469  *   superclass - The parent class. May be either csIBaseVector or
00470  *                csRestrictedAccessVector.
00471  *   NAME - Name of the new vector class.
00472  *   TYPE - Data type to which this vector refer.
00473  *          The TYPE should be possible to cast to (void *) and back.
00474  */
00475 
00476 #define CS_PRIVATE_IMPLEMENT_TYPED_VECTOR_DELETE(NAME,TYPE)             \
00477   bool NAME::FreeTypedItem (TYPE *Item)                                 \
00478   { delete Item; return true; }
00479 
00480 #define CS_PRIVATE_BEGIN_USER_VECTOR(MACRO,NAME,TYPE)                   \
00481   MACRO (NAME##_Helper, TYPE);                                          \
00482   class NAME : public NAME##_Helper                                     \
00483   {                                                                     \
00484   public:
00485 
00486 #define CS_PRIVATE_FINISH_USER_VECTOR                                   \
00487   }
00488 
00489 #define CS_PRIVATE_TYPED_VECTOR_CONSTRUCTOR(NAME)                       \
00490   NAME (int ilimit = 8, int ithreshold = 16) :                          \
00491     NAME##_Helper (ilimit, ithreshold) {}
00492 
00493 #endif // __TYPEDVEC_H__

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