'g'o should not miss items in corners anymore
[k8-i-v-a-n.git] / src / felib / fearray.h
blobb071206208dff9ebc253fb8308194a7d0a76aec9
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 public:
20 typedef uInt sizetype;
22 public:
23 fearray () : Data(0), Size(0) {}
24 fearray (const fearray &arr);
25 fearray (const type *arr, sizetype aSize);
26 ~fearray ();
28 fearray &operator = (const fearray &arr);
29 type &operator [] (sizetype idx) { return Data[idx]; }
30 const type &operator [] (sizetype idx) const { return Data[idx]; }
32 void Allocate (sizetype count);
33 void Add (const type &it);
34 void Clear ();
36 const type &GetRandomElement () const { return Data[RAND_N(Size)]; }
38 public:
39 type *Data;
40 sizetype Size;
44 template <class type> inline fearray<type>::fearray (const fearray<type>& arr) : Data(arr.Data), Size(arr.Size) {
45 if (Data) ++REFS(Data);
49 template <class type> inline fearray<type>::fearray (const type *arr, sizetype aSize) : Data(0), Size(aSize) {
50 char *ptr = new char[aSize*sizeof(type)+sizeof(rcint)];
51 *reinterpret_cast<rcint *>(ptr) = 0;
52 Data = reinterpret_cast<type *>(ptr+sizeof(rcint));
53 for (sizetype c = 0; c < aSize; ++c) new (&Data[c])type(arr[c]);
57 template <class type> inline fearray<type>::~fearray<type> () {
58 Clear();
62 template <class type> inline fearray<type> &fearray<type>::operator = (const fearray<type> &arr) {
63 if (arr.Data != Data) Clear();
64 Data = arr.Data;
65 if (Data) ++REFS(Data);
66 Size = arr.Size;
67 return *this;
71 template <class type> inline void fearray<type>::Clear () {
72 type *ptr = Data;
73 if (ptr) {
74 if (!REFS(ptr)--) {
75 for (sizetype c = 0; c < Size; ++c) ptr[c].~type();
76 delete [] REFSA(ptr);
78 Data = 0;
79 Size = 0;
84 template <class type> inline void fearray<type>::Allocate (sizetype count) {
85 char *ptr = new char[count*sizeof(type)+sizeof(rcint)];
86 *reinterpret_cast<rcint *>(ptr) = 0;
87 Data = reinterpret_cast<type *>(ptr+sizeof(rcint));
88 Size = count;
89 for (sizetype c = 0; c < count; ++c) new (&Data[c])type;
93 /* Don't use unless necessary */
94 template <class type> inline void fearray<type>::Add (const type &it) {
95 type *ptr = Data;
96 if (ptr) {
97 sizetype oldsize = this->Size++;
98 char *newptr = new char[Size*sizeof(type)+sizeof(rcint)];
99 *reinterpret_cast<rcint *>(newptr) = 0;
100 type *newdata = reinterpret_cast<type *>(newptr+sizeof(rcint));
101 if (!REFS(ptr)--) {
102 for (sizetype c = 0; c < oldsize; ++c) {
103 new (&newdata[c])type(ptr[c]);
104 ptr[c].~type();
106 delete [] REFSA(ptr);
107 } else {
108 for(sizetype c = 0; c < oldsize; ++c) new (&newdata[c])type(ptr[c]);
110 Data = newdata;
111 new(&newdata[oldsize]) type(it);
112 } else {
113 char *newptr = new char[sizeof(type)+sizeof(rcint)];
114 *reinterpret_cast<int*>(newptr) = 0;
115 Data = reinterpret_cast<type*>(newptr+sizeof(rcint));
116 Size = 1;
117 new(Data) type(it);
122 template <class type1, class type2> inline void ArrayToVector (const fearray<type1> &arr, std::vector<type2> &vect) {
123 vect.resize(arr.Size, type2());
124 for (typename fearray<type1>::sizetype c = 0; c < arr.Size; ++c) vect[c] = arr.Data[c];
128 #endif