ratl_common.h 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  1. ////////////////////////////////////////////////////////////////////////////////////////
  2. // RAVEN STANDARD TEMPLATE LIBRARY
  3. // (c) 2002 Activision
  4. //
  5. //
  6. // Common
  7. // ------
  8. // The raven libraries contain a number of common defines, enums, and typedefs which
  9. // need to be accessed by all templates. Each of these is included here.
  10. //
  11. // Also included is a safeguarded assert file for all the asserts in RTL.
  12. //
  13. // This file is included in EVERY TEMPLATE, so it should be very light in order to
  14. // reduce compile times.
  15. //
  16. //
  17. // Format
  18. // ------
  19. // In order to simplify code and provide readability, the template library has some
  20. // standard formats. Any new templates or functions should adhere to these formats:
  21. //
  22. // - All memory is statically allocated, usually by parameter SIZE
  23. // - All classes provide an enum which defines constant variables, including CAPACITY
  24. // - All classes which moniter the number of items allocated provide the following functions:
  25. // size() - the number of objects
  26. // empty() - does the container have zero objects
  27. // full() - does the container have any room left for more objects
  28. // clear() - remove all objects
  29. //
  30. //
  31. // - Functions are defined in the following order:
  32. // Capacity
  33. // Constructors (copy, from string, etc...)
  34. // Range (size(), empty(), full(), clear(), etc...)
  35. // Access (operator[], front(), back(), etc...)
  36. // Modification (add(), remove(), push(), pop(), etc...)
  37. // Iteration (begin(), end(), insert(), erase(), find(), etc...)
  38. //
  39. //
  40. // NOTES:
  41. //
  42. //
  43. //
  44. ////////////////////////////////////////////////////////////////////////////////////////
  45. #if !defined(RATL_COMMON_INC)
  46. #define RATL_COMMON_INC
  47. ////////////////////////////////////////////////////////////////////////////////////////
  48. // In VC++, Don't Bother With These Warnings
  49. ////////////////////////////////////////////////////////////////////////////////////////
  50. #if defined(_MSC_VER) && !defined(__MWERKS__)
  51. #pragma warning ( disable : 4786 ) // Truncated to 255 characters warning
  52. #pragma warning ( disable : 4284 ) // nevamind what this is
  53. #pragma warning ( disable : 4100 ) // unreferenced formal parameter
  54. #pragma warning ( disable : 4512 ) // unable to generate default operator=
  55. #pragma warning ( disable : 4130 ) // logical operation on address of string constant
  56. #pragma warning ( disable : 4127 ) // conditional expression is constant
  57. #endif
  58. ////////////////////////////////////////////////////////////////////////////////////////
  59. // Includes
  60. ////////////////////////////////////////////////////////////////////////////////////////
  61. #if !defined(ASSERT_H_INC)
  62. #include <assert.h>
  63. #define ASSERT_H_INC
  64. #endif
  65. #if !defined(STRING_H_INC)
  66. #include <string.h>
  67. #define STRING_H_INC
  68. #endif
  69. ////////////////////////////////////////////////////////////////////////////////////////
  70. // Forward Dec.
  71. ////////////////////////////////////////////////////////////////////////////////////////
  72. class hfile;
  73. // I don't know why this needs to be in the global namespace, but it does
  74. class TRatlNew;
  75. inline void *operator new(size_t,TRatlNew *where)
  76. {
  77. return where;
  78. }
  79. inline void operator delete(void *, TRatlNew *)
  80. {
  81. return;
  82. }
  83. namespace ratl
  84. {
  85. #ifdef _DEBUG
  86. extern int HandleSaltValue; //this is used in debug for global uniqueness of handles
  87. extern int FoolTheOptimizer; //this is used to make sure certain things aren't optimized out
  88. #endif
  89. ////////////////////////////////////////////////////////////////////////////////////////
  90. // All Raven Template Library Internal Memory Operations
  91. //
  92. // This is mostly for future use. For now, they only provide a simple interface with
  93. // a couple extra functions (eql and clr).
  94. ////////////////////////////////////////////////////////////////////////////////////////
  95. namespace mem
  96. {
  97. ////////////////////////////////////////////////////////////////////////////////////////
  98. // The Align Struct Is The Root Memory Structure for Inheritance and Object Semantics
  99. //
  100. // In most cases, we just want a simple int. However, sometimes we need to use an
  101. // unsigned character array
  102. //
  103. ////////////////////////////////////////////////////////////////////////////////////////
  104. #if defined(_MSC_VER) && !defined(__MWERKS__)
  105. struct alignStruct
  106. {
  107. int space;
  108. };
  109. #else
  110. struct alignStruct
  111. {
  112. unsigned char space[16];
  113. } __attribute__ ((aligned(16)));
  114. #endif
  115. inline void* cpy( void *dest, const void *src, size_t count )
  116. {
  117. return memcpy(dest, src, count);
  118. }
  119. inline void* set( void *dest, int c, size_t count )
  120. {
  121. return memset(dest, c, count);
  122. }
  123. inline int cmp( const void *buf1, const void *buf2, size_t count )
  124. {
  125. return memcmp( buf1, buf2, count );
  126. }
  127. inline bool eql( const void *buf1, const void *buf2, size_t count )
  128. {
  129. return (memcmp( buf1, buf2, count )==0);
  130. }
  131. inline void* zero( void *dest, size_t count )
  132. {
  133. return memset(dest, 0, count);
  134. }
  135. template<class T>
  136. inline void cpy( T *dest, const T *src)
  137. {
  138. cpy(dest, src, sizeof(T));
  139. }
  140. template<class T>
  141. inline void set(T *dest, int c)
  142. {
  143. set(dest, c, sizeof(T));
  144. }
  145. template<class T>
  146. inline void swap(T *s1, T *s2)
  147. {
  148. unsigned char temp[sizeof(T)];
  149. cpy((T *)temp,s1);
  150. cpy(s1,s2);
  151. cpy(s2,(T *)temp);
  152. }
  153. template<class T>
  154. inline int cmp( const T *buf1, const T *buf2)
  155. {
  156. return cmp( buf1, buf2, sizeof(T) );
  157. }
  158. template<class T>
  159. inline bool eql( const T *buf1, const T *buf2)
  160. {
  161. return cmp( buf1, buf2,sizeof(T))==0;
  162. }
  163. template<class T>
  164. inline void zero( T *dest )
  165. {
  166. return set(dest, 0, sizeof(T));
  167. }
  168. }
  169. namespace str
  170. {
  171. inline int len(const char *src)
  172. {
  173. return strlen(src);
  174. }
  175. inline void cpy(char *dest,const char *src)
  176. {
  177. strcpy(dest,src);
  178. }
  179. inline void ncpy(char *dest,const char *src,int destBufferLen)
  180. {
  181. strncpy(dest,src,destBufferLen);
  182. }
  183. inline void cat(char *dest,const char *src)
  184. {
  185. strcat(dest,src);
  186. }
  187. inline void ncat(char *dest,const char *src,int destBufferLen)
  188. {
  189. ncpy(dest+len(dest),src,destBufferLen-len(dest));
  190. }
  191. inline int cmp(const char *s1,const char *s2)
  192. {
  193. return strcmp(s1,s2);
  194. }
  195. inline bool eql(const char *s1,const char *s2)
  196. {
  197. return !strcmp(s1,s2);
  198. }
  199. inline int icmp(const char *s1,const char *s2)
  200. {
  201. return stricmp(s1,s2);
  202. }
  203. inline int cmpi(const char *s1,const char *s2)
  204. {
  205. return stricmp(s1,s2);
  206. }
  207. inline bool ieql(const char *s1,const char *s2)
  208. {
  209. return !stricmp(s1,s2);
  210. }
  211. inline bool eqli(const char *s1,const char *s2)
  212. {
  213. return !stricmp(s1,s2);
  214. }
  215. inline char *tok(char *s,const char *gap)
  216. {
  217. return strtok(s,gap);
  218. }
  219. void to_upper(char *dest);
  220. void to_lower(char *dest);
  221. void printf(char *dest,const char *formatS, ...);
  222. }
  223. ////////////////////////////////////////////////////////////////////////////////////////
  224. // The Raven Template Library Compile Assert
  225. //
  226. // If, during compile time the stuff under (condition) is zero, this code will not
  227. // compile.
  228. ////////////////////////////////////////////////////////////////////////////////////////
  229. template<int condition>
  230. class compile_assert
  231. {
  232. #ifdef _DEBUG
  233. int junk[(1 - (2 * !condition))]; // Look At Where This Was Being Compiled
  234. public:
  235. compile_assert()
  236. {
  237. assert(condition);
  238. junk[0]=FoolTheOptimizer++;
  239. }
  240. int operator()()
  241. {
  242. assert(condition);
  243. FoolTheOptimizer++;
  244. return junk[0];
  245. }
  246. #else
  247. public:
  248. int operator()()
  249. {
  250. return 1;
  251. }
  252. #endif;
  253. };
  254. ////////////////////////////////////////////////////////////////////////////////////////
  255. // The Raven Template Library Base Class
  256. //
  257. // This is the base class for all the Raven Template Library container classes like
  258. // vector_vs and pool_vs.
  259. //
  260. // This class might be a good place to put memory profile code in the future.
  261. //
  262. ////////////////////////////////////////////////////////////////////////////////////////
  263. class ratl_base
  264. {
  265. public:
  266. #ifndef _XBOX
  267. void save(hfile& file);
  268. void load(hfile& file);
  269. #endif
  270. void ProfilePrint(const char * format, ...);
  271. public:
  272. static void* OutputPrint;
  273. };
  274. ////////////////////////////////////////////////////////////////////////////////////////
  275. // this is a simplified version of bits_vs
  276. ////////////////////////////////////////////////////////////////////////////////////////
  277. template <int SZ>
  278. class bits_base
  279. {
  280. protected:
  281. enum
  282. {
  283. BITS_SHIFT = 5, // 5. Such A Nice Number
  284. BITS_INT_SIZE = 32, // Size Of A Single Word
  285. BITS_AND = (BITS_INT_SIZE - 1), // Used For And Operation
  286. ARRAY_SIZE = ((SZ + BITS_AND)/(BITS_INT_SIZE)), // Num Words Used
  287. BYTE_SIZE = (ARRAY_SIZE*sizeof(unsigned int)), // Num Bytes Used
  288. };
  289. ////////////////////////////////////////////////////////////////////////////////////
  290. // Data
  291. ////////////////////////////////////////////////////////////////////////////////////
  292. unsigned int mV[ARRAY_SIZE];
  293. public:
  294. enum
  295. {
  296. SIZE = SZ,
  297. CAPACITY = SZ,
  298. };
  299. bits_base(bool init=true,bool initValue=false)
  300. {
  301. if (init)
  302. {
  303. if (initValue)
  304. {
  305. set();
  306. }
  307. else
  308. {
  309. clear();
  310. }
  311. }
  312. }
  313. void clear()
  314. {
  315. mem::zero(&mV,BYTE_SIZE);
  316. }
  317. void set()
  318. {
  319. mem::set(&mV, 0xff,BYTE_SIZE);
  320. }
  321. void set_bit(const int i)
  322. {
  323. assert(i>=0 && i < SIZE);
  324. mV[i>>BITS_SHIFT] |= (1<<(i&BITS_AND));
  325. }
  326. void clear_bit(const int i)
  327. {
  328. assert(i>=0 && i < SIZE);
  329. mV[i>>BITS_SHIFT] &= ~(1<<(i&BITS_AND));
  330. }
  331. void mark_bit(const int i, bool set)
  332. {
  333. assert(i>=0 && i < SIZE);
  334. if (set)
  335. {
  336. mV[i>>BITS_SHIFT] |= (1<<(i&BITS_AND));
  337. }
  338. else
  339. {
  340. mV[i>>BITS_SHIFT] &= ~(1<<(i&BITS_AND));
  341. }
  342. }
  343. bool operator[](const int i) const
  344. {
  345. assert(i>=0 && i < SIZE);
  346. return (mV[i>>BITS_SHIFT] & (1<<(i&BITS_AND)))!=0;
  347. }
  348. int next_bit(int start=0,bool onBit=true) const
  349. {
  350. assert(start>=0&&start<=SIZE); //we have to accept start==size for the way the loops are done
  351. if (start>=SIZE)
  352. {
  353. return SIZE; // Did Not Find
  354. }
  355. // Get The Word Which Contains The Start Bit & Mask Out Everything Before The Start Bit
  356. //--------------------------------------------------------------------------------------
  357. unsigned int v = mV[start>>BITS_SHIFT];
  358. if (!onBit)
  359. {
  360. v= (~v);
  361. }
  362. v >>= (start&31);
  363. // Search For The First Non Zero Word In The Array
  364. //-------------------------------------------------
  365. while(!v)
  366. {
  367. start = (start & (~(BITS_INT_SIZE-1))) + BITS_INT_SIZE;
  368. if (start>=SIZE)
  369. {
  370. return SIZE; // Did Not Find
  371. }
  372. v = mV[start>>BITS_SHIFT];
  373. if (!onBit)
  374. {
  375. v= (~v);
  376. }
  377. }
  378. // So, We've Found A Non Zero Word, So Start Masking Against Parts To Skip Over Bits
  379. //-----------------------------------------------------------------------------------
  380. if (!(v&0xffff))
  381. {
  382. start+=16;
  383. v>>=16;
  384. }
  385. if (!(v&0xff))
  386. {
  387. start+=8;
  388. v>>=8;
  389. }
  390. if (!(v&0xf))
  391. {
  392. start+=4;
  393. v>>=4;
  394. }
  395. // Time To Search Each Bit
  396. //-------------------------
  397. while(!(v&1))
  398. {
  399. start++;
  400. v>>=1;
  401. }
  402. if (start>=SIZE)
  403. {
  404. return SIZE;
  405. }
  406. return start;
  407. }
  408. };
  409. ////////////////////////////////////////////////////////////////////////////////////////
  410. // Raven Standard Compare Class
  411. ////////////////////////////////////////////////////////////////////////////////////////
  412. struct ratl_compare
  413. {
  414. float mCost;
  415. int mHandle;
  416. bool operator<(const ratl_compare& t) const
  417. {
  418. return (mCost<t.mCost);
  419. }
  420. };
  421. ////////////////////////////////////////////////////////////////////////////////////////
  422. // this is used to keep track of the constuction state for things that are always constucted
  423. ////////////////////////////////////////////////////////////////////////////////////////
  424. class bits_true
  425. {
  426. public:
  427. void clear()
  428. {
  429. }
  430. void set()
  431. {
  432. }
  433. void set_bit(const int i)
  434. {
  435. }
  436. void clear_bit(const int i)
  437. {
  438. }
  439. bool operator[](const int i) const
  440. {
  441. return true;
  442. }
  443. int next_bit(int start=0,bool onBit=true) const
  444. {
  445. assert(onBit); ///I didn't want to add the sz template arg, you could though
  446. return start;
  447. }
  448. };
  449. namespace storage
  450. {
  451. template<class T,int SIZE>
  452. struct value_semantics
  453. {
  454. enum
  455. {
  456. CAPACITY = SIZE,
  457. };
  458. typedef T TAlign; // this is any type that has the right alignment
  459. typedef T TValue; // this is the actual thing the user uses
  460. typedef T TStorage; // this is what we make our array of
  461. typedef bits_true TConstructed;
  462. typedef TStorage TArray[SIZE];
  463. enum
  464. {
  465. NEEDS_CONSTRUCT=0,
  466. TOTAL_SIZE=sizeof(TStorage),
  467. VALUE_SIZE=sizeof(TStorage),
  468. };
  469. static void construct(TStorage *)
  470. {
  471. }
  472. static void construct(TStorage *me,const TValue &v)
  473. {
  474. *me=v;
  475. }
  476. static void destruct(TStorage *)
  477. {
  478. }
  479. static TRatlNew *raw(TStorage *me)
  480. {
  481. return (TRatlNew *)me;
  482. }
  483. static T * ptr(TStorage *me)
  484. {
  485. return me;
  486. }
  487. static const T * ptr(const TStorage *me)
  488. {
  489. return me;
  490. }
  491. static T & ref(TStorage *me)
  492. {
  493. return *me;
  494. }
  495. static const T & ref(const TStorage *me)
  496. {
  497. return *me;
  498. }
  499. static T *raw_array(TStorage *me)
  500. {
  501. return me;
  502. }
  503. static const T *raw_array(const TStorage *me)
  504. {
  505. return me;
  506. }
  507. static void swap(TStorage *s1,TStorage *s2)
  508. {
  509. mem::swap(ptr(s1),ptr(s2));
  510. }
  511. static int pointer_to_index(const void *s1,const void *s2)
  512. {
  513. return ((TStorage *)s1)-((TStorage *)s2);
  514. }
  515. };
  516. template<class T,int SIZE>
  517. struct object_semantics
  518. {
  519. enum
  520. {
  521. CAPACITY = SIZE,
  522. };
  523. typedef mem::alignStruct TAlign; // this is any type that has the right alignment
  524. typedef T TValue; // this is the actual thing the user uses
  525. typedef bits_base<SIZE> TConstructed;
  526. struct TStorage
  527. {
  528. TAlign mMemory[((sizeof(T) + sizeof(TAlign) -1 )/sizeof(TAlign))];
  529. };
  530. typedef TStorage TArray[SIZE];
  531. enum
  532. {
  533. NEEDS_CONSTRUCT=1,
  534. TOTAL_SIZE=sizeof(TStorage),
  535. VALUE_SIZE=sizeof(TStorage),
  536. };
  537. static void construct(TStorage *me)
  538. {
  539. new(raw(me)) TValue();
  540. }
  541. static void construct(TStorage *me,const TValue &v)
  542. {
  543. new(raw(me)) TValue(v);
  544. }
  545. static void destruct(TStorage *me)
  546. {
  547. ptr(me)->~T();
  548. }
  549. static TRatlNew *raw(TStorage *me)
  550. {
  551. return (TRatlNew *)me;
  552. }
  553. static T * ptr(TStorage *me)
  554. {
  555. return (T *)me;
  556. }
  557. static const T * ptr(const TStorage *me)
  558. {
  559. return (const T *)me;
  560. }
  561. static T & ref(TStorage *me)
  562. {
  563. return *(T *)me;
  564. }
  565. static const T & ref(const TStorage *me)
  566. {
  567. return *(const T *)me;
  568. }
  569. static void swap(TStorage *s1,TStorage *s2)
  570. {
  571. TValue temp(ref(s1));
  572. ref(s1)=ref(s2);
  573. ref(s2)=temp;
  574. }
  575. static int pointer_to_index(const void *s1,const void *s2)
  576. {
  577. return ((TStorage *)s1)-((TStorage *)s2);
  578. }
  579. };
  580. template<class T,int SIZE,int MAX_CLASS_SIZE>
  581. struct virtual_semantics
  582. {
  583. enum
  584. {
  585. CAPACITY = SIZE,
  586. };
  587. typedef mem::alignStruct TAlign; // this is any type that has the right alignment
  588. typedef T TValue; // this is the actual thing the user uses
  589. typedef bits_base<SIZE> TConstructed;
  590. struct TStorage
  591. {
  592. TAlign mMemory[((MAX_CLASS_SIZE + sizeof(TAlign) -1 )/sizeof(TAlign))];
  593. };
  594. typedef TStorage TArray[SIZE];
  595. enum
  596. {
  597. NEEDS_CONSTRUCT=1,
  598. TOTAL_SIZE=sizeof(TStorage),
  599. VALUE_SIZE=MAX_CLASS_SIZE,
  600. };
  601. static void construct(TStorage *me)
  602. {
  603. new(raw(me)) TValue();
  604. }
  605. static void destruct(TStorage *me)
  606. {
  607. ptr(me)->~T();
  608. }
  609. static TRatlNew *raw(TStorage *me)
  610. {
  611. return (TRatlNew *)me;
  612. }
  613. static T * ptr(TStorage *me)
  614. {
  615. return (T *)me;
  616. }
  617. static const T * ptr(const TStorage *me)
  618. {
  619. return (const T *)me;
  620. }
  621. static T & ref(TStorage *me)
  622. {
  623. return *(T *)me;
  624. }
  625. static const T & ref(const TStorage *me)
  626. {
  627. return *(const T *)me;
  628. }
  629. // this is a bit suspicious, we are forced to do a memory swap, and for a class, that, say
  630. // stores a pointer to itself, it won't work right
  631. static void swap(TStorage *s1,TStorage *s2)
  632. {
  633. mem::swap(s1,s2);
  634. }
  635. static int pointer_to_index(const void *s1,const void *s2)
  636. {
  637. return ((TStorage *)s1)-((TStorage *)s2);
  638. }
  639. template<class CAST_TO>
  640. static CAST_TO *verify_alloc(CAST_TO *p)
  641. {
  642. #ifdef _DEBUG
  643. assert(p);
  644. assert(dynamic_cast<const T *>(p));
  645. T *ptr=p; // if this doesn't compile, you are trying to alloc something that is not derived from base
  646. assert(dynamic_cast<const CAST_TO *>(ptr));
  647. int i=VALUE_SIZE;
  648. int k=MAX_CLASS_SIZE;
  649. int j=sizeof(CAST_TO);
  650. compile_assert<sizeof(CAST_TO)<=MAX_CLASS_SIZE>();
  651. assert(sizeof(CAST_TO)<=MAX_CLASS_SIZE);
  652. #endif
  653. return p;
  654. }
  655. };
  656. // The below versions are for nodes
  657. template<class T,int SIZE,class NODE>
  658. struct value_semantics_node
  659. {
  660. enum
  661. {
  662. CAPACITY = SIZE,
  663. };
  664. struct SNode
  665. {
  666. NODE nodeData;
  667. T value;
  668. };
  669. typedef SNode TAlign; // this is any type that has the right alignment
  670. typedef T TValue; // this is the actual thing the user uses
  671. typedef SNode TStorage; // this is what we make our array of
  672. typedef bits_true TConstructed;
  673. typedef TStorage TArray[SIZE];
  674. enum
  675. {
  676. NEEDS_CONSTRUCT=0,
  677. TOTAL_SIZE=sizeof(TStorage),
  678. VALUE_SIZE=sizeof(TValue),
  679. };
  680. static void construct(TStorage *)
  681. {
  682. }
  683. static void construct(TStorage *me,const TValue &v)
  684. {
  685. me->value=v;
  686. }
  687. static void destruct(TStorage *)
  688. {
  689. }
  690. static TRatlNew *raw(TStorage *me)
  691. {
  692. return (TRatlNew *)&me->value;
  693. }
  694. static T * ptr(TStorage *me)
  695. {
  696. return &me->value;
  697. }
  698. static const T * ptr(const TStorage *me)
  699. {
  700. return &me->value;
  701. }
  702. static T & ref(TStorage *me)
  703. {
  704. return me->value;
  705. }
  706. static const T & ref(const TStorage *me)
  707. {
  708. return me->value;
  709. }
  710. // this ugly unsafe cast-hack is a backhanded way of getting the node data from the value data
  711. // this is so node support does not need to be added to the primitive containers
  712. static NODE & node(TValue &v)
  713. {
  714. return *(NODE *)((unsigned char *)(&v)+int(&((TStorage *)0)->nodeData)-int(&((TStorage *)0)->value));
  715. }
  716. static const NODE & node(const TValue &v)
  717. {
  718. return *(const NODE *)((unsigned char *)(&v)+int(&((TStorage *)0)->nodeData)-int(&((TStorage *)0)->value));
  719. }
  720. static void swap(TStorage *s1,TStorage *s2)
  721. {
  722. mem::swap(&s1->value,&s2->value);
  723. }
  724. // this is hideous
  725. static int pointer_to_index(const void *s1,const void *s2)
  726. {
  727. return
  728. ((TStorage *)(((unsigned char *)s1)-int(&((TStorage *)0)->value))) -
  729. ((TStorage *)(((unsigned char *)s2)-int(&((TStorage *)0)->value)));
  730. }
  731. };
  732. template<class T,int SIZE,class NODE>
  733. struct object_semantics_node
  734. {
  735. enum
  736. {
  737. CAPACITY = SIZE,
  738. };
  739. typedef mem::alignStruct TAlign; // this is any type that has the right alignment
  740. typedef T TValue; // this is the actual thing the user uses
  741. typedef bits_base<SIZE> TConstructed;
  742. struct TValueStorage
  743. {
  744. TAlign mMemory[((sizeof(T) + sizeof(TAlign) -1 )/sizeof(TAlign))];
  745. };
  746. struct SNode
  747. {
  748. NODE nodeData;
  749. TValueStorage value;
  750. };
  751. typedef SNode TStorage; // this is what we make our array of
  752. typedef TStorage TArray[SIZE];
  753. enum
  754. {
  755. NEEDS_CONSTRUCT=0,
  756. TOTAL_SIZE=sizeof(TStorage),
  757. VALUE_SIZE=sizeof(TValueStorage),
  758. };
  759. static void construct(TStorage *me)
  760. {
  761. new(raw(me)) TValue();
  762. }
  763. static void construct(TStorage *me,const TValue &v)
  764. {
  765. new(raw(me)) TValue(v);
  766. }
  767. static void destruct(TStorage *me)
  768. {
  769. ptr(me)->~T();
  770. }
  771. static TRatlNew *raw(TStorage *me)
  772. {
  773. return (TRatlNew *)&me->value;
  774. }
  775. static T * ptr(TStorage *me)
  776. {
  777. return (T *)&me->value;
  778. }
  779. static const T * ptr(const TStorage *me)
  780. {
  781. return (const T *)&me->value;
  782. }
  783. static T & ref(TStorage *me)
  784. {
  785. return *(T *)&me->value;
  786. }
  787. static const T & ref(const TStorage *me)
  788. {
  789. return *(const T *)&me->value;
  790. }
  791. static NODE & node(TStorage *me)
  792. {
  793. return me->nodeData;
  794. }
  795. static const NODE & node(const TStorage *me)
  796. {
  797. return me->nodeData;
  798. }
  799. // this ugly unsafe cast-hack is a backhanded way of getting the node data from the value data
  800. // this is so node support does not need to be added to the primitive containers
  801. static NODE & node(TValue &v)
  802. {
  803. return *(NODE *)((unsigned char *)(&v)+int(&((TStorage *)0)->nodeData)-int(&((TStorage *)0)->value));
  804. }
  805. static const NODE & node(const TValue &v)
  806. {
  807. return *(const NODE *)((unsigned char *)(&v)+int(&((TStorage *)0)->nodeData)-int(&((TStorage *)0)->value));
  808. }
  809. static void swap(TStorage *s1,TStorage *s2)
  810. {
  811. TValue temp(ref(s1));
  812. ref(s1)=ref(s2);
  813. ref(s2)=temp;
  814. }
  815. // this is hideous
  816. static int pointer_to_index(const void *s1,const void *s2)
  817. {
  818. return
  819. ((TStorage *)(((unsigned char *)s1)-int(&((TStorage *)0)->value))) -
  820. ((TStorage *)(((unsigned char *)s2)-int(&((TStorage *)0)->value)));
  821. }
  822. };
  823. template<class T,int SIZE,int MAX_CLASS_SIZE,class NODE>
  824. struct virtual_semantics_node
  825. {
  826. enum
  827. {
  828. CAPACITY = SIZE,
  829. };
  830. typedef mem::alignStruct TAlign; // this is any type that has the right alignment
  831. typedef T TValue; // this is the actual thing the user uses
  832. typedef bits_base<SIZE> TConstructed;
  833. struct TValueStorage
  834. {
  835. TAlign mMemory[((MAX_CLASS_SIZE + sizeof(TAlign) -1 )/sizeof(TAlign))];
  836. };
  837. struct SNode
  838. {
  839. NODE nodeData;
  840. TValueStorage value;
  841. };
  842. typedef SNode TStorage; // this is what we make our array of
  843. typedef TStorage TArray[SIZE];
  844. enum
  845. {
  846. NEEDS_CONSTRUCT=1,
  847. TOTAL_SIZE=sizeof(TStorage),
  848. VALUE_SIZE=sizeof(TValueStorage),
  849. };
  850. static void construct(TStorage *me)
  851. {
  852. new(raw(me)) TValue();
  853. }
  854. static void destruct(TStorage *me)
  855. {
  856. ptr(me)->~T();
  857. }
  858. static TRatlNew *raw(TStorage *me)
  859. {
  860. return (TRatlNew *)&me->value;
  861. }
  862. static T * ptr(TStorage *me)
  863. {
  864. return (T *)&me->value;
  865. }
  866. static const T * ptr(const TStorage *me)
  867. {
  868. return (const T *)&me->value;
  869. }
  870. static T & ref(TStorage *me)
  871. {
  872. return *(T *)&me->value;
  873. }
  874. static const T & ref(const TStorage *me)
  875. {
  876. return *(const T *)&me->value;
  877. }
  878. static NODE & node(TStorage *me)
  879. {
  880. return me->nodeData;
  881. }
  882. static const NODE & node(const TStorage *me)
  883. {
  884. return me->nodeData;
  885. }
  886. // this ugly unsafe cast-hack is a backhanded way of getting the node data from the value data
  887. // this is so node support does not need to be added to the primitive containers
  888. static NODE & node(TValue &v)
  889. {
  890. return *(NODE *)((unsigned char *)(&v)+int(&((TStorage *)0)->nodeData)-int(&((TStorage *)0)->value));
  891. }
  892. static const NODE & node(const TValue &v)
  893. {
  894. return *(const NODE *)((unsigned char *)(&v)+int(&((TStorage *)0)->nodeData)-int(&((TStorage *)0)->value));
  895. }
  896. // this is a bit suspicious, we are forced to do a memory swap, and for a class, that, say
  897. // stores a pointer to itself, it won't work right
  898. static void swap(TStorage *s1,TStorage *s2)
  899. {
  900. mem::swap(&s1->value,&s2->value);
  901. }
  902. // this is hideous
  903. static int pointer_to_index(const void *s1,const void *s2)
  904. {
  905. return
  906. ((TStorage *)(((unsigned char *)s1)-int(&((TStorage *)0)->value))) -
  907. ((TStorage *)(((unsigned char *)s2)-int(&((TStorage *)0)->value)));
  908. }
  909. template<class CAST_TO>
  910. static CAST_TO *verify_alloc(CAST_TO *p)
  911. {
  912. #ifdef _DEBUG
  913. assert(p);
  914. assert(dynamic_cast<const T *>(p));
  915. T *ptr=p; // if this doesn't compile, you are trying to alloc something that is not derived from base
  916. assert(dynamic_cast<const CAST_TO *>(ptr));
  917. int i=VALUE_SIZE;
  918. int k=MAX_CLASS_SIZE;
  919. int j=sizeof(CAST_TO);
  920. compile_assert<sizeof(CAST_TO)<=MAX_CLASS_SIZE>();
  921. assert(sizeof(CAST_TO)<=MAX_CLASS_SIZE);
  922. #endif
  923. return p;
  924. }
  925. };
  926. }
  927. ////////////////////////////////////////////////////////////////////////////////////////
  928. // The Array Base Class, used for most containers
  929. ////////////////////////////////////////////////////////////////////////////////////////
  930. template<class T>
  931. class array_base : public ratl_base
  932. {
  933. public:
  934. ////////////////////////////////////////////////////////////////////////////////////
  935. // Capacity Enum
  936. ////////////////////////////////////////////////////////////////////////////////////
  937. enum
  938. {
  939. CAPACITY = T::CAPACITY,
  940. SIZE = T::CAPACITY,
  941. };
  942. ////////////////////////////////////////////////////////////////////////////////////
  943. // Data
  944. ////////////////////////////////////////////////////////////////////////////////////
  945. typedef typename T TStorageTraits;
  946. typedef typename T::TArray TTArray;
  947. typedef typename T::TValue TTValue;
  948. typedef typename T::TConstructed TTConstructed;
  949. private:
  950. TTArray mArray;
  951. TTConstructed mConstructed;
  952. public:
  953. array_base()
  954. {
  955. }
  956. ~array_base()
  957. {
  958. clear();
  959. }
  960. void clear()
  961. {
  962. if (T::NEEDS_CONSTRUCT)
  963. {
  964. int i=mConstructed.next_bit();
  965. while (i<SIZE)
  966. {
  967. T::destruct(mArray+i);
  968. i=mConstructed.next_bit(i+1);
  969. }
  970. mConstructed.clear();
  971. }
  972. }
  973. ////////////////////////////////////////////////////////////////////////////////////
  974. // Access Operator
  975. ////////////////////////////////////////////////////////////////////////////////////
  976. TTValue& operator[](int index)
  977. {
  978. assert(index>=0 && index<SIZE);
  979. assert(mConstructed[index]);
  980. return T::ref(mArray+index);
  981. }
  982. ////////////////////////////////////////////////////////////////////////////////////
  983. // Const Access Operator
  984. ////////////////////////////////////////////////////////////////////////////////////
  985. const TTValue& operator[](int index) const
  986. {
  987. assert(index>=0 && index<SIZE);
  988. assert(mConstructed[index]);
  989. return T::ref(mArray+index);
  990. }
  991. void construct(int i)
  992. {
  993. if (T::NEEDS_CONSTRUCT)
  994. {
  995. assert(!mConstructed[i]);
  996. T::construct(mArray+i);
  997. mConstructed.set_bit(i);
  998. }
  999. }
  1000. void construct(int i, const TTValue &v)
  1001. {
  1002. assert(i>=0 && i<SIZE);
  1003. T::construct(mArray+i,v);
  1004. if (T::NEEDS_CONSTRUCT)
  1005. {
  1006. assert(!mConstructed[i]);
  1007. mConstructed.set_bit(i);
  1008. }
  1009. }
  1010. void fill(const TTValue &v)
  1011. {
  1012. clear();
  1013. int i;
  1014. for (i=0;i<SIZE;i++)
  1015. {
  1016. T::construct(mArray+i,v);
  1017. }
  1018. if (T::NEEDS_CONSTRUCT)
  1019. {
  1020. mConstructed.set();
  1021. }
  1022. }
  1023. void swap(int i,int j)
  1024. {
  1025. assert(i>=0 && i<SIZE);
  1026. assert(j>=0 && j<SIZE);
  1027. assert(i!=j);
  1028. assert(mConstructed[i]);
  1029. assert(mConstructed[j]);
  1030. T::swap(mArray+i,mArray+j);
  1031. }
  1032. TRatlNew *alloc_raw(int i)
  1033. {
  1034. assert(i>=0 && i<SIZE);
  1035. if (T::NEEDS_CONSTRUCT)
  1036. {
  1037. assert(!mConstructed[i]);
  1038. mConstructed.set_bit(i);
  1039. }
  1040. return T::raw(mArray+i);
  1041. }
  1042. void destruct(int i)
  1043. {
  1044. assert(i>=0 && i<SIZE);
  1045. assert(mConstructed[i]);
  1046. if (T::NEEDS_CONSTRUCT)
  1047. {
  1048. T::destruct(mArray+i);
  1049. mConstructed.clear_bit(i);
  1050. }
  1051. }
  1052. int pointer_to_index(const TTValue *me) const
  1053. {
  1054. int index=T::pointer_to_index(me,mArray);
  1055. assert(index>=0 && index<SIZE);
  1056. assert(mConstructed[index]);
  1057. return index;
  1058. }
  1059. int pointer_to_index(const TRatlNew *me) const
  1060. {
  1061. int index=T::pointer_to_index(me,mArray);
  1062. assert(index>=0 && index<SIZE);
  1063. assert(mConstructed[index]);
  1064. return index;
  1065. }
  1066. typename T::TValue *raw_array()
  1067. {
  1068. return T::raw_array(mArray);
  1069. }
  1070. const typename T::TValue *raw_array() const
  1071. {
  1072. return T::raw_array(mArray);
  1073. }
  1074. template<class CAST_TO>
  1075. CAST_TO *verify_alloc(CAST_TO *p) const
  1076. {
  1077. return T::verify_alloc(p);
  1078. }
  1079. };
  1080. }
  1081. #endif