4 * \brief Operations on vectors.
6 * \author this file, vector.c, was written and is
7 * Copyright (c) 2001 C. Scott Ananian.
11 * <h1><b>Copyright.</b></h1>\n
13 * PCB, interactive printed circuit board design
15 * Copyright (C) 1994,1995,1996 Thomas Nau
17 * Copyright (C) 1998,1999,2000,2001 harry eaton
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 * Contact addresses for paper mail and Email:
35 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
37 * haceaton@aplcomm.jhuapl.edu
53 #ifdef HAVE_LIBDMALLOC
57 /* ---------------------------------------------------------------------------
58 * some local prototypes
61 /* ---------------------------------------------------------------------------
66 vector_element_t
*element
;
70 /* ---------------------------------------------------------------------------
71 * some local identifiers
74 /* ---------------------------------------------------------------------------
80 * \brief Helper function for assertions.
83 __vector_is_good (vector_t
* vector
)
85 return vector
&& (vector
->max
== 0 || vector
->element
) &&
86 (vector
->max
>= 0) && (vector
->size
>= 0) &&
87 (vector
->size
<= vector
->max
) && 1;
92 * \brief Create an empty vector.
98 /* okay, create empty vector */
99 vector
= (vector_t
*)calloc (1, sizeof (*vector
));
101 assert (__vector_is_good (vector
));
106 * \brief Destroy a vector.
109 vector_destroy (vector_t
** vector
)
111 assert (vector
&& *vector
);
112 assert (__vector_is_good (*vector
));
113 if ((*vector
)->element
)
114 free ((*vector
)->element
);
119 /* -- interrogation -- */
121 vector_is_empty (vector_t
* vector
)
123 assert (__vector_is_good (vector
));
124 return (vector
->size
== 0);
128 vector_size (vector_t
* vector
)
130 assert (__vector_is_good (vector
));
131 return (vector
->size
);
135 vector_element (vector_t
* vector
, int N
)
137 assert (__vector_is_good (vector
));
138 assert (N
< vector
->size
);
139 return vector
->element
[N
];
143 * \brief Return the first element of the vector.
146 vector_element_first (vector_t
* vector
)
148 assert (__vector_is_good (vector
));
149 assert (vector
->size
> 0);
150 return vector_element (vector
, 0);
154 * \brief Return the last element of the vector.
157 vector_element_last (vector_t
* vector
)
159 assert (__vector_is_good (vector
));
160 assert (vector
->size
> 0);
161 return vector_element (vector
, vector
->size
- 1);
166 * \brief Add data to end of vector.
169 vector_append (vector_t
* vector
, vector_element_t data
)
171 vector_insert_many (vector
, vector
->size
, &data
, 1);
175 * \brief Add multiple elements to end of vector.
178 vector_append_many (vector_t
* vector
, vector_element_t data
[], int count
)
180 vector_insert_many (vector
, vector
->size
, data
, count
);
184 * \brief Add a vector of elements to the end of vector.
187 vector_append_vector (vector_t
* vector
, vector_t
* other_vector
)
189 vector_append_many (vector
, other_vector
->element
, other_vector
->size
);
193 * \brief Add data at specified position of vector.
196 vector_insert (vector_t
* vector
, int N
, vector_element_t data
)
198 vector_insert_many (vector
, N
, &data
, 1);
202 * \brief Add data at specified position of vector.
205 vector_insert_many (vector_t
* vector
, int N
,
206 vector_element_t data
[], int count
)
208 assert (__vector_is_good (vector
));
209 assert (N
<= vector
->size
);
212 assert (data
&& count
> 0);
213 if (vector
->size
+ count
> vector
->max
)
215 vector
->max
= MAX (32, MAX (vector
->size
+ count
, vector
->max
* 2));
216 vector
->element
= (void **)realloc (vector
->element
,
217 vector
->max
* sizeof (*vector
->element
));
219 memmove (vector
->element
+ N
+ count
, vector
->element
+ N
,
220 (vector
->size
- N
) * sizeof (*vector
->element
));
221 memmove (vector
->element
+ N
, data
, count
* sizeof (*data
));
222 vector
->size
+= count
;
223 assert (__vector_is_good (vector
));
227 * \brief Copy a vector.
230 vector_duplicate (vector_t
* orig
)
232 vector_t
* newone
= vector_create();
235 newone
->element
= (void **)malloc (orig
->max
* sizeof (*orig
->element
));
236 newone
->max
= orig
->max
;
237 newone
->size
= orig
->size
;
238 memcpy (newone
->element
, orig
->element
, orig
->size
* sizeof (vector_element_t
));
239 assert (__vector_is_good (newone
));
244 * \brief Return and delete the *last* element of vector.
247 vector_remove_last (vector_t
* vector
)
249 assert (vector
->size
> 0);
250 return vector_remove (vector
, vector
->size
- 1);
254 * \brief Rreturn and delete data at specified position of vector.
257 vector_remove (vector_t
* vector
, int N
)
259 vector_element_t old
;
260 assert (__vector_is_good (vector
));
261 assert (N
< vector
->size
);
262 old
= vector
->element
[N
];
263 memmove (vector
->element
+ N
, vector
->element
+ N
+ 1,
264 (vector
->size
- (N
+ 1)) * sizeof (*vector
->element
));
266 assert (__vector_is_good (vector
));
271 * \brief Replace the data at the specified position with the given
274 * \return the old data.
277 vector_replace (vector_t
* vector
, vector_element_t data
, int N
)
279 vector_element_t old
;
280 assert (__vector_is_good (vector
));
281 assert (N
< vector
->size
);
282 old
= vector
->element
[N
];
283 vector
->element
[N
] = data
;
284 assert (__vector_is_good (vector
));