3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
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__
18 template <class type
> struct fearray
{
20 typedef uInt sizetype
;
23 fearray () : Data(0), Size(0) {}
24 fearray (const fearray
&arr
);
25 fearray (const type
*arr
, sizetype aSize
);
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
);
36 const type
&GetRandomElement () const { return Data
[RAND_N(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
> () {
62 template <class type
> inline fearray
<type
> &fearray
<type
>::operator = (const fearray
<type
> &arr
) {
63 if (arr
.Data
!= Data
) Clear();
65 if (Data
) ++REFS(Data
);
71 template <class type
> inline void fearray
<type
>::Clear () {
75 for (sizetype c
= 0; c
< Size
; ++c
) ptr
[c
].~type();
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
));
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
) {
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
));
102 for (sizetype c
= 0; c
< oldsize
; ++c
) {
103 new (&newdata
[c
])type(ptr
[c
]);
106 delete [] REFSA(ptr
);
108 for(sizetype c
= 0; c
< oldsize
; ++c
) new (&newdata
[c
])type(ptr
[c
]);
111 new(&newdata
[oldsize
]) type(it
);
113 char *newptr
= new char[sizeof(type
)+sizeof(rcint
)];
114 *reinterpret_cast<int*>(newptr
) = 0;
115 Data
= reinterpret_cast<type
*>(newptr
+sizeof(rcint
));
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
];