1 /*
2  * This file is part of NumptyPhysics
3  * Copyright (C) 2008 Tim Edmonds
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 3 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  */
16 
17 #ifndef ARRAY_H
18 #define ARRAY_H
19 
20 #include "Common.h"
21 
22 template <typename T>
23 class Array
24 {
25  public:
26 
m_data(NULL)27   Array( int cap=0 ) : m_data(NULL), m_size(0), m_capacity(0)
28   {
29     capacity( cap );
30   }
31 
Array(int n,const T * d)32  Array( int n, const T* d ) : m_data(NULL), m_size(0), m_capacity(0)
33   {
34     if ( n ) {
35       capacity( n );
36       memcpy( m_data, d, n * sizeof(T) );
37       m_size = n;
38     }
39   }
40 
Array(const Array & other)41   Array( const Array& other ) : m_data(NULL), m_size(0), m_capacity(0)
42   {
43     if ( other.size() ) {
44       capacity( other.size() );
45       memcpy( m_data, other.m_data, other.size() * sizeof(T) );
46       m_size = other.size();
47     }
48   }
49 
~Array()50   ~Array()
51   {
52     if ( m_data ) {
53       free( m_data );
54     }
55   }
56 
size()57   int size() const
58   {
59     return m_size;
60   }
61 
empty()62   void empty()
63   {
64     m_size = 0;
65   }
66 
at(int i)67   T& at( int i )
68   {
69     ASSERT( i < m_size );
70     return m_data[i];
71   }
72 
at(int i)73   const T& at( int i ) const
74   {
75     ASSERT( i < m_size );
76     return m_data[i];
77   }
78 
append(const T & t)79   void append( const T& t )
80   {
81     ensureCapacity( m_size + 1 );
82     m_data[ m_size++ ] = t;
83   }
84 
insert(int i,const T & t)85   void insert( int i, const T& t )
86   {
87     if ( i==m_size ) {
88       append( t );
89     } else {
90       ASSERT( i < m_size );
91       ensureCapacity( m_size + 1 );
92       for ( int j=m_size-1; j>=i; j-- ) {
93 	m_data[j+1] = m_data[j];
94       }
95       m_data[ i ] = t;
96       m_size++;
97     }
98   }
99 
erase(int i)100   void erase( int i )
101   {
102     ASSERT( i < m_size );
103     if ( i < m_size-1 ) {
104       memcpy( m_data+i, m_data+i+1, (m_size-i-1)*sizeof(T) );
105     }
106     m_size--;
107   }
108 
trim(int i)109   void trim( int i )
110   {
111     ASSERT( i < m_size );
112     m_size -= i;
113   }
114 
capacity(int c)115   void capacity( int c )
116   {
117     if ( c >= m_size ) {
118       if ( m_capacity ) {
119 	m_data = (T*)realloc( m_data, c * sizeof(T) );
120       } else {
121 	m_data = (T*)malloc( c * sizeof(T) );
122       }
123       m_capacity = c;
124     }
125   }
126 
indexOf(const T & t)127   int indexOf( const T& t )
128   {
129     for ( int i=0; i<m_size; i++ ) {
130       if ( m_data[i] == t ) {
131 	return i;
132       }
133     }
134     return -1;
135   }
136 
137   T& operator[]( int i )
138   {
139     return at(i);
140   }
141 
142   const T& operator[]( int i ) const
143   {
144     return at(i);
145   }
146 
147   Array<T>& operator=(const Array<T>& other)
148   {
149     m_size = 0;
150     if ( other.size() ) {
151       capacity( other.size() );
152       memcpy( m_data, other.m_data, other.size() * sizeof(T) );
153       m_size = other.size();
154     }
155     return *this;
156   }
157 
158  private:
ensureCapacity(int c)159   void ensureCapacity( int c )
160   {
161     if ( c > m_capacity ) {
162       int newc = m_capacity ? m_capacity : 4;
163       while ( newc < c  ) {
164 	newc += newc;
165       }
166       capacity( newc );
167     }
168   }
169 
170   T* m_data;
171   int m_size;
172   int m_capacity;
173 };
174 
175 #endif //ARRAY_H
176