fixed some bugs in new 'g'o system
[k8-i-v-a-n.git] / src / felib / fearray.h
blobb0020994a7c1714a5e3d9832cdb994f9a51d58c2
1 /*
3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
6 * Public License
8 * See LICENSING which should be included
9 * along with this file for more details
12 #ifndef __FELIB_FEARRAY_H__
13 #define __FELIB_FEARRAY_H__
15 #include "femath.h"
18 template <class type> struct fearray {
19 typedef uInt sizetype;
20 fearray () : Data(0), Size(0) {}
21 fearray (const fearray &);
22 fearray (const type *, sizetype);
23 ~fearray ();
24 fearray &operator = (const fearray &);
25 type &operator [] (sizetype I) { return Data[I]; }
26 const type &operator [] (sizetype I) const { return Data[I]; }
27 void Allocate (sizetype);
28 void Add (const type &);
29 void Clear ();
30 const type &GetRandomElement () const { return Data[RAND_N(Size)]; }
31 type *Data;
32 sizetype Size;
36 template <class type> inline fearray<type>::fearray (const fearray<type>& A) : Data(A.Data), Size(A.Size) {
37 if (Data) ++REFS(Data);
41 template <class type> inline fearray<type>::fearray (const type *Array, sizetype Size) : Size(Size) {
42 char *Ptr = new char[Size*sizeof(type)+sizeof(feuLong)];
43 *reinterpret_cast<feuLong *>(Ptr) = 0;
44 Data = reinterpret_cast<type *>(Ptr+sizeof(feuLong));
45 for (sizetype c = 0; c < Size; ++c) new (&Data[c])type(Array[c]);
49 template <class type> inline fearray<type>::~fearray<type> () {
50 type *Ptr = Data;
51 if (Ptr && !REFS(Ptr)--) {
52 type *TempPtr = Ptr, *EndPtr = Ptr+Size;
53 for (; TempPtr != EndPtr; ++TempPtr) TempPtr->~type();
54 delete [] REFSA(Ptr);
59 template <class type> inline fearray<type> &fearray<type>::operator = (const fearray<type> &A) {
60 if (A.Data) ++REFS(Data = A.Data);
61 Size = A.Size;
62 return *this;
66 template <class type> inline void fearray<type>::Clear () {
67 type *Ptr = Data;
68 if (Ptr) {
69 if (!REFS(Ptr)--) {
70 for (sizetype c = 0; c < Size; ++c) Ptr[c].~type();
71 delete [] REFSA(Ptr);
73 Data = 0;
74 Size = 0;
79 template <class type> inline void fearray<type>::Allocate (sizetype What) {
80 char *Ptr = new char[What*sizeof(type)+sizeof(feuLong)];
81 *reinterpret_cast<feuLong *>(Ptr) = 0;
82 Data = reinterpret_cast<type *>(Ptr+sizeof(feuLong));
83 Size = What;
84 for (sizetype c = 0; c < What; ++c) new (&Data[c])type;
88 /* Don't use unless necessary */
89 template <class type> inline void fearray<type>::Add (const type &Type) {
90 type *Ptr = Data;
91 if (Ptr) {
92 sizetype Size = this->Size++;
93 char* NewPtr = new char[(Size+1)*sizeof(type)+sizeof(feuLong)];
94 *reinterpret_cast<feuLong *>(NewPtr) = 0;
95 type* NewData = reinterpret_cast<type *>(NewPtr+sizeof(feuLong));
96 if (!REFS(Ptr)--) {
97 for (sizetype c = 0; c < Size; ++c) {
98 new (&NewData[c])type(Ptr[c]);
99 Ptr[c].~type();
101 delete [] REFSA(Ptr);
102 } else {
103 for(sizetype c = 0; c < Size; ++c) new (&NewData[c])type(Ptr[c]);
105 Data = NewData;
106 new(&NewData[Size]) type(Type);
107 } else {
108 char *NewPtr = new char[sizeof(type)+sizeof(feuLong)];
109 *reinterpret_cast<feuLong*>(NewPtr) = 0;
110 Data = reinterpret_cast<type*>(NewPtr+sizeof(feuLong));
111 Size = 1;
112 new(Data) type(Type);
117 template <class type1, class type2> inline void ArrayToVector (const fearray<type1> &Array, std::vector<type2> &Vect) {
118 Vect.resize(Array.Size, type2());
119 for (typename fearray<type1>::sizetype c = 0; c < Array.Size; ++c) Vect[c] = Array.Data[c];
123 #endif