Credit Andrew - fix vorbis audio which was scratchy and ensure aging plugin does...
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / arraylist.h
1 /*
2  * CINELERRA
3  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
4  * 
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.
9  * 
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.
14  * 
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
18  * 
19  */
20
21 #ifndef ARRAYLIST_H
22 #define ARRAYLIST_H
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 template<class TYPE>
27 class ArrayList {
28         enum { d_none, d_delete, d_array, d_free, };
29         int avail, dtype;
30         void reallocate(int n);
31         void del(TYPE &value) {
32                 switch( dtype ) {
33                 case d_delete: delete value;        break;
34                 case d_array:  delete [] value;     break;
35                 case d_free:   free((void*)value);  break;
36                 }
37         }
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;
42         }
43 public:
44         int total;
45         TYPE* values;
46
47         void allocate(int total) { if( total >= avail ) reallocate(total); }
48         TYPE &append() {
49                 int i = total++;
50                 if( total >= avail ) reallocate(total*2);
51                 return values[i];
52         }
53         TYPE &append(TYPE value) { return append() = value; }
54         TYPE &insert(TYPE value, int n) {
55                 append();
56                 for(int i=total; --i>n; ) values[i]=values[i-1];
57                 return values[n] = value;
58         }
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");
63         }
64         void remove_number(int n) {
65                 if( n >= total ) return;
66                 while( ++n<total ) values[n-1]=values[n];
67                 remove();
68         }
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];
72                 total = i;
73         }
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];
78                 total = i;
79         }
80         void remove(TYPE value) {
81                 int out = 0;
82                 for( int in=0; in<total; ++in )
83                         if( values[in] != value ) values[out++] = values[in];
84                 total = out;
85         }
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);
91         }
92         int number_of(TYPE value) {
93                 for( int i=0; i<total; ++i )
94                         if( values[i] == value ) return i;
95                 return -1;
96         }
97         void remove_all() { total = 0; }
98         void remove_all_objects() {
99                 for( int i=0; i<total; ++i ) del(values[i]);
100                 total = 0;
101         }
102         TYPE &last() { return values[total - 1]; }
103
104         void set_array_delete() { dtype = d_array; }
105         void set_free() { dtype = d_free; }
106         int size() { return total; }
107         TYPE get(int i) {
108                 if( i < total ) return values[i];
109                 fprintf(stderr,"ArrayList<TYPE>::get number=%d total=%d\n",i,total);
110                 return 0;
111         }
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);
115                 return 0;
116         }
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));
121         }
122
123         ArrayList() { total = 0; dtype = d_delete;  values = new TYPE[avail = 16]; }
124         ~ArrayList() { delete [] values; }
125 };
126
127 template<class TYPE>
128 void ArrayList<TYPE>::reallocate(int n)
129 {
130         TYPE* newvalues = new TYPE[avail=n];
131         for( int i=total; --i>=0; ) newvalues[i] = values[i];
132         delete [] values;  values = newvalues;
133 }
134
135
136 #endif