Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/GIMPACT/gim_array.h @ 2122

Last change on this file since 2122 was 2119, checked in by rgrieder, 16 years ago

Merged physics branch into physics_new branch.

  • Property svn:eol-style set to native
File size: 6.1 KB
Line 
1#ifndef GIM_ARRAY_H_INCLUDED
2#define GIM_ARRAY_H_INCLUDED
3/*! \file gim_array.h
4\author Francisco Len Nßjera
5*/
6/*
7-----------------------------------------------------------------------------
8This source file is part of GIMPACT Library.
9
10For the latest info, see http://gimpact.sourceforge.net/
11
12Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
13email: 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/*! \addtogroup CONTAINERS
38\brief
39Abstract class for template containers
40*/
41//! @{
42
43#define GIM_ARRAY_GROW_INCREMENT 2
44#define GIM_ARRAY_GROW_FACTOR 2
45
46//!     Very simple array container with fast access and simd memory
47template<typename T>
48class gim_array
49{
50public:
51//! properties
52//!@{
53    T *m_data;
54    GUINT m_size;
55    GUINT m_allocated_size;
56//!@}
57//! protected operations
58//!@{
59
60    inline void destroyData()
61        {
62            m_allocated_size = 0;
63                if(m_data==NULL) return;
64                gim_free(m_data);
65                m_data = NULL;
66        }
67
68        inline bool resizeData(GUINT newsize)
69        {
70                if(newsize==0)
71                {
72                        destroyData();
73                        return true;
74                }
75
76                if(m_size>0)
77                {
78            m_data = (T*)gim_realloc(m_data,m_size*sizeof(T),newsize*sizeof(T));
79                }
80                else
81                {
82                    m_data = (T*)gim_alloc(newsize*sizeof(T));
83                }
84                m_allocated_size = newsize;
85                return true;
86        }
87
88        inline bool growingCheck()
89        {
90                if(m_allocated_size<=m_size)
91                {
92                    GUINT requestsize = m_size;
93                    m_size = m_allocated_size;
94                        if(resizeData((requestsize+GIM_ARRAY_GROW_INCREMENT)*GIM_ARRAY_GROW_FACTOR)==false) return false;
95                }
96                return true;
97        }
98
99//!@}
100//! public operations
101//!@{
102    inline  bool reserve(GUINT size)
103    {
104        if(m_allocated_size>=size) return false;
105        return resizeData(size);
106    }
107
108    inline void clear_range(GUINT start_range)
109    {
110        while(m_size>start_range)
111        {
112            m_data[--m_size].~T();
113        }
114    }
115
116    inline void clear()
117    {
118        if(m_size==0)return;
119        clear_range(0);
120    }
121
122    inline void clear_memory()
123    {
124        clear();
125        destroyData();
126    }
127
128    gim_array()
129    {
130        m_data = 0;
131        m_size = 0;
132        m_allocated_size = 0;
133    }
134
135    gim_array(GUINT reservesize)
136    {
137        m_data = 0;
138        m_size = 0;
139
140        m_allocated_size = 0;
141        reserve(reservesize);
142    }
143
144    ~gim_array()
145    {
146        clear_memory();
147    }
148
149    inline GUINT size() const
150    {
151        return m_size;
152    }
153
154    inline GUINT max_size() const
155    {
156        return m_allocated_size;
157    }
158
159    inline T & operator[](size_t i)
160        {
161                return m_data[i];
162        }
163        inline  const T & operator[](size_t i) const
164        {
165                return m_data[i];
166        }
167
168    inline T * pointer(){ return m_data;}
169    inline const T * pointer() const
170    { return m_data;}
171
172
173    inline T * get_pointer_at(GUINT i)
174        {
175                return m_data + i;
176        }
177
178        inline const T * get_pointer_at(GUINT i) const
179        {
180                return m_data + i;
181        }
182
183        inline T & at(GUINT i)
184        {
185                return m_data[i];
186        }
187
188        inline const T & at(GUINT i) const
189        {
190                return m_data[i];
191        }
192
193        inline T & front()
194        {
195                return *m_data;
196        }
197
198        inline const T & front() const
199        {
200                return *m_data;
201        }
202
203        inline T & back()
204        {
205                return m_data[m_size-1];
206        }
207
208        inline const T & back() const
209        {
210                return m_data[m_size-1];
211        }
212
213
214        inline void swap(GUINT i, GUINT j)
215        {
216            gim_swap_elements(m_data,i,j);
217        }
218
219        inline void push_back(const T & obj)
220        {
221            this->growingCheck();
222            m_data[m_size] = obj;
223            m_size++;
224        }
225
226        //!Simply increase the m_size, doesn't call the new element constructor
227        inline void push_back_mem()
228        {
229            this->growingCheck();
230            m_size++;
231        }
232
233        inline void push_back_memcpy(const T & obj)
234        {
235            this->growingCheck();
236            irr_simd_memcpy(&m_data[m_size],&obj,sizeof(T));
237            m_size++;
238        }
239
240        inline void pop_back()
241        {
242            m_size--;
243        m_data[m_size].~T();
244        }
245
246        //!Simply decrease the m_size, doesn't call the deleted element destructor
247        inline void pop_back_mem()
248        {
249            m_size--;
250        }
251
252    //! fast erase
253        inline void erase(GUINT index)
254        {
255            if(index<m_size-1)
256            {
257                swap(index,m_size-1);
258            }
259            pop_back();
260        }
261
262        inline void erase_sorted_mem(GUINT index)
263        {
264            m_size--;
265            for(GUINT i = index;i<m_size;i++)
266            {
267                gim_simd_memcpy(m_data+i,m_data+i+1,sizeof(T));
268            }
269        }
270
271        inline void erase_sorted(GUINT index)
272        {
273            m_data[index].~T();
274            erase_sorted_mem(index);
275        }
276
277        inline void insert_mem(GUINT index)
278        {
279            this->growingCheck();
280            for(GUINT i = m_size;i>index;i--)
281            {
282                gim_simd_memcpy(m_data+i,m_data+i-1,sizeof(T));
283            }
284            m_size++;
285        }
286
287        inline void insert(const T & obj,GUINT index)
288        {
289            insert_mem(index);
290            m_data[index] = obj;
291        }
292
293        inline void resize(GUINT size, bool call_constructor = true)
294        {
295
296            if(size>m_size)
297            {
298            reserve(size);
299            if(call_constructor)
300            {
301                T obj;
302                while(m_size<size)
303                {
304                    m_data[m_size] = obj;
305                    m_size++;
306                }
307            }
308            else
309            {
310                m_size = size;
311            }
312            }
313            else if(size<m_size)
314            {
315                if(call_constructor) clear_range(size);
316                m_size = size;
317            }
318        }
319
320        inline void refit()
321        {
322            resizeData(m_size);
323        }
324//!@}
325};
326
327
328//! @}
329
330
331
332#endif // GIM_CONTAINERS_H_INCLUDED
Note: See TracBrowser for help on using the repository browser.