6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996 Thomas Nau
8 * Copyright (C) 1998,1999,2000,2001 harry eaton
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Contact addresses for paper mail and Email:
25 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
26 * haceaton@aplcomm.jhuapl.edu
30 /* this file, vector.c, was written and is
31 * Copyright (c) 2001 C. Scott Ananian.
34 /* operations on vectors.
50 #ifdef HAVE_LIBDMALLOC
56 /* ---------------------------------------------------------------------------
57 * some local prototypes
60 /* ---------------------------------------------------------------------------
65 vector_element_t
*element
;
69 /* ---------------------------------------------------------------------------
70 * some local identifiers
73 /* ---------------------------------------------------------------------------
77 /* helper function for assertions */
80 __vector_is_good (vector_t
* vector
)
82 return vector
&& (vector
->max
== 0 || vector
->element
) &&
83 (vector
->max
>= 0) && (vector
->size
>= 0) &&
84 (vector
->size
<= vector
->max
) && 1;
88 /* create an empty vector */
93 /* okay, create empty vector */
94 vector
= calloc (1, sizeof (*vector
));
96 assert (__vector_is_good (vector
));
100 /* destroy a vector */
102 vector_destroy (vector_t
** vector
)
104 assert (vector
&& *vector
);
105 assert (__vector_is_good (*vector
));
106 if ((*vector
)->element
)
107 free ((*vector
)->element
);
112 /* -- interrogation -- */
114 vector_is_empty (vector_t
* vector
)
116 assert (__vector_is_good (vector
));
117 return (vector
->size
== 0);
121 vector_size (vector_t
* vector
)
123 assert (__vector_is_good (vector
));
124 return (vector
->size
);
128 vector_element (vector_t
* vector
, int N
)
130 assert (__vector_is_good (vector
));
131 assert (N
< vector
->size
);
132 return vector
->element
[N
];
135 /* return the first element of the vector. */
137 vector_element_first (vector_t
* vector
)
139 assert (__vector_is_good (vector
));
140 assert (vector
->size
> 0);
141 return vector_element (vector
, 0);
144 /* return the last element of the vector. */
146 vector_element_last (vector_t
* vector
)
148 assert (__vector_is_good (vector
));
149 assert (vector
->size
> 0);
150 return vector_element (vector
, vector
->size
- 1);
154 /* add data to end of vector */
156 vector_append (vector_t
* vector
, vector_element_t data
)
158 vector_insert_many (vector
, vector
->size
, &data
, 1);
162 vector_append_many (vector_t
* vector
, vector_element_t data
[], int count
)
164 vector_insert_many (vector
, vector
->size
, data
, count
);
168 vector_append_vector (vector_t
* vector
, vector_t
* other_vector
)
170 vector_append_many (vector
, other_vector
->element
, other_vector
->size
);
174 vector_insert (vector_t
* vector
, int N
, vector_element_t data
)
176 vector_insert_many (vector
, N
, &data
, 1);
179 /* add data at specified position of vector */
181 vector_insert_many (vector_t
* vector
, int N
,
182 vector_element_t data
[], int count
)
184 assert (__vector_is_good (vector
));
185 assert (N
<= vector
->size
);
188 assert (data
&& count
> 0);
189 if (vector
->size
+ count
> vector
->max
)
191 vector
->max
= MAX (32, MAX (vector
->size
+ count
, vector
->max
* 2));
192 vector
->element
= realloc (vector
->element
,
193 vector
->max
* sizeof (*vector
->element
));
195 memmove (vector
->element
+ N
+ count
, vector
->element
+ N
,
196 (vector
->size
- N
) * sizeof (*vector
->element
));
197 memmove (vector
->element
+ N
, data
, count
* sizeof (*data
));
198 vector
->size
+= count
;
199 assert (__vector_is_good (vector
));
203 vector_duplicate (vector_t
* orig
)
205 vector_t
* new = vector_create();
208 new->element
= malloc (orig
->max
* sizeof (*orig
->element
));
209 new->max
= orig
->max
;
210 new->size
= orig
->size
;
211 memcpy (new->element
, orig
->element
, orig
->size
* sizeof (vector_element_t
));
212 assert (__vector_is_good (new));
216 /* return and delete the *last* element of vector */
218 vector_remove_last (vector_t
* vector
)
220 assert (vector
->size
> 0);
221 return vector_remove (vector
, vector
->size
- 1);
224 /* return and delete data at specified position of vector */
226 vector_remove (vector_t
* vector
, int N
)
228 vector_element_t old
;
229 assert (__vector_is_good (vector
));
230 assert (N
< vector
->size
);
231 old
= vector
->element
[N
];
232 memmove (vector
->element
+ N
, vector
->element
+ N
+ 1,
233 (vector
->size
- (N
+ 1)) * sizeof (*vector
->element
));
235 assert (__vector_is_good (vector
));
239 /* replace the data at the specified position with the given data.
240 * returns the old data. */
242 vector_replace (vector_t
* vector
, vector_element_t data
, int N
)
244 vector_element_t old
;
245 assert (__vector_is_good (vector
));
246 assert (N
< vector
->size
);
247 old
= vector
->element
[N
];
248 vector
->element
[N
] = data
;
249 assert (__vector_is_good (vector
));