1+ /*
2+ * Copyright (c) 2009-2011, NVIDIA Corporation
3+ * All rights reserved.
4+ *
5+ * Redistribution and use in source and binary forms, with or without
6+ * modification, are permitted provided that the following conditions are met:
7+ * * Redistributions of source code must retain the above copyright
8+ * notice, this list of conditions and the following disclaimer.
9+ * * Redistributions in binary form must reproduce the above copyright
10+ * notice, this list of conditions and the following disclaimer in the
11+ * documentation and/or other materials provided with the distribution.
12+ * * Neither the name of NVIDIA Corporation nor the
13+ * names of its contributors may be used to endorse or promote products
14+ * derived from this software without specific prior written permission.
15+ *
16+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+ */
27+
28+ #pragma once
29+ #include " linear_math.h"
30+ #include < string.h>
31+ #include " Util.h"
32+
33+
34+ template <class T > class Array
35+ {
36+ private:
37+ enum
38+ {
39+ MinBytes = 32 ,
40+ };
41+
42+ public:
43+ Array (void ) { init (); }
44+ explicit Array (const T& item) { init (); add (item); }
45+ Array (const T* ptr, int size) { init (); set (ptr, size); }
46+ Array (const Array<T>& other) { init (); set (other); }
47+ ~Array (void ) { delete[] m_ptr; }
48+
49+ int getSize (void ) const { return m_size; }
50+ const T& get (int idx) const { FW_ASSERT (idx >= 0 && idx < m_size); return m_ptr[idx]; }
51+ T& get (int idx) { FW_ASSERT (idx >= 0 && idx < m_size); return m_ptr[idx]; }
52+ T set (int idx, const T& item) { T& slot = get (idx); T old = slot; slot = item; return old; }
53+ const T& getFirst (void ) const { return get (0 ); }
54+ T& getFirst (void ) { return get (0 ); }
55+ const T& getLast (void ) const { return get (getSize () - 1 ); }
56+ T& getLast (void ) { return get (getSize () - 1 ); }
57+ const T* getPtr (int idx = 0 ) const { FW_ASSERT (idx >= 0 && idx <= m_size); return m_ptr + idx; }
58+ T* getPtr (int idx = 0 ) { FW_ASSERT (idx >= 0 && idx <= m_size); return m_ptr + idx; }
59+
60+ int getStride (void ) const { return sizeof (T); }
61+ int getNumBytes (void ) const { return getSize () * getStride (); }
62+
63+ void reset (int size = 0 ) { clear (); setCapacity (size); m_size = size; }
64+ void clear (void ) { m_size = 0 ; }
65+ void resize (int size);
66+ void setCapacity (int capacity) { int c = max1i (capacity, m_size); if (m_alloc != c) realloc (c); }
67+ void compact (void ) { setCapacity (0 ); }
68+
69+ void set (const T* ptr, int size) { reset (size); if (ptr) copy (getPtr (), ptr, size); }
70+ void set (const Array<T>& other) { if (&other != this ) set (other.getPtr (), other.getSize ()); }
71+ void setRange (int start, int end, const T* ptr) { FW_ASSERT (end <= m_size); copy (getPtr (start), ptr, end - start); }
72+ void setRange (int start, const Array<T>& other) { setRange (start, start + other.getSize (), other.getPtr ()); }
73+ Array<T> getRange (int start, int end) const { FW_ASSERT (end <= m_size); return Array<T>(getPtr (start), end - start); }
74+
75+ T& add (void ) { return *add (NULL , 1 ); }
76+ T& add (const T& item) { T* slot = add (NULL , 1 ); *slot = item; return *slot; }
77+ T* add (const T* ptr, int size) { int oldSize = getSize (); resize (oldSize + size); T* slot = getPtr (oldSize); if (ptr) copy (slot, ptr, size); return slot; }
78+ T* add (const Array<T>& other) { return replace (getSize (), getSize (), other); }
79+
80+ T& insert (int idx) { return *replace (idx, idx, 1 ); }
81+ T& insert (int idx, const T& item) { T* slot = replace (idx, idx, 1 ); *slot = item; return *slot; }
82+ T* insert (int idx, const T* ptr, int size) { return replace (idx, idx, ptr, size); }
83+ T* insert (int idx, const Array<T>& other) { return replace (idx, idx, other); }
84+
85+ T remove (int idx) { T old = get (idx); replace (idx, idx + 1 , 0 ); return old; }
86+ void remove (int start, int end) { replace (start, end, 0 ); }
87+ T& removeLast (void ) { FW_ASSERT (m_size > 0 ); m_size--; return m_ptr[m_size]; }
88+ T removeSwap (int idx);
89+ void removeSwap (int start, int end);
90+
91+ T* replace (int start, int end, int size);
92+ T* replace (int start, int end, const T* ptr, int size) { T* slot = replace (start, end, size); if (ptr) copy (slot, ptr, size); return slot; }
93+ T* replace (int start, int end, const Array<T>& other);
94+
95+ int indexOf (const T& item) const { return indexOf (item, 0 ); }
96+ int indexOf (const T& item, int fromIdx) const ;
97+ int lastIndexOf (const T& item) const { return lastIndexOf (item, getSize () - 1 ); }
98+ int lastIndexOf (const T& item, int fromIdx) const ;
99+ bool contains (const T& item) const { return (indexOf (item) != -1 ); }
100+ bool removeItem (const T& item) { int idx = indexOf (item); if (idx == -1 ) return false ; remove (idx); return true ; }
101+
102+ const T& operator [] (int idx) const { return get (idx); }
103+ T& operator [] (int idx) { return get (idx); }
104+ Array<T>& operator = (const Array<T>& other) { set (other); return *this ; }
105+ bool operator == (const Array<T>& other) const ;
106+ bool operator != (const Array<T>& other) const { return (!operator ==(other)); }
107+
108+ static void copy (T* dst, const T* src, int size);
109+ static void copyOverlap (T* dst, const T* src, int size);
110+
111+ private:
112+ void init (void ) { m_ptr = NULL ; m_size = 0 ; m_alloc = 0 ; }
113+ void realloc (int size);
114+
115+ private:
116+ T* m_ptr;
117+ S32 m_size;
118+ S32 m_alloc;
119+ };
120+
121+ // ------------------------------------------------------------------------
122+
123+
124+
125+ template <class T > void Array<T>::resize(int size)
126+ {
127+ FW_ASSERT (size >= 0 );
128+
129+ if (size > m_alloc)
130+ {
131+ int newAlloc = max1i ((int )(MinBytes / sizeof (T)), 1 );
132+ while (size > newAlloc)
133+ newAlloc <<= 1 ;
134+ realloc (newAlloc);
135+ }
136+
137+ m_size = size;
138+ }
139+
140+ // ------------------------------------------------------------------------
141+
142+ template <class T > T Array<T>::removeSwap(int idx)
143+ {
144+ FW_ASSERT (idx >= 0 && idx < m_size);
145+
146+ T old = get (idx);
147+ m_size--;
148+ if (idx < m_size)
149+ m_ptr[idx] = m_ptr[m_size];
150+ return old;
151+ }
152+
153+ // ------------------------------------------------------------------------
154+
155+ template <class T > void Array<T>::removeSwap(int start, int end)
156+ {
157+ FW_ASSERT (start >= 0 );
158+ FW_ASSERT (start <= end);
159+ FW_ASSERT (end <= m_size);
160+
161+ int oldSize = m_size;
162+ m_size += start - end;
163+
164+ int copyStart = max (m_size, end);
165+ copy (m_ptr + start, m_ptr + copyStart, oldSize - copyStart);
166+ }
167+
168+ // ------------------------------------------------------------------------
169+
170+ template <class T > T* Array<T>::replace(int start, int end, int size)
171+ {
172+ FW_ASSERT (start >= 0 );
173+ FW_ASSERT (start <= end);
174+ FW_ASSERT (end <= m_size);
175+ FW_ASSERT (size >= 0 );
176+
177+ int tailSize = m_size - end;
178+ int newEnd = start + size;
179+ resize (m_size + newEnd - end);
180+
181+ copyOverlap (m_ptr + newEnd, m_ptr + end, tailSize);
182+ return m_ptr + start;
183+ }
184+
185+ // ------------------------------------------------------------------------
186+
187+ template <class T > T* Array<T>::replace(int start, int end, const Array<T>& other)
188+ {
189+ Array<T> tmp;
190+ const T* ptr = other.getPtr ();
191+ if (&other == this )
192+ {
193+ tmp = other;
194+ ptr = tmp.getPtr ();
195+ }
196+ return replace (start, end, ptr, other.getSize ());
197+ }
198+
199+ // ------------------------------------------------------------------------
200+
201+ template <class T > int Array<T>::indexOf(const T& item, int fromIdx) const
202+ {
203+ for (int i = max1i (fromIdx, 0 ); i < getSize (); i++)
204+ if (get (i) == item)
205+ return i;
206+ return -1 ;
207+ }
208+
209+ // ------------------------------------------------------------------------
210+
211+ template <class T > int Array<T>::lastIndexOf(const T& item, int fromIdx) const
212+ {
213+ for (int i = min1i (fromIdx, getSize () - 1 ); i >= 0 ; i--)
214+ if (get (i) == item)
215+ return i;
216+ return -1 ;
217+ }
218+
219+ // ------------------------------------------------------------------------
220+
221+ template <class T > bool Array<T>::operator ==(const Array<T>& other) const
222+ {
223+ if (getSize () != other.getSize ())
224+ return false ;
225+
226+ for (int i = 0 ; i < getSize (); i++)
227+ if (get (i) != other[i])
228+ return false ;
229+ return true ;
230+ }
231+
232+ // ------------------------------------------------------------------------
233+
234+ template <class T > void Array<T>::copy(T* dst, const T* src, int size)
235+ {
236+ FW_ASSERT (size >= 0 );
237+ if (!size)
238+ return ;
239+
240+ FW_ASSERT (dst && src);
241+ for (int i = 0 ; i < size; i++)
242+ dst[i] = src[i];
243+ }
244+
245+ // ------------------------------------------------------------------------
246+
247+ template <class T > void Array<T>::copyOverlap(T* dst, const T* src, int size)
248+ {
249+ FW_ASSERT (size >= 0 );
250+ if (!size)
251+ return ;
252+
253+ FW_ASSERT (dst && src);
254+ if (dst < src || dst >= src + size)
255+ for (int i = 0 ; i < size; i++)
256+ dst[i] = src[i];
257+ else
258+ for (int i = size - 1 ; i >= 0 ; i--)
259+ dst[i] = src[i];
260+ }
261+
262+ // ------------------------------------------------------------------------
263+
264+ template <class T > void Array<T>::realloc(int size)
265+ {
266+ FW_ASSERT (size >= 0 );
267+
268+ T* newPtr = NULL ;
269+ if (size)
270+ {
271+ newPtr = new T[size];
272+ copy (newPtr, m_ptr, min1i (size, m_size));
273+ }
274+
275+ delete[] m_ptr;
276+ m_ptr = newPtr;
277+ m_alloc = size;
278+ }
279+
280+ // ------------------------------------------------------------------------
281+
282+ inline void Array<S32>::copy(S32* dst, const S32* src, int size) { memcpy (dst, src, size * sizeof (S32)); }
283+ inline void Array<U32>::copy(U32* dst, const U32* src, int size) { memcpy (dst, src, size * sizeof (U32)); }
284+ inline void Array<F32>::copy(F32* dst, const F32* src, int size) { memcpy (dst, src, size * sizeof (F32)); }
285+
286+ inline void Array<Vec2f>::copy(Vec2f* dst, const Vec2f* src, int size) { memcpy (dst, src, size * sizeof (Vec2f)); }
287+ inline void Array<Vec3f>::copy(Vec3f* dst, const Vec3f* src, int size) { memcpy (dst, src, size * sizeof (Vec3f)); }
288+ inline void Array<Vec4f>::copy(Vec4f* dst, const Vec4f* src, int size) { memcpy (dst, src, size * sizeof (Vec4f)); }
289+
290+ // ------------------------------------------------------------------------
0 commit comments