1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#ifndef __SimpleArray_h__
#define __SimpleArray_h__
#include <cstddef>
#include <string.h> /* for memcpy and memmov */
#include "message.h"
/**
* SimpleArray holds a pointer to an array and the array size, and is designed to
* be passed by value. It does not define any virtual methods to prevent overheads
* in its subclasses.
*/
template<typename T>
class SimpleArray {
protected:
T* data;
size_t size;
public:
SimpleArray() : data(NULL), size(0){}
SimpleArray(T* data, size_t size) : data(data), size(size){}
/* virtual ~SimpleArray(){} No virtual destructor to prevent adding a vtable to the object size */
/**
* Get the data stored in the Array.
* @return a T* pointer to the data stored in the Array
*/
T* getData(){
return data;
}
size_t getSize() const {
return size;
}
bool isEmpty() const {
return size == 0;
}
/**
* Get a single value stored in the array.
* @return the value stored at index @param index
*/
T getElement(size_t index){
return data[index];
}
/**
* Set a single value in the array.
*/
void setElement(size_t index, T value){
data[index] = value;
}
/**
* Compares two arrays.
* Performs an element-wise comparison of the values contained in the arrays.
* @param other the array to compare against.
* @return **true** if the arrays have the same size and the value of each of the elements of the one
* match the value of the corresponding element of the other, or **false** otherwise.
*/
bool equals(const SimpleArray<T>& other) const {
if(size != other.size)
return false;
for(size_t n=0; n<size; n++){
if(data[n] != other.data[n])
return false;
}
return true;
}
/**
* Copies the content of this array to another array.
* The other array needs to be at least as big as this array.
* @param[out] destination the destination array
*/
void copyTo(SimpleArray<T> destination){
ASSERT(destination.size >= size, "Array too small");
memcpy((void*)destination.data, (void*)data, size*sizeof(T));
}
/**
* Copies the content of another array into this array.
* This array needs to be at least as big as the other array.
* @param[in] source the source array
*/
void copyFrom(SimpleArray<T> source){
ASSERT(size >= source.size, "Array too small");
memcpy((void*)data, (void*)source.data, source.size*sizeof(T));
}
/**
* Copies the content of an array into a subset of the array.
* Copies **len** elements from **source** to **destinationOffset** in the current array.
* @param[in] source the source array
* @param[in] destinationOffset the offset into the destination array
* @param[in] len the number of samples to copy
*
*/
void insert(SimpleArray<T> source, int destinationOffset, size_t len){
insert(source, 0, destinationOffset, len);
}
/**
* Copies the content of an array into a subset of the array.
* Copies **len** elements starting from **sourceOffset** of **source** to **destinationOffset** in the current array.
* @param[in] source the source array
* @param[in] sourceOffset the offset into the source array
* @param[in] destinationOffset the offset into the destination array
* @param[in] len the number of samples to copy
*/
void insert(SimpleArray<T> source, int sourceOffset, int destinationOffset, size_t len){
ASSERT(size >= destinationOffset+len, "Array too small");
ASSERT(source.size >= sourceOffset+len, "Array too small");
memcpy((void*)(data+destinationOffset), (void*)(source.data+sourceOffset), len*sizeof(T));
}
/**
* Copies values within an array.
* Copies **length** values starting from index **fromIndex** to locations starting with index **toIndex**
* @param[in] fromIndex the first element to copy
* @param[in] toIndex the destination of the first element
* @param[in] len the number of elements to copy
*/
void move(int fromIndex, int toIndex, size_t len){
ASSERT(size >= toIndex+len, "Array too small");
memmove((void*)(data+toIndex), (void*)(data+fromIndex), len*sizeof(T));
}
/**
* Optimised array copy for datatype T.
* Copy four at a time to minimise loop overheads and allow SIMD optimisations.
* This performs well on external RAM but is slower on internal memory compared to memcpy.
*/
static void copy(T* dst, T* src, size_t len){
size_t blocks = len >> 2u;
T a, b, c, d;
while(blocks--){
a = *src++;
b = *src++;
c = *src++;
d = *src++;
*dst++ = a;
*dst++ = b;
*dst++ = c;
*dst++ = d;
}
blocks = len & 0x3;
while(blocks--){
*dst++ = *src++;
}
}
/**
* Casting operator to T*
* @return a T* pointer to the data stored in the Array
*/
operator T*(){
return data;
}
// /**
// * Allows to index the array using array-style brackets.
// * @param index the index of the element
// * @return the value of the **index** element of the array
// */
// T& operator [](size_t index){
// return data[index];
// }
// /**
// * Allows to index the array using array-style brackets.
// * **const** version of operator[]
// */
// const T& operator [](size_t index) const {
// return data[index];
// }
};
#endif // __SimpleArray_h__