3 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 enum { d_none, d_delete, d_array, d_free, };
30 void reallocate(int n);
31 void del(TYPE &value) {
33 case d_delete: delete value; break;
34 case d_array: delete [] value; break;
35 case d_free: free((void*)value); break;
38 void del_value(int i) { del(values[i]); }
39 static int cmpr(TYPE *a, TYPE *b) {
40 if( *a == *b ) return 0;
41 return *a > *b ? 1 : -1;
47 void allocate(int total) { if( total >= avail ) reallocate(total); }
50 if( total >= avail ) reallocate(total*2);
53 TYPE &append(TYPE value) { return append() = value; }
54 TYPE &insert(TYPE value, int n) {
56 for(int i=total; --i>n; ) values[i]=values[i-1];
57 return values[n] = value;
59 void remove() { --total; }
60 void remove_object() {
61 if( total > 0 ) { del_value(total-1); remove(); }
62 else fprintf(stderr, "ArrayList<TYPE>::remove_object: array is 0 length.\n");
64 void remove_number(int n) {
65 if( n >= total ) return;
66 while( ++n<total ) values[n-1]=values[n];
69 void remove_block(int i, int n) {
70 if( i >= total || !n ) return;
71 for( n+=i; n<total; ++i,++n ) values[i] = values[n];
74 void remove_object_block(int i, int n) {
75 if( i >= total || !n ) return;
76 for( int j=i,k=n; --k>=0 && j<total; ++j ) del_value(j);
77 for( n+=i; n<total; ++i,++n ) values[i] = values[n];
80 void remove(TYPE value) {
82 for( int in=0; in<total; ++in )
83 if( values[in] != value ) values[out++] = values[in];
86 void remove_object(TYPE value) { remove(value); del(value); }
87 void remove_object_number(int i) {
88 if( i < total ) { del_value(i); remove_number(i); }
89 else fprintf(stderr, "ArrayList<TYPE>::remove_object_number:"
90 " number %d out of range %d.\n", i, total);
92 int number_of(TYPE value) {
93 for( int i=0; i<total; ++i )
94 if( values[i] == value ) return i;
97 void remove_all() { total = 0; }
98 void remove_all_objects() {
99 for( int i=0; i<total; ++i ) del(values[i]);
102 TYPE &last() { return values[total - 1]; }
104 void set_array_delete() { dtype = d_array; }
105 void set_free() { dtype = d_free; }
106 int size() { return total; }
108 if( i < total ) return values[i];
109 fprintf(stderr,"ArrayList<TYPE>::get number=%d total=%d\n",i,total);
112 TYPE set(int i, TYPE value) {
113 if( i < total ) return values[i] = value;
114 fprintf(stderr,"ArrayList<TYPE>::set number=%d total=%d\n",i,total);
117 TYPE &operator [](int i) { return values[i]; }
118 void sort(int (*cmp)(TYPE *a, TYPE *b) = 0) {
119 return qsort(values, size(), sizeof(TYPE),
120 (int(*)(const void *, const void *))(cmp ? cmp : cmpr));
123 ArrayList() { total = 0; dtype = d_delete; values = new TYPE[avail = 16]; }
124 ~ArrayList() { delete [] values; }
128 void ArrayList<TYPE>::reallocate(int n)
130 TYPE* newvalues = new TYPE[avail=n];
131 for( int i=total; --i>=0; ) newvalues[i] = values[i];
132 delete [] values; values = newvalues;