[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / src / BulletCollision / Gimpact / gim_array.h
1 #ifndef GIM_ARRAY_H_INCLUDED
2 #define GIM_ARRAY_H_INCLUDED
3 /*! \file gim_array.h
4 \author Francisco Leon Najera
5 */
6 /*
7 -----------------------------------------------------------------------------
8 This source file is part of GIMPACT Library.
9
10 For the latest info, see http://gimpact.sourceforge.net/
11
12 Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
13 email: projectileman@yahoo.com
14
15  This library is free software; you can redistribute it and/or
16  modify it under the terms of EITHER:
17    (1) The GNU Lesser General Public License as published by the Free
18        Software Foundation; either version 2.1 of the License, or (at
19        your option) any later version. The text of the GNU Lesser
20        General Public License is included with this library in the
21        file GIMPACT-LICENSE-LGPL.TXT.
22    (2) The BSD-style license that is included with this library in
23        the file GIMPACT-LICENSE-BSD.TXT.
24    (3) The zlib/libpng license that is included with this library in
25        the file GIMPACT-LICENSE-ZLIB.TXT.
26
27  This library is distributed in the hope that it will be useful,
28  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
30  GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
31
32 -----------------------------------------------------------------------------
33 */
34
35 #include "gim_memory.h"
36
37 #define GIM_ARRAY_GROW_INCREMENT 2
38 #define GIM_ARRAY_GROW_FACTOR 2
39
40 //!     Very simple array container with fast access and simd memory
41 template <typename T>
42 class gim_array
43 {
44 public:
45         //! properties
46         //!@{
47         T* m_data;
48         GUINT m_size;
49         GUINT m_allocated_size;
50         //!@}
51         //! protected operations
52         //!@{
53
54         inline void destroyData()
55         {
56                 m_allocated_size = 0;
57                 if (m_data == NULL) return;
58                 gim_free(m_data);
59                 m_data = NULL;
60         }
61
62         inline bool resizeData(GUINT newsize)
63         {
64                 if (newsize == 0)
65                 {
66                         destroyData();
67                         return true;
68                 }
69
70                 if (m_size > 0)
71                 {
72                         m_data = (T*)gim_realloc(m_data, m_size * sizeof(T), newsize * sizeof(T));
73                 }
74                 else
75                 {
76                         m_data = (T*)gim_alloc(newsize * sizeof(T));
77                 }
78                 m_allocated_size = newsize;
79                 return true;
80         }
81
82         inline bool growingCheck()
83         {
84                 if (m_allocated_size <= m_size)
85                 {
86                         GUINT requestsize = m_size;
87                         m_size = m_allocated_size;
88                         if (resizeData((requestsize + GIM_ARRAY_GROW_INCREMENT) * GIM_ARRAY_GROW_FACTOR) == false) return false;
89                 }
90                 return true;
91         }
92
93         //!@}
94         //! public operations
95         //!@{
96         inline bool reserve(GUINT size)
97         {
98                 if (m_allocated_size >= size) return false;
99                 return resizeData(size);
100         }
101
102         inline void clear_range(GUINT start_range)
103         {
104                 while (m_size > start_range)
105                 {
106                         m_data[--m_size].~T();
107                 }
108         }
109
110         inline void clear()
111         {
112                 if (m_size == 0) return;
113                 clear_range(0);
114         }
115
116         inline void clear_memory()
117         {
118                 clear();
119                 destroyData();
120         }
121
122         gim_array()
123         {
124                 m_data = 0;
125                 m_size = 0;
126                 m_allocated_size = 0;
127         }
128
129         gim_array(GUINT reservesize)
130         {
131                 m_data = 0;
132                 m_size = 0;
133
134                 m_allocated_size = 0;
135                 reserve(reservesize);
136         }
137
138         ~gim_array()
139         {
140                 clear_memory();
141         }
142
143         inline GUINT size() const
144         {
145                 return m_size;
146         }
147
148         inline GUINT max_size() const
149         {
150                 return m_allocated_size;
151         }
152
153         inline T& operator[](size_t i)
154         {
155                 return m_data[i];
156         }
157         inline const T& operator[](size_t i) const
158         {
159                 return m_data[i];
160         }
161
162         inline T* pointer() { return m_data; }
163         inline const T* pointer() const
164         {
165                 return m_data;
166         }
167
168         inline T* get_pointer_at(GUINT i)
169         {
170                 return m_data + i;
171         }
172
173         inline const T* get_pointer_at(GUINT i) const
174         {
175                 return m_data + i;
176         }
177
178         inline T& at(GUINT i)
179         {
180                 return m_data[i];
181         }
182
183         inline const T& at(GUINT i) const
184         {
185                 return m_data[i];
186         }
187
188         inline T& front()
189         {
190                 return *m_data;
191         }
192
193         inline const T& front() const
194         {
195                 return *m_data;
196         }
197
198         inline T& back()
199         {
200                 return m_data[m_size - 1];
201         }
202
203         inline const T& back() const
204         {
205                 return m_data[m_size - 1];
206         }
207
208         inline void swap(GUINT i, GUINT j)
209         {
210                 gim_swap_elements(m_data, i, j);
211         }
212
213         inline void push_back(const T& obj)
214         {
215                 this->growingCheck();
216                 m_data[m_size] = obj;
217                 m_size++;
218         }
219
220         //!Simply increase the m_size, doesn't call the new element constructor
221         inline void push_back_mem()
222         {
223                 this->growingCheck();
224                 m_size++;
225         }
226
227         inline void push_back_memcpy(const T& obj)
228         {
229                 this->growingCheck();
230                 gim_simd_memcpy(&m_data[m_size], &obj, sizeof(T));
231                 m_size++;
232         }
233
234         inline void pop_back()
235         {
236                 m_size--;
237                 m_data[m_size].~T();
238         }
239
240         //!Simply decrease the m_size, doesn't call the deleted element destructor
241         inline void pop_back_mem()
242         {
243                 m_size--;
244         }
245
246         //! fast erase
247         inline void erase(GUINT index)
248         {
249                 if (index < m_size - 1)
250                 {
251                         swap(index, m_size - 1);
252                 }
253                 pop_back();
254         }
255
256         inline void erase_sorted_mem(GUINT index)
257         {
258                 m_size--;
259                 for (GUINT i = index; i < m_size; i++)
260                 {
261                         gim_simd_memcpy(m_data + i, m_data + i + 1, sizeof(T));
262                 }
263         }
264
265         inline void erase_sorted(GUINT index)
266         {
267                 m_data[index].~T();
268                 erase_sorted_mem(index);
269         }
270
271         inline void insert_mem(GUINT index)
272         {
273                 this->growingCheck();
274                 for (GUINT i = m_size; i > index; i--)
275                 {
276                         gim_simd_memcpy(m_data + i, m_data + i - 1, sizeof(T));
277                 }
278                 m_size++;
279         }
280
281         inline void insert(const T& obj, GUINT index)
282         {
283                 insert_mem(index);
284                 m_data[index] = obj;
285         }
286
287         inline void resize(GUINT size, bool call_constructor = true, const T& fillData = T())
288         {
289                 if (size > m_size)
290                 {
291                         reserve(size);
292                         if (call_constructor)
293                         {
294                                 while (m_size < size)
295                                 {
296                                         m_data[m_size] = fillData;
297                                         m_size++;
298                                 }
299                         }
300                         else
301                         {
302                                 m_size = size;
303                         }
304                 }
305                 else if (size < m_size)
306                 {
307                         if (call_constructor) clear_range(size);
308                         m_size = size;
309                 }
310         }
311
312         inline void refit()
313         {
314                 resizeData(m_size);
315         }
316 };
317
318 #endif  // GIM_CONTAINERS_H_INCLUDED