OSDN Git Service

2011/12/29 23:57:10
[nlite/nlite.git] / include / cstl / vector.h
1 /* 
2  * Copyright (c) 2006-2010, KATO Noriaki
3  * All rights reserved.
4  * 
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * 
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.
13  * 
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.
24  */
25 /*! 
26  * \file vector.h
27  * \brief vector\83R\83\93\83e\83i
28  * \author KATO Noriaki <katono@users.sourceforge.jp>
29  * \date 2006-11-29
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 $
32  */
33 #ifndef CSTL_VECTOR_H_INCLUDED
34 #define CSTL_VECTOR_H_INCLUDED
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include "common.h"
39
40
41 #ifndef CSTL_ALGORITHM_INTERFACE
42 #define CSTL_ALGORITHM_INTERFACE(Name, Type)
43 #endif
44
45 #ifndef CSTL_ALGORITHM_IMPLEMENT
46 #define CSTL_ALGORITHM_IMPLEMENT(Name, Type, DIRECT_ACCESS)
47 #endif
48
49
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)
56
57
58 /*! 
59  * \brief \83C\83\93\83^\81[\83t\83F\83C\83X\83}\83N\83\8d
60  * 
61  * \param Name \83R\83\93\83e\83i\96¼
62  * \param Type \97v\91f\82Ì\8c^
63  */
64 #define CSTL_VECTOR_INTERFACE(Name, Type)       \
65 typedef struct Name Name;\
66 \
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)\
93 CSTL_EXTERN_C_END()\
94
95
96
97 #define CSTL_VECTOR_IMPLEMENT_BASE(Name, Type)  \
98 /*! \
99  * \brief vector\8d\\91¢\91Ì\
100  */\
101 struct Name {\
102         size_t size;\
103         size_t capacity;\
104         Type *buf;\
105         CSTL_MAGIC(Name *magic;)\
106 };\
107 \
108 Name *Name##_new(void)\
109 {\
110         Name *self;\
111         self = (Name *) malloc(sizeof(Name));\
112         if (!self) return 0;\
113         self->capacity = 0;\
114         self->size = 0;\
115         self->buf = 0;\
116         CSTL_MAGIC(self->magic = self);\
117         return self;\
118 }\
119 \
120 Name *Name##_new_reserve(size_t n)\
121 {\
122         Name *self;\
123         self = Name##_new();\
124         if (!self) return 0;\
125         if (!Name##_reserve(self, n)) {\
126                 Name##_delete(self);\
127                 return 0;\
128         }\
129         return self;\
130 }\
131 \
132 void Name##_delete(Name *self)\
133 {\
134         if (!self) return;\
135         CSTL_ASSERT(self->magic == self && "Vector_delete");\
136         CSTL_MAGIC(self->magic = 0);\
137         free(self->buf);\
138         free(self);\
139 }\
140 \
141
142
143 #define CSTL_VECTOR_IMPLEMENT_PUSH_BACK(Name, Type)     \
144 int Name##_push_back(Name *self, Type data)\
145 {\
146         CSTL_ASSERT(self && "Vector_push_back");\
147         CSTL_ASSERT(self->magic == self && "Vector_push_back");\
148         return Name##_push_back_ref(self, &data);\
149 }\
150 \
151 int Name##_push_back_ref(Name *self, Type const *data)\
152 {\
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;\
158         self->size++;\
159         return 1;\
160 }\
161 \
162
163 #define CSTL_VECTOR_IMPLEMENT_POP_BACK(Name, Type)      \
164 void Name##_pop_back(Name *self)\
165 {\
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");\
169         self->size--;\
170 }\
171 \
172
173 #define CSTL_VECTOR_IMPLEMENT_SIZE(Name, Type)  \
174 size_t Name##_size(Name *self)\
175 {\
176         CSTL_ASSERT(self && "Vector_size");\
177         CSTL_ASSERT(self->magic == self && "Vector_size");\
178         return CSTL_VECTOR_SIZE(self);\
179 }\
180 \
181
182 #define CSTL_VECTOR_IMPLEMENT_CAPACITY(Name, Type)      \
183 size_t Name##_capacity(Name *self)\
184 {\
185         CSTL_ASSERT(self && "Vector_capacity");\
186         CSTL_ASSERT(self->magic == self && "Vector_capacity");\
187         return CSTL_VECTOR_CAPACITY(self);\
188 }\
189 \
190
191 #define CSTL_VECTOR_IMPLEMENT_EMPTY(Name, Type) \
192 int Name##_empty(Name *self)\
193 {\
194         CSTL_ASSERT(self && "Vector_empty");\
195         CSTL_ASSERT(self->magic == self && "Vector_empty");\
196         return CSTL_VECTOR_EMPTY(self);\
197 }\
198 \
199
200 #define CSTL_VECTOR_IMPLEMENT_CLEAR(Name, Type) \
201 void Name##_clear(Name *self)\
202 {\
203         CSTL_ASSERT(self && "Vector_clear");\
204         CSTL_ASSERT(self->magic == self && "Vector_clear");\
205         CSTL_VECTOR_CLEAR(self);\
206 }\
207 \
208
209 #define CSTL_VECTOR_IMPLEMENT_RESERVE(Name, Type)       \
210 static int Name##_expand(Name *self, size_t size)\
211 {\
212         size_t n;\
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);\
216 }\
217 \
218 int Name##_reserve(Name *self, size_t n)\
219 {\
220         Type *newbuf;\
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é */\
226                 return 0;\
227         }\
228         newbuf = (Type *) realloc(self->buf, sizeof(Type) * n);\
229         if (!newbuf) return 0;\
230         self->buf = newbuf;\
231         self->capacity = n;\
232         return 1;\
233 }\
234 \
235
236 #define CSTL_VECTOR_IMPLEMENT_SHRINK(Name, Type)        \
237 void Name##_shrink(Name *self, size_t n)\
238 {\
239         Type *newbuf;\
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);\
245         }\
246         self->capacity = n;\
247         if (!n) {\
248                 free(self->buf);\
249                 self->buf = 0;\
250                 return;\
251         }\
252         newbuf = (Type *) realloc(self->buf, sizeof(Type) * n);\
253         if (newbuf) {\
254                 self->buf = newbuf;\
255         }\
256 }\
257 \
258
259 #define CSTL_VECTOR_IMPLEMENT_RESIZE(Name, Type)        \
260 int Name##_resize(Name *self, size_t n, Type data)\
261 {\
262         size_t size;\
263         CSTL_ASSERT(self && "Vector_resize");\
264         CSTL_ASSERT(self->magic == self && "Vector_resize");\
265         size = CSTL_VECTOR_SIZE(self);\
266         if (size >= n) {\
267                 self->size = n;\
268         } else {\
269                 register size_t i;\
270                 if (!Name##_insert_n_no_data(self, size, n - size)) {\
271                         return 0;\
272                 }\
273                 for (i = size; i < n; i++) {\
274                         CSTL_VECTOR_AT(self, i) = data;\
275                 }\
276         }\
277         return 1;\
278 }\
279 \
280
281 #define CSTL_VECTOR_IMPLEMENT_AT(Name, Type)    \
282 Type *Name##_at(Name *self, size_t idx)\
283 {\
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);\
288 }\
289 \
290
291 #define CSTL_VECTOR_IMPLEMENT_FRONT(Name, Type) \
292 Type *Name##_front(Name *self)\
293 {\
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];\
298 }\
299 \
300
301 #define CSTL_VECTOR_IMPLEMENT_BACK(Name, Type)  \
302 Type *Name##_back(Name *self)\
303 {\
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];\
308 }\
309 \
310
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)\
313 {\
314         memmove(&self->buf[first + n], &self->buf[first], sizeof(Type) * (last - first));\
315 }\
316 \
317
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)\
320 {\
321         memmove(&self->buf[first - n], &self->buf[first], sizeof(Type) * (last - first));\
322 }\
323 \
324
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)\
327 {\
328         if (!Name##_expand(self, CSTL_VECTOR_SIZE(self) + n)) return 0;\
329         Name##_move_backward(self, idx, self->size, n);\
330         self->size += n;\
331         return 1;\
332 }\
333 \
334
335 #define CSTL_VECTOR_IMPLEMENT_INSERT(Name, Type)        \
336 int Name##_insert(Name *self, size_t idx, Type data)\
337 {\
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);\
342 }\
343 \
344 int Name##_insert_ref(Name *self, size_t idx, Type const *data)\
345 {\
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);\
351 }\
352 \
353
354 #define CSTL_VECTOR_IMPLEMENT_INSERT_N(Name, Type)      \
355 int Name##_insert_n(Name *self, size_t idx, size_t n, Type data)\
356 {\
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);\
361 }\
362 \
363 int Name##_insert_n_ref(Name *self, size_t idx, size_t n, Type const *data)\
364 {\
365         register size_t i;\
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)) {\
371                 return 0;\
372         }\
373         for (i = 0; i < n; i++) {\
374                 self->buf[idx + i] = *data;\
375         }\
376         return 1;\
377 }\
378 \
379
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)\
382 {\
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)) {\
388                 return 0;\
389         }\
390         memcpy(&self->buf[idx], data, sizeof(Type) * n);\
391         return 1;\
392 }\
393 \
394
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)\
397 {\
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)) {\
407                 return 0;\
408         }\
409         if (self == x) {\
410                 if (idx <= xidx) {\
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)));\
415                 } else {\
416                         memcpy(&CSTL_VECTOR_AT(self, idx), &CSTL_VECTOR_AT(self, xidx), sizeof(Type) * n);\
417                 }\
418         } else {\
419                 memcpy(&CSTL_VECTOR_AT(self, idx), &CSTL_VECTOR_AT(x, xidx), sizeof(Type) * n);\
420         }\
421         return 1;\
422 }\
423 \
424
425 #define CSTL_VECTOR_IMPLEMENT_ERASE(Name, Type) \
426 void Name##_erase(Name *self, size_t idx, size_t n)\
427 {\
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);\
434         self->size -= n;\
435 }\
436 \
437
438 #define CSTL_VECTOR_IMPLEMENT_SWAP(Name, Type)  \
439 void Name##_swap(Name *self, Name *x)\
440 {\
441         size_t tmp_size;\
442         size_t tmp_capacity;\
443         Type *tmp_buf;\
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;\
453         self->buf = x->buf;\
454         x->size = tmp_size;\
455         x->capacity = tmp_capacity;\
456         x->buf = tmp_buf;\
457 }\
458 \
459
460
461 /*! 
462  * \brief \8eÀ\91\95\83}\83N\83\8d
463  * 
464  * \param Name \83R\83\93\83e\83i\96¼
465  * \param Type \97v\91f\82Ì\8c^
466  */
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)\
491
492
493 #endif /* CSTL_VECTOR_H_INCLUDED */