4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996 Thomas Nau
6 * Copyright (C) 1998,1999,2000,2001 harry eaton
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Contact addresses for paper mail and Email:
23 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
24 * haceaton@aplcomm.jhuapl.edu
28 /* this file, vector.c, was written and is
29 * Copyright (c) 2001 C. Scott Ananian.
32 /* operations on vectors.
48 #ifdef HAVE_LIBDMALLOC
52 /* ---------------------------------------------------------------------------
53 * some local prototypes
56 /* ---------------------------------------------------------------------------
61 vector_element_t
*element
;
65 /* ---------------------------------------------------------------------------
66 * some local identifiers
69 /* ---------------------------------------------------------------------------
73 /* helper function for assertions */
76 __vector_is_good (vector_t
* vector
)
78 return vector
&& (vector
->max
== 0 || vector
->element
) &&
79 (vector
->max
>= 0) && (vector
->size
>= 0) &&
80 (vector
->size
<= vector
->max
) && 1;
84 /* create an empty vector */
89 /* okay, create empty vector */
90 vector
= (vector_t
*)calloc (1, sizeof (*vector
));
92 assert (__vector_is_good (vector
));
96 /* destroy a vector */
98 vector_destroy (vector_t
** vector
)
100 assert (vector
&& *vector
);
101 assert (__vector_is_good (*vector
));
102 if ((*vector
)->element
)
103 free ((*vector
)->element
);
108 /* -- interrogation -- */
110 vector_is_empty (vector_t
* vector
)
112 assert (__vector_is_good (vector
));
113 return (vector
->size
== 0);
117 vector_size (vector_t
* vector
)
119 assert (__vector_is_good (vector
));
120 return (vector
->size
);
124 vector_element (vector_t
* vector
, int N
)
126 assert (__vector_is_good (vector
));
127 assert (N
< vector
->size
);
128 return vector
->element
[N
];
131 /* return the first element of the vector. */
133 vector_element_first (vector_t
* vector
)
135 assert (__vector_is_good (vector
));
136 assert (vector
->size
> 0);
137 return vector_element (vector
, 0);
140 /* return the last element of the vector. */
142 vector_element_last (vector_t
* vector
)
144 assert (__vector_is_good (vector
));
145 assert (vector
->size
> 0);
146 return vector_element (vector
, vector
->size
- 1);
150 /* add data to end of vector */
152 vector_append (vector_t
* vector
, vector_element_t data
)
154 vector_insert_many (vector
, vector
->size
, &data
, 1);
158 vector_append_many (vector_t
* vector
, vector_element_t data
[], int count
)
160 vector_insert_many (vector
, vector
->size
, data
, count
);
164 vector_append_vector (vector_t
* vector
, vector_t
* other_vector
)
166 vector_append_many (vector
, other_vector
->element
, other_vector
->size
);
170 vector_insert (vector_t
* vector
, int N
, vector_element_t data
)
172 vector_insert_many (vector
, N
, &data
, 1);
175 /* add data at specified position of vector */
177 vector_insert_many (vector_t
* vector
, int N
,
178 vector_element_t data
[], int count
)
180 assert (__vector_is_good (vector
));
181 assert (N
<= vector
->size
);
184 assert (data
&& count
> 0);
185 if (vector
->size
+ count
> vector
->max
)
187 vector
->max
= MAX (32, MAX (vector
->size
+ count
, vector
->max
* 2));
188 vector
->element
= (void **)realloc (vector
->element
,
189 vector
->max
* sizeof (*vector
->element
));
191 memmove (vector
->element
+ N
+ count
, vector
->element
+ N
,
192 (vector
->size
- N
) * sizeof (*vector
->element
));
193 memmove (vector
->element
+ N
, data
, count
* sizeof (*data
));
194 vector
->size
+= count
;
195 assert (__vector_is_good (vector
));
199 vector_duplicate (vector_t
* orig
)
201 vector_t
* newone
= vector_create();
204 newone
->element
= (void **)malloc (orig
->max
* sizeof (*orig
->element
));
205 newone
->max
= orig
->max
;
206 newone
->size
= orig
->size
;
207 memcpy (newone
->element
, orig
->element
, orig
->size
* sizeof (vector_element_t
));
208 assert (__vector_is_good (newone
));
212 /* return and delete the *last* element of vector */
214 vector_remove_last (vector_t
* vector
)
216 assert (vector
->size
> 0);
217 return vector_remove (vector
, vector
->size
- 1);
220 /* return and delete data at specified position of vector */
222 vector_remove (vector_t
* vector
, int N
)
224 vector_element_t old
;
225 assert (__vector_is_good (vector
));
226 assert (N
< vector
->size
);
227 old
= vector
->element
[N
];
228 memmove (vector
->element
+ N
, vector
->element
+ N
+ 1,
229 (vector
->size
- (N
+ 1)) * sizeof (*vector
->element
));
231 assert (__vector_is_good (vector
));
235 /* replace the data at the specified position with the given data.
236 * returns the old data. */
238 vector_replace (vector_t
* vector
, vector_element_t data
, int N
)
240 vector_element_t old
;
241 assert (__vector_is_good (vector
));
242 assert (N
< vector
->size
);
243 old
= vector
->element
[N
];
244 vector
->element
[N
] = data
;
245 assert (__vector_is_good (vector
));