2 * Copyright (c) 2006-2010, KATO Noriaki
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * \brief vector
\83R
\83\93\83e
\83i
28 * \author KATO Noriaki <katono@users.sourceforge.jp>
30 * $URL: http://svn.sourceforge.jp/svnroot/cstl/tags/rel-0.7.0/cstl/vector.h $
31 * $Id: vector.h 328 2010-01-24 03:49:15Z katono $
33 #ifndef CSTL_VECTOR_H_INCLUDED
34 #define CSTL_VECTOR_H_INCLUDED
41 #ifndef CSTL_ALGORITHM_INTERFACE
42 #define CSTL_ALGORITHM_INTERFACE(Name, Type)
45 #ifndef CSTL_ALGORITHM_IMPLEMENT
46 #define CSTL_ALGORITHM_IMPLEMENT(Name, Type, DIRECT_ACCESS)
50 #define CSTL_VECTOR_AT(self, idx) (self)->buf[(idx)]
51 #define CSTL_VECTOR_SIZE(self) (self)->size
52 #define CSTL_VECTOR_EMPTY(self) ((self)->size == 0)
53 #define CSTL_VECTOR_CAPACITY(self) (self)->capacity
54 #define CSTL_VECTOR_FULL(self) (CSTL_VECTOR_SIZE((self)) == CSTL_VECTOR_CAPACITY((self)))
55 #define CSTL_VECTOR_CLEAR(self) do { (self)->size = 0; } while (0)
59 * \brief
\83C
\83\93\83^
\81[
\83t
\83F
\83C
\83X
\83}
\83N
\83\8d
61 * \param Name
\83R
\83\93\83e
\83i
\96¼
62 * \param Type
\97v
\91f
\82Ì
\8c^
64 #define CSTL_VECTOR_INTERFACE(Name, Type) \
65 typedef struct Name Name;\
67 CSTL_EXTERN_C_BEGIN()\
68 Name *Name##_new(void);\
69 Name *Name##_new_reserve(size_t n);\
70 void Name##_delete(Name *self);\
71 int Name##_push_back(Name *self, Type data);\
72 int Name##_push_back_ref(Name *self, Type const *data);\
73 void Name##_pop_back(Name *self);\
74 size_t Name##_size(Name *self);\
75 size_t Name##_capacity(Name *self);\
76 int Name##_empty(Name *self);\
77 void Name##_clear(Name *self);\
78 int Name##_reserve(Name *self, size_t n);\
79 void Name##_shrink(Name *self, size_t n);\
80 int Name##_resize(Name *self, size_t n, Type data);\
81 Type *Name##_at(Name *self, size_t idx);\
82 Type *Name##_front(Name *self);\
83 Type *Name##_back(Name *self);\
84 int Name##_insert(Name *self, size_t idx, Type data);\
85 int Name##_insert_ref(Name *self, size_t idx, Type const *data);\
86 int Name##_insert_n(Name *self, size_t idx, size_t n, Type data);\
87 int Name##_insert_n_ref(Name *self, size_t idx, size_t n, Type const *data);\
88 int Name##_insert_array(Name *self, size_t idx, Type const *data, size_t n);\
89 int Name##_insert_range(Name *self, size_t idx, Name *x, size_t xidx, size_t n);\
90 void Name##_erase(Name *self, size_t idx, size_t n);\
91 void Name##_swap(Name *self, Name *x);\
92 CSTL_ALGORITHM_INTERFACE(Name, Type)\
97 #define CSTL_VECTOR_IMPLEMENT_BASE(Name, Type) \
99 * \brief vector
\8d\
\91¢
\91Ì\
105 CSTL_MAGIC(Name *magic;)\
108 Name *Name##_new(void)\
111 self = (Name *) malloc(sizeof(Name));\
112 if (!self) return 0;\
116 CSTL_MAGIC(self->magic = self);\
120 Name *Name##_new_reserve(size_t n)\
123 self = Name##_new();\
124 if (!self) return 0;\
125 if (!Name##_reserve(self, n)) {\
126 Name##_delete(self);\
132 void Name##_delete(Name *self)\
135 CSTL_ASSERT(self->magic == self && "Vector_delete");\
136 CSTL_MAGIC(self->magic = 0);\
143 #define CSTL_VECTOR_IMPLEMENT_PUSH_BACK(Name, Type) \
144 int Name##_push_back(Name *self, Type data)\
146 CSTL_ASSERT(self && "Vector_push_back");\
147 CSTL_ASSERT(self->magic == self && "Vector_push_back");\
148 return Name##_push_back_ref(self, &data);\
151 int Name##_push_back_ref(Name *self, Type const *data)\
153 CSTL_ASSERT(self && "Vector_push_back_ref");\
154 CSTL_ASSERT(self->magic == self && "Vector_push_back_ref");\
155 CSTL_ASSERT(data && "Vector_push_back_ref");\
156 if (!Name##_expand(self, CSTL_VECTOR_SIZE(self) + 1)) return 0;\
157 self->buf[self->size] = *data;\
163 #define CSTL_VECTOR_IMPLEMENT_POP_BACK(Name, Type) \
164 void Name##_pop_back(Name *self)\
166 CSTL_ASSERT(self && "Vector_pop_back");\
167 CSTL_ASSERT(self->magic == self && "Vector_pop_back");\
168 CSTL_ASSERT(!CSTL_VECTOR_EMPTY(self) && "Vector_pop_back");\
173 #define CSTL_VECTOR_IMPLEMENT_SIZE(Name, Type) \
174 size_t Name##_size(Name *self)\
176 CSTL_ASSERT(self && "Vector_size");\
177 CSTL_ASSERT(self->magic == self && "Vector_size");\
178 return CSTL_VECTOR_SIZE(self);\
182 #define CSTL_VECTOR_IMPLEMENT_CAPACITY(Name, Type) \
183 size_t Name##_capacity(Name *self)\
185 CSTL_ASSERT(self && "Vector_capacity");\
186 CSTL_ASSERT(self->magic == self && "Vector_capacity");\
187 return CSTL_VECTOR_CAPACITY(self);\
191 #define CSTL_VECTOR_IMPLEMENT_EMPTY(Name, Type) \
192 int Name##_empty(Name *self)\
194 CSTL_ASSERT(self && "Vector_empty");\
195 CSTL_ASSERT(self->magic == self && "Vector_empty");\
196 return CSTL_VECTOR_EMPTY(self);\
200 #define CSTL_VECTOR_IMPLEMENT_CLEAR(Name, Type) \
201 void Name##_clear(Name *self)\
203 CSTL_ASSERT(self && "Vector_clear");\
204 CSTL_ASSERT(self->magic == self && "Vector_clear");\
205 CSTL_VECTOR_CLEAR(self);\
209 #define CSTL_VECTOR_IMPLEMENT_RESERVE(Name, Type) \
210 static int Name##_expand(Name *self, size_t size)\
213 if (size <= CSTL_VECTOR_CAPACITY(self)) return 1;\
214 n = (size > CSTL_VECTOR_CAPACITY(self) * 2) ? size : CSTL_VECTOR_CAPACITY(self) * 2;\
215 return Name##_reserve(self, n);\
218 int Name##_reserve(Name *self, size_t n)\
221 CSTL_ASSERT(self && "Vector_reserve");\
222 CSTL_ASSERT(self->magic == self && "Vector_reserve");\
223 if (n <= CSTL_VECTOR_CAPACITY(self)) return 1;\
224 if (n > ((size_t) -1) / sizeof(Type)) {\
225 /* sizeof(Type)*n
\82ª
\83I
\81[
\83o
\81[
\83t
\83\8d\81[
\82·
\82é */\
228 newbuf = (Type *) realloc(self->buf, sizeof(Type) * n);\
229 if (!newbuf) return 0;\
236 #define CSTL_VECTOR_IMPLEMENT_SHRINK(Name, Type) \
237 void Name##_shrink(Name *self, size_t n)\
240 CSTL_ASSERT(self && "Vector_shrink");\
241 CSTL_ASSERT(self->magic == self && "Vector_shrink");\
242 if (n >= CSTL_VECTOR_CAPACITY(self)) return;\
243 if (n < CSTL_VECTOR_SIZE(self)) {\
244 n = CSTL_VECTOR_SIZE(self);\
252 newbuf = (Type *) realloc(self->buf, sizeof(Type) * n);\
259 #define CSTL_VECTOR_IMPLEMENT_RESIZE(Name, Type) \
260 int Name##_resize(Name *self, size_t n, Type data)\
263 CSTL_ASSERT(self && "Vector_resize");\
264 CSTL_ASSERT(self->magic == self && "Vector_resize");\
265 size = CSTL_VECTOR_SIZE(self);\
270 if (!Name##_insert_n_no_data(self, size, n - size)) {\
273 for (i = size; i < n; i++) {\
274 CSTL_VECTOR_AT(self, i) = data;\
281 #define CSTL_VECTOR_IMPLEMENT_AT(Name, Type) \
282 Type *Name##_at(Name *self, size_t idx)\
284 CSTL_ASSERT(self && "Vector_at");\
285 CSTL_ASSERT(self->magic == self && "Vector_at");\
286 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) > idx && "Vector_at");\
287 return &CSTL_VECTOR_AT(self, idx);\
291 #define CSTL_VECTOR_IMPLEMENT_FRONT(Name, Type) \
292 Type *Name##_front(Name *self)\
294 CSTL_ASSERT(self && "Vector_front");\
295 CSTL_ASSERT(self->magic == self && "Vector_front");\
296 CSTL_ASSERT(!CSTL_VECTOR_EMPTY(self) && "Vector_front");\
297 return &self->buf[0];\
301 #define CSTL_VECTOR_IMPLEMENT_BACK(Name, Type) \
302 Type *Name##_back(Name *self)\
304 CSTL_ASSERT(self && "Vector_back");\
305 CSTL_ASSERT(self->magic == self && "Vector_back");\
306 CSTL_ASSERT(!CSTL_VECTOR_EMPTY(self) && "Vector_back");\
307 return &self->buf[self->size - 1];\
311 #define CSTL_VECTOR_IMPLEMENT_MOVE_BACKWARD(Name, Type) \
312 static void Name##_move_backward(Name *self, size_t first, size_t last, size_t n)\
314 memmove(&self->buf[first + n], &self->buf[first], sizeof(Type) * (last - first));\
318 #define CSTL_VECTOR_IMPLEMENT_MOVE_FORWARD(Name, Type) \
319 static void Name##_move_forward(Name *self, size_t first, size_t last, size_t n)\
321 memmove(&self->buf[first - n], &self->buf[first], sizeof(Type) * (last - first));\
325 #define CSTL_VECTOR_IMPLEMENT_INSERT_N_NO_DATA(Name, Type) \
326 static int Name##_insert_n_no_data(Name *self, size_t idx, size_t n)\
328 if (!Name##_expand(self, CSTL_VECTOR_SIZE(self) + n)) return 0;\
329 Name##_move_backward(self, idx, self->size, n);\
335 #define CSTL_VECTOR_IMPLEMENT_INSERT(Name, Type) \
336 int Name##_insert(Name *self, size_t idx, Type data)\
338 CSTL_ASSERT(self && "Vector_insert");\
339 CSTL_ASSERT(self->magic == self && "Vector_insert");\
340 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) >= idx && "Vector_insert");\
341 return Name##_insert_n_ref(self, idx, 1, &data);\
344 int Name##_insert_ref(Name *self, size_t idx, Type const *data)\
346 CSTL_ASSERT(self && "Vector_insert_ref");\
347 CSTL_ASSERT(self->magic == self && "Vector_insert_ref");\
348 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) >= idx && "Vector_insert_ref");\
349 CSTL_ASSERT(data && "Vector_insert_ref");\
350 return Name##_insert_n_ref(self, idx, 1, data);\
354 #define CSTL_VECTOR_IMPLEMENT_INSERT_N(Name, Type) \
355 int Name##_insert_n(Name *self, size_t idx, size_t n, Type data)\
357 CSTL_ASSERT(self && "Vector_insert_n");\
358 CSTL_ASSERT(self->magic == self && "Vector_insert_n");\
359 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) >= idx && "Vector_insert_n");\
360 return Name##_insert_n_ref(self, idx, n, &data);\
363 int Name##_insert_n_ref(Name *self, size_t idx, size_t n, Type const *data)\
366 CSTL_ASSERT(self && "Vector_insert_n_ref");\
367 CSTL_ASSERT(self->magic == self && "Vector_insert_n_ref");\
368 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) >= idx && "Vector_insert_n_ref");\
369 CSTL_ASSERT(data && "Vector_insert_n_ref");\
370 if (!Name##_insert_n_no_data(self, idx, n)) {\
373 for (i = 0; i < n; i++) {\
374 self->buf[idx + i] = *data;\
380 #define CSTL_VECTOR_IMPLEMENT_INSERT_ARRAY(Name, Type) \
381 int Name##_insert_array(Name *self, size_t idx, Type const *data, size_t n)\
383 CSTL_ASSERT(self && "Vector_insert_array");\
384 CSTL_ASSERT(self->magic == self && "Vector_insert_array");\
385 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) >= idx && "Vector_insert_array");\
386 CSTL_ASSERT(data && "Vector_insert_array");\
387 if (!Name##_insert_n_no_data(self, idx, n)) {\
390 memcpy(&self->buf[idx], data, sizeof(Type) * n);\
395 #define CSTL_VECTOR_IMPLEMENT_INSERT_RANGE(Name, Type) \
396 int Name##_insert_range(Name *self, size_t idx, Name *x, size_t xidx, size_t n)\
398 CSTL_ASSERT(self && "Vector_insert_range");\
399 CSTL_ASSERT(self->magic == self && "Vector_insert_range");\
400 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) >= idx && "Vector_insert_range");\
401 CSTL_ASSERT(x && "Vector_insert_range");\
402 CSTL_ASSERT(x->magic == x && "Vector_insert_range");\
403 CSTL_ASSERT(CSTL_VECTOR_SIZE(x) >= xidx + n && "Vector_insert_range");\
404 CSTL_ASSERT(CSTL_VECTOR_SIZE(x) >= n && "Vector_insert_range");\
405 CSTL_ASSERT(CSTL_VECTOR_SIZE(x) > xidx && "Vector_insert_range");\
406 if (!Name##_insert_n_no_data(self, idx, n)) {\
411 memcpy(&CSTL_VECTOR_AT(self, idx), &CSTL_VECTOR_AT(self, xidx + n), sizeof(Type) * n);\
412 } else if (xidx < idx && idx < xidx + n) {\
413 memcpy(&CSTL_VECTOR_AT(self, idx), &CSTL_VECTOR_AT(self, xidx), sizeof(Type) * (idx - xidx));\
414 memcpy(&CSTL_VECTOR_AT(self, idx + (idx - xidx)), &CSTL_VECTOR_AT(self, idx + n), sizeof(Type) * (n - (idx - xidx)));\
416 memcpy(&CSTL_VECTOR_AT(self, idx), &CSTL_VECTOR_AT(self, xidx), sizeof(Type) * n);\
419 memcpy(&CSTL_VECTOR_AT(self, idx), &CSTL_VECTOR_AT(x, xidx), sizeof(Type) * n);\
425 #define CSTL_VECTOR_IMPLEMENT_ERASE(Name, Type) \
426 void Name##_erase(Name *self, size_t idx, size_t n)\
428 CSTL_ASSERT(self && "Vector_erase");\
429 CSTL_ASSERT(self->magic == self && "Vector_erase");\
430 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) >= idx + n && "Vector_erase");\
431 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) >= n && "Vector_erase");\
432 CSTL_ASSERT(CSTL_VECTOR_SIZE(self) > idx && "Vector_erase");\
433 Name##_move_forward(self, idx + n, self->size, n);\
438 #define CSTL_VECTOR_IMPLEMENT_SWAP(Name, Type) \
439 void Name##_swap(Name *self, Name *x)\
442 size_t tmp_capacity;\
444 CSTL_ASSERT(self && "Vector_swap");\
445 CSTL_ASSERT(x && "Vector_swap");\
446 CSTL_ASSERT(self->magic == self && "Vector_swap");\
447 CSTL_ASSERT(x->magic == x && "Vector_swap");\
448 tmp_size = self->size;\
449 tmp_capacity = self->capacity;\
450 tmp_buf = self->buf;\
451 self->size = x->size;\
452 self->capacity = x->capacity;\
455 x->capacity = tmp_capacity;\
462 * \brief
\8eÀ
\91\95\83}
\83N
\83\8d
464 * \param Name
\83R
\83\93\83e
\83i
\96¼
465 * \param Type
\97v
\91f
\82Ì
\8c^
467 #define CSTL_VECTOR_IMPLEMENT(Name, Type) \
468 CSTL_VECTOR_IMPLEMENT_BASE(Name, Type)\
469 CSTL_VECTOR_IMPLEMENT_RESERVE(Name, Type)\
470 CSTL_VECTOR_IMPLEMENT_MOVE_FORWARD(Name, Type)\
471 CSTL_VECTOR_IMPLEMENT_MOVE_BACKWARD(Name, Type)\
472 CSTL_VECTOR_IMPLEMENT_INSERT_N_NO_DATA(Name, Type)\
473 CSTL_VECTOR_IMPLEMENT_PUSH_BACK(Name, Type)\
474 CSTL_VECTOR_IMPLEMENT_POP_BACK(Name, Type)\
475 CSTL_VECTOR_IMPLEMENT_SIZE(Name, Type)\
476 CSTL_VECTOR_IMPLEMENT_CAPACITY(Name, Type)\
477 CSTL_VECTOR_IMPLEMENT_EMPTY(Name, Type)\
478 CSTL_VECTOR_IMPLEMENT_CLEAR(Name, Type)\
479 CSTL_VECTOR_IMPLEMENT_SHRINK(Name, Type)\
480 CSTL_VECTOR_IMPLEMENT_RESIZE(Name, Type)\
481 CSTL_VECTOR_IMPLEMENT_AT(Name, Type)\
482 CSTL_VECTOR_IMPLEMENT_FRONT(Name, Type)\
483 CSTL_VECTOR_IMPLEMENT_BACK(Name, Type)\
484 CSTL_VECTOR_IMPLEMENT_INSERT(Name, Type)\
485 CSTL_VECTOR_IMPLEMENT_INSERT_N(Name, Type)\
486 CSTL_VECTOR_IMPLEMENT_INSERT_ARRAY(Name, Type)\
487 CSTL_VECTOR_IMPLEMENT_INSERT_RANGE(Name, Type)\
488 CSTL_VECTOR_IMPLEMENT_ERASE(Name, Type)\
489 CSTL_VECTOR_IMPLEMENT_SWAP(Name, Type)\
490 CSTL_ALGORITHM_IMPLEMENT(Name, Type, CSTL_VECTOR_AT)\
493 #endif /* CSTL_VECTOR_H_INCLUDED */