|
typedvec.h00001 /* 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 |