00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef GCC_VEC_H
00023 #define GCC_VEC_H
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 #define VEC_length(T,V) (VEC_OP(T,base,length)(VEC_BASE(V)))
00149
00150
00151
00152
00153
00154
00155
00156 #define VEC_empty(T,V) (VEC_length (T,V) == 0)
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 #define VEC_last(T,V) (VEC_OP(T,base,last)(VEC_BASE(V) VEC_CHECK_INFO))
00167
00168
00169
00170
00171
00172
00173
00174
00175 #define VEC_index(T,V,I) (VEC_OP(T,base,index)(VEC_BASE(V),I VEC_CHECK_INFO))
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 #define VEC_iterate(T,V,I,P) (VEC_OP(T,base,iterate)(VEC_BASE(V),I,&(P)))
00190
00191
00192
00193
00194
00195
00196
00197 #define VEC_alloc(T,A,N) (VEC_OP(T,A,alloc)(N MEM_STAT_INFO))
00198
00199
00200
00201
00202
00203
00204 #define VEC_free(T,A,V) (VEC_OP(T,A,free)(&V))
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 #define VEC_embedded_size(T,N) (VEC_OP(T,base,embedded_size)(N))
00215 #define VEC_embedded_init(T,O,N) (VEC_OP(T,base,embedded_init)(VEC_BASE(O),N))
00216
00217
00218
00219
00220
00221
00222
00223 #define VEC_copy(T,A,V) (VEC_OP(T,A,copy)(VEC_BASE(V) MEM_STAT_INFO))
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 #define VEC_space(T,V,R) \
00236 (VEC_OP(T,base,space)(VEC_BASE(V),R VEC_CHECK_INFO))
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 #define VEC_reserve(T,A,V,R) \
00247 (VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 #define VEC_reserve_exact(T,A,V,R) \
00258 (VEC_OP(T,A,reserve_exact)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 #define VEC_quick_push(T,V,O) \
00271 (VEC_OP(T,base,quick_push)(VEC_BASE(V),O VEC_CHECK_INFO))
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 #define VEC_safe_push(T,A,V,O) \
00283 (VEC_OP(T,A,safe_push)(&(V),O VEC_CHECK_INFO MEM_STAT_INFO))
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 #define VEC_pop(T,V) (VEC_OP(T,base,pop)(VEC_BASE(V) VEC_CHECK_INFO))
00294
00295
00296
00297
00298
00299
00300
00301 #define VEC_truncate(T,V,I) \
00302 (VEC_OP(T,base,truncate)(VEC_BASE(V),I VEC_CHECK_INFO))
00303
00304
00305
00306
00307
00308
00309
00310
00311 #define VEC_safe_grow(T,A,V,I) \
00312 (VEC_OP(T,A,safe_grow)(&(V),I VEC_CHECK_INFO MEM_STAT_INFO))
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 #define VEC_replace(T,V,I,O) \
00326 (VEC_OP(T,base,replace)(VEC_BASE(V),I,O VEC_CHECK_INFO))
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 #define VEC_quick_insert(T,V,I,O) \
00339 (VEC_OP(T,base,quick_insert)(VEC_BASE(V),I,O VEC_CHECK_INFO))
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 #define VEC_safe_insert(T,A,V,I,O) \
00352 (VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO))
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 #define VEC_ordered_remove(T,V,I) \
00364 (VEC_OP(T,base,ordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 #define VEC_unordered_remove(T,V,I) \
00376 (VEC_OP(T,base,unordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
00377
00378
00379
00380
00381
00382
00383
00384 #define VEC_block_remove(T,V,I,L) \
00385 (VEC_OP(T,base,block_remove)(VEC_BASE(V),I,L VEC_CHECK_INFO))
00386
00387
00388
00389
00390
00391
00392
00393 #define VEC_address(T,V) (VEC_OP(T,base,address)(VEC_BASE(V)))
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 #define VEC_lower_bound(T,V,O,LT) \
00408 (VEC_OP(T,base,lower_bound)(VEC_BASE(V),O,LT VEC_CHECK_INFO))
00409
00410 #if !IN_GENGTYPE
00411
00412 extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
00413 extern void *vec_gc_p_reserve_exact (void *, int MEM_STAT_DECL);
00414 extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
00415 extern void *vec_gc_o_reserve_exact (void *, int, size_t, size_t
00416 MEM_STAT_DECL);
00417 extern void ggc_free (void *);
00418 #define vec_gc_free(V) ggc_free (V)
00419 extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL);
00420 extern void *vec_heap_p_reserve_exact (void *, int MEM_STAT_DECL);
00421 extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
00422 extern void *vec_heap_o_reserve_exact (void *, int, size_t, size_t
00423 MEM_STAT_DECL);
00424 #define vec_heap_free(V) free (V)
00425
00426 #if ENABLE_CHECKING
00427 #define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__
00428 #define VEC_CHECK_DECL ,const char *file_,unsigned line_,const char *function_
00429 #define VEC_CHECK_PASS ,file_,line_,function_
00430
00431 #define VEC_ASSERT(EXPR,OP,T,A) \
00432 (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0))
00433
00434 extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL)
00435 ATTRIBUTE_NORETURN;
00436 #define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS)
00437 #else
00438 #define VEC_CHECK_INFO
00439 #define VEC_CHECK_DECL
00440 #define VEC_CHECK_PASS
00441 #define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR)
00442 #endif
00443
00444 #define VEC(T,A) VEC_##T##_##A
00445 #define VEC_OP(T,A,OP) VEC_##T##_##A##_##OP
00446 #else
00447 #define VEC(T,A) VEC_ T _ A
00448 #define VEC_STRINGIFY(X) VEC_STRINGIFY_(X)
00449 #define VEC_STRINGIFY_(X) #X
00450 #undef GTY
00451 #endif
00452
00453
00454 #define VEC_T(T,B) \
00455 typedef struct VEC(T,B) \
00456 { \
00457 unsigned num; \
00458 unsigned alloc; \
00459 T vec[1]; \
00460 } VEC(T,B)
00461
00462 #define VEC_T_GTY(T,B) \
00463 typedef struct VEC(T,B) GTY(()) \
00464 { \
00465 unsigned num; \
00466 unsigned alloc; \
00467 T GTY ((length ("%h.num"))) vec[1]; \
00468 } VEC(T,B)
00469
00470
00471 #define VEC_TA_GTY(T,B,A,GTY) \
00472 typedef struct VEC(T,A) GTY \
00473 { \
00474 VEC(T,B) base; \
00475 } VEC(T,A)
00476
00477
00478 #define VEC_BASE(P) ((P) ? &(P)->base : 0)
00479
00480
00481 #if IN_GENGTYPE
00482 {"DEF_VEC_I", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
00483 {"DEF_VEC_ALLOC_I", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
00484 #else
00485 #define DEF_VEC_I(T) \
00486 static inline void VEC_OP (T,must_be,integral_type) (void) \
00487 { \
00488 (void)~(T)0; \
00489 } \
00490 \
00491 VEC_T(T,base); \
00492 VEC_TA_GTY(T,base,none,); \
00493 DEF_VEC_FUNC_P(T) \
00494 struct vec_swallow_trailing_semi
00495 #define DEF_VEC_ALLOC_I(T,A) \
00496 VEC_TA_GTY(T,base,A,); \
00497 DEF_VEC_ALLOC_FUNC_I(T,A) \
00498 struct vec_swallow_trailing_semi
00499 #endif
00500
00501
00502 #if IN_GENGTYPE
00503 {"DEF_VEC_P", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
00504 {"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA_GTY (#0,#1,#2,#3)) ";", NULL},
00505 #else
00506 #define DEF_VEC_P(T) \
00507 static inline void VEC_OP (T,must_be,pointer_type) (void) \
00508 { \
00509 (void)((T)1 == (void *)1); \
00510 } \
00511 \
00512 VEC_T_GTY(T,base); \
00513 VEC_TA_GTY(T,base,none,); \
00514 DEF_VEC_FUNC_P(T) \
00515 struct vec_swallow_trailing_semi
00516 #define DEF_VEC_ALLOC_P(T,A) \
00517 VEC_TA_GTY(T,base,A,); \
00518 DEF_VEC_ALLOC_FUNC_P(T,A) \
00519 struct vec_swallow_trailing_semi
00520 #endif
00521
00522 #define DEF_VEC_FUNC_P(T) \
00523 static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
00524 { \
00525 return vec_ ? vec_->num : 0; \
00526 } \
00527 \
00528 static inline T VEC_OP (T,base,last) \
00529 (const VEC(T,base) *vec_ VEC_CHECK_DECL) \
00530 { \
00531 VEC_ASSERT (vec_ && vec_->num, "last", T, base); \
00532 \
00533 return vec_->vec[vec_->num - 1]; \
00534 } \
00535 \
00536 static inline T VEC_OP (T,base,index) \
00537 (const VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \
00538 { \
00539 VEC_ASSERT (vec_ && ix_ < vec_->num, "index", T, base); \
00540 \
00541 return vec_->vec[ix_]; \
00542 } \
00543 \
00544 static inline int VEC_OP (T,base,iterate) \
00545 (const VEC(T,base) *vec_, unsigned ix_, T *ptr) \
00546 { \
00547 if (vec_ && ix_ < vec_->num) \
00548 { \
00549 *ptr = vec_->vec[ix_]; \
00550 return 1; \
00551 } \
00552 else \
00553 { \
00554 *ptr = 0; \
00555 return 0; \
00556 } \
00557 } \
00558 \
00559 static inline size_t VEC_OP (T,base,embedded_size) \
00560 (int alloc_) \
00561 { \
00562 return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T); \
00563 } \
00564 \
00565 static inline void VEC_OP (T,base,embedded_init) \
00566 (VEC(T,base) *vec_, int alloc_) \
00567 { \
00568 vec_->num = 0; \
00569 vec_->alloc = alloc_; \
00570 } \
00571 \
00572 static inline int VEC_OP (T,base,space) \
00573 (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL) \
00574 { \
00575 VEC_ASSERT (alloc_ >= 0, "space", T, base); \
00576 return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
00577 } \
00578 \
00579 static inline T *VEC_OP (T,base,quick_push) \
00580 (VEC(T,base) *vec_, T obj_ VEC_CHECK_DECL) \
00581 { \
00582 T *slot_; \
00583 \
00584 VEC_ASSERT (vec_->num < vec_->alloc, "push", T, base); \
00585 slot_ = &vec_->vec[vec_->num++]; \
00586 *slot_ = obj_; \
00587 \
00588 return slot_; \
00589 } \
00590 \
00591 static inline T VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL) \
00592 { \
00593 T obj_; \
00594 \
00595 VEC_ASSERT (vec_->num, "pop", T, base); \
00596 obj_ = vec_->vec[--vec_->num]; \
00597 \
00598 return obj_; \
00599 } \
00600 \
00601 static inline void VEC_OP (T,base,truncate) \
00602 (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL) \
00603 { \
00604 VEC_ASSERT (vec_ ? vec_->num >= size_ : !size_, "truncate", T, base); \
00605 if (vec_) \
00606 vec_->num = size_; \
00607 } \
00608 \
00609 static inline T VEC_OP (T,base,replace) \
00610 (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL) \
00611 { \
00612 T old_obj_; \
00613 \
00614 VEC_ASSERT (ix_ < vec_->num, "replace", T, base); \
00615 old_obj_ = vec_->vec[ix_]; \
00616 vec_->vec[ix_] = obj_; \
00617 \
00618 return old_obj_; \
00619 } \
00620 \
00621 static inline T *VEC_OP (T,base,quick_insert) \
00622 (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL) \
00623 { \
00624 T *slot_; \
00625 \
00626 VEC_ASSERT (vec_->num < vec_->alloc, "insert", T, base); \
00627 VEC_ASSERT (ix_ <= vec_->num, "insert", T, base); \
00628 slot_ = &vec_->vec[ix_]; \
00629 memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T)); \
00630 *slot_ = obj_; \
00631 \
00632 return slot_; \
00633 } \
00634 \
00635 static inline T VEC_OP (T,base,ordered_remove) \
00636 (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \
00637 { \
00638 T *slot_; \
00639 T obj_; \
00640 \
00641 VEC_ASSERT (ix_ < vec_->num, "remove", T, base); \
00642 slot_ = &vec_->vec[ix_]; \
00643 obj_ = *slot_; \
00644 memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
00645 \
00646 return obj_; \
00647 } \
00648 \
00649 static inline T VEC_OP (T,base,unordered_remove) \
00650 (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \
00651 { \
00652 T *slot_; \
00653 T obj_; \
00654 \
00655 VEC_ASSERT (ix_ < vec_->num, "remove", T, base); \
00656 slot_ = &vec_->vec[ix_]; \
00657 obj_ = *slot_; \
00658 *slot_ = vec_->vec[--vec_->num]; \
00659 \
00660 return obj_; \
00661 } \
00662 \
00663 static inline void VEC_OP (T,base,block_remove) \
00664 (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL) \
00665 { \
00666 T *slot_; \
00667 \
00668 VEC_ASSERT (ix_ + len_ <= vec_->num, "block_remove", T, base); \
00669 slot_ = &vec_->vec[ix_]; \
00670 vec_->num -= len_; \
00671 memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
00672 } \
00673 \
00674 static inline T *VEC_OP (T,base,address) \
00675 (VEC(T,base) *vec_) \
00676 { \
00677 return vec_ ? vec_->vec : 0; \
00678 } \
00679 \
00680 static inline unsigned VEC_OP (T,base,lower_bound) \
00681 (VEC(T,base) *vec_, const T obj_, \
00682 bool (*lessthan_)(const T, const T) VEC_CHECK_DECL) \
00683 { \
00684 unsigned int len_ = VEC_OP (T,base, length) (vec_); \
00685 unsigned int half_, middle_; \
00686 unsigned int first_ = 0; \
00687 while (len_ > 0) \
00688 { \
00689 T middle_elem_; \
00690 half_ = len_ >> 1; \
00691 middle_ = first_; \
00692 middle_ += half_; \
00693 middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \
00694 if (lessthan_ (middle_elem_, obj_)) \
00695 { \
00696 first_ = middle_; \
00697 ++first_; \
00698 len_ = len_ - half_ - 1; \
00699 } \
00700 else \
00701 len_ = half_; \
00702 } \
00703 return first_; \
00704 }
00705
00706 #define DEF_VEC_ALLOC_FUNC_P(T,A) \
00707 static inline VEC(T,A) *VEC_OP (T,A,alloc) \
00708 (int alloc_ MEM_STAT_DECL) \
00709 { \
00710 return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \
00711 PASS_MEM_STAT); \
00712 } \
00713 \
00714 static inline void VEC_OP (T,A,free) \
00715 (VEC(T,A) **vec_) \
00716 { \
00717 if (*vec_) \
00718 vec_##A##_free (*vec_); \
00719 *vec_ = NULL; \
00720 } \
00721 \
00722 static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
00723 { \
00724 size_t len_ = vec_ ? vec_->num : 0; \
00725 VEC (T,A) *new_vec_ = NULL; \
00726 \
00727 if (len_) \
00728 { \
00729 new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve_exact \
00730 (NULL, len_ PASS_MEM_STAT)); \
00731 \
00732 new_vec_->base.num = len_; \
00733 memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \
00734 } \
00735 return new_vec_; \
00736 } \
00737 \
00738 static inline int VEC_OP (T,A,reserve) \
00739 (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
00740 { \
00741 int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
00742 VEC_CHECK_PASS); \
00743 \
00744 if (extend) \
00745 *vec_ = (VEC(T,A) *) vec_##A##_p_reserve (*vec_, alloc_ PASS_MEM_STAT); \
00746 \
00747 return extend; \
00748 } \
00749 \
00750 static inline int VEC_OP (T,A,reserve_exact) \
00751 (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
00752 { \
00753 int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
00754 VEC_CHECK_PASS); \
00755 \
00756 if (extend) \
00757 *vec_ = (VEC(T,A) *) vec_##A##_p_reserve_exact (*vec_, alloc_ \
00758 PASS_MEM_STAT); \
00759 \
00760 return extend; \
00761 } \
00762 \
00763 static inline void VEC_OP (T,A,safe_grow) \
00764 (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
00765 { \
00766 VEC_ASSERT (size_ >= 0 \
00767 && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
00768 "grow", T, A); \
00769 VEC_OP (T,A,reserve_exact) (vec_, \
00770 size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
00771 VEC_CHECK_PASS PASS_MEM_STAT); \
00772 VEC_BASE (*vec_)->num = size_; \
00773 } \
00774 \
00775 static inline T *VEC_OP (T,A,safe_push) \
00776 (VEC(T,A) **vec_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL) \
00777 { \
00778 VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \
00779 \
00780 return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \
00781 } \
00782 \
00783 static inline T *VEC_OP (T,A,safe_insert) \
00784 (VEC(T,A) **vec_, unsigned ix_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL) \
00785 { \
00786 VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \
00787 \
00788 return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
00789 VEC_CHECK_PASS); \
00790 }
00791
00792
00793 #if IN_GENGTYPE
00794 {"DEF_VEC_O", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
00795 {"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA_GTY(#0,#1,#2,#3)) ";", NULL},
00796 #else
00797 #define DEF_VEC_O(T) \
00798 VEC_T_GTY(T,base); \
00799 VEC_TA_GTY(T,base,none,); \
00800 DEF_VEC_FUNC_O(T) \
00801 struct vec_swallow_trailing_semi
00802 #define DEF_VEC_ALLOC_O(T,A) \
00803 VEC_TA_GTY(T,base,A,); \
00804 DEF_VEC_ALLOC_FUNC_O(T,A) \
00805 struct vec_swallow_trailing_semi
00806 #endif
00807
00808 #define DEF_VEC_FUNC_O(T) \
00809 static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
00810 { \
00811 return vec_ ? vec_->num : 0; \
00812 } \
00813 \
00814 static inline T *VEC_OP (T,base,last) (VEC(T,base) *vec_ VEC_CHECK_DECL) \
00815 { \
00816 VEC_ASSERT (vec_ && vec_->num, "last", T, base); \
00817 \
00818 return &vec_->vec[vec_->num - 1]; \
00819 } \
00820 \
00821 static inline T *VEC_OP (T,base,index) \
00822 (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \
00823 { \
00824 VEC_ASSERT (vec_ && ix_ < vec_->num, "index", T, base); \
00825 \
00826 return &vec_->vec[ix_]; \
00827 } \
00828 \
00829 static inline int VEC_OP (T,base,iterate) \
00830 (VEC(T,base) *vec_, unsigned ix_, T **ptr) \
00831 { \
00832 if (vec_ && ix_ < vec_->num) \
00833 { \
00834 *ptr = &vec_->vec[ix_]; \
00835 return 1; \
00836 } \
00837 else \
00838 { \
00839 *ptr = 0; \
00840 return 0; \
00841 } \
00842 } \
00843 \
00844 static inline size_t VEC_OP (T,base,embedded_size) \
00845 (int alloc_) \
00846 { \
00847 return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T); \
00848 } \
00849 \
00850 static inline void VEC_OP (T,base,embedded_init) \
00851 (VEC(T,base) *vec_, int alloc_) \
00852 { \
00853 vec_->num = 0; \
00854 vec_->alloc = alloc_; \
00855 } \
00856 \
00857 static inline int VEC_OP (T,base,space) \
00858 (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL) \
00859 { \
00860 VEC_ASSERT (alloc_ >= 0, "space", T, base); \
00861 return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
00862 } \
00863 \
00864 static inline T *VEC_OP (T,base,quick_push) \
00865 (VEC(T,base) *vec_, const T *obj_ VEC_CHECK_DECL) \
00866 { \
00867 T *slot_; \
00868 \
00869 VEC_ASSERT (vec_->num < vec_->alloc, "push", T, base); \
00870 slot_ = &vec_->vec[vec_->num++]; \
00871 if (obj_) \
00872 *slot_ = *obj_; \
00873 \
00874 return slot_; \
00875 } \
00876 \
00877 static inline void VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL) \
00878 { \
00879 VEC_ASSERT (vec_->num, "pop", T, base); \
00880 --vec_->num; \
00881 } \
00882 \
00883 static inline void VEC_OP (T,base,truncate) \
00884 (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL) \
00885 { \
00886 VEC_ASSERT (vec_ ? vec_->num >= size_ : !size_, "truncate", T, base); \
00887 if (vec_) \
00888 vec_->num = size_; \
00889 } \
00890 \
00891 static inline T *VEC_OP (T,base,replace) \
00892 (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL) \
00893 { \
00894 T *slot_; \
00895 \
00896 VEC_ASSERT (ix_ < vec_->num, "replace", T, base); \
00897 slot_ = &vec_->vec[ix_]; \
00898 if (obj_) \
00899 *slot_ = *obj_; \
00900 \
00901 return slot_; \
00902 } \
00903 \
00904 static inline T *VEC_OP (T,base,quick_insert) \
00905 (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL) \
00906 { \
00907 T *slot_; \
00908 \
00909 VEC_ASSERT (vec_->num < vec_->alloc, "insert", T, base); \
00910 VEC_ASSERT (ix_ <= vec_->num, "insert", T, base); \
00911 slot_ = &vec_->vec[ix_]; \
00912 memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T)); \
00913 if (obj_) \
00914 *slot_ = *obj_; \
00915 \
00916 return slot_; \
00917 } \
00918 \
00919 static inline void VEC_OP (T,base,ordered_remove) \
00920 (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \
00921 { \
00922 T *slot_; \
00923 \
00924 VEC_ASSERT (ix_ < vec_->num, "remove", T, base); \
00925 slot_ = &vec_->vec[ix_]; \
00926 memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
00927 } \
00928 \
00929 static inline void VEC_OP (T,base,unordered_remove) \
00930 (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \
00931 { \
00932 VEC_ASSERT (ix_ < vec_->num, "remove", T, base); \
00933 vec_->vec[ix_] = vec_->vec[--vec_->num]; \
00934 } \
00935 \
00936 static inline void VEC_OP (T,base,block_remove) \
00937 (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL) \
00938 { \
00939 T *slot_; \
00940 \
00941 VEC_ASSERT (ix_ + len_ <= vec_->num, "block_remove", T, base); \
00942 slot_ = &vec_->vec[ix_]; \
00943 vec_->num -= len_; \
00944 memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
00945 } \
00946 \
00947 static inline T *VEC_OP (T,base,address) \
00948 (VEC(T,base) *vec_) \
00949 { \
00950 return vec_ ? vec_->vec : 0; \
00951 } \
00952 \
00953 static inline unsigned VEC_OP (T,base,lower_bound) \
00954 (VEC(T,base) *vec_, const T *obj_, \
00955 bool (*lessthan_)(const T *, const T *) VEC_CHECK_DECL) \
00956 { \
00957 unsigned int len_ = VEC_OP (T, base, length) (vec_); \
00958 unsigned int half_, middle_; \
00959 unsigned int first_ = 0; \
00960 while (len_ > 0) \
00961 { \
00962 T *middle_elem_; \
00963 half_ = len_ >> 1; \
00964 middle_ = first_; \
00965 middle_ += half_; \
00966 middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \
00967 if (lessthan_ (middle_elem_, obj_)) \
00968 { \
00969 first_ = middle_; \
00970 ++first_; \
00971 len_ = len_ - half_ - 1; \
00972 } \
00973 else \
00974 len_ = half_; \
00975 } \
00976 return first_; \
00977 }
00978
00979 #define DEF_VEC_ALLOC_FUNC_O(T,A) \
00980 static inline VEC(T,A) *VEC_OP (T,A,alloc) \
00981 (int alloc_ MEM_STAT_DECL) \
00982 { \
00983 return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_, \
00984 offsetof (VEC(T,A),base.vec), \
00985 sizeof (T) \
00986 PASS_MEM_STAT); \
00987 } \
00988 \
00989 static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
00990 { \
00991 size_t len_ = vec_ ? vec_->num : 0; \
00992 VEC (T,A) *new_vec_ = NULL; \
00993 \
00994 if (len_) \
00995 { \
00996 new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \
00997 (NULL, len_, \
00998 offsetof (VEC(T,A),base.vec), sizeof (T) \
00999 PASS_MEM_STAT)); \
01000 \
01001 new_vec_->base.num = len_; \
01002 memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \
01003 } \
01004 return new_vec_; \
01005 } \
01006 \
01007 static inline void VEC_OP (T,A,free) \
01008 (VEC(T,A) **vec_) \
01009 { \
01010 if (*vec_) \
01011 vec_##A##_free (*vec_); \
01012 *vec_ = NULL; \
01013 } \
01014 \
01015 static inline int VEC_OP (T,A,reserve) \
01016 (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
01017 { \
01018 int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
01019 VEC_CHECK_PASS); \
01020 \
01021 if (extend) \
01022 *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_, \
01023 offsetof (VEC(T,A),base.vec),\
01024 sizeof (T) \
01025 PASS_MEM_STAT); \
01026 \
01027 return extend; \
01028 } \
01029 \
01030 static inline int VEC_OP (T,A,reserve_exact) \
01031 (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
01032 { \
01033 int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
01034 VEC_CHECK_PASS); \
01035 \
01036 if (extend) \
01037 *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \
01038 (*vec_, alloc_, \
01039 offsetof (VEC(T,A),base.vec), \
01040 sizeof (T) PASS_MEM_STAT); \
01041 \
01042 return extend; \
01043 } \
01044 \
01045 static inline void VEC_OP (T,A,safe_grow) \
01046 (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
01047 { \
01048 VEC_ASSERT (size_ >= 0 \
01049 && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
01050 "grow", T, A); \
01051 VEC_OP (T,A,reserve_exact) (vec_, \
01052 size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
01053 VEC_CHECK_PASS PASS_MEM_STAT); \
01054 VEC_BASE (*vec_)->num = size_; \
01055 } \
01056 \
01057 static inline T *VEC_OP (T,A,safe_push) \
01058 (VEC(T,A) **vec_, const T *obj_ VEC_CHECK_DECL MEM_STAT_DECL) \
01059 { \
01060 VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \
01061 \
01062 return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \
01063 } \
01064 \
01065 static inline T *VEC_OP (T,A,safe_insert) \
01066 (VEC(T,A) **vec_, unsigned ix_, const T *obj_ \
01067 VEC_CHECK_DECL MEM_STAT_DECL) \
01068 { \
01069 VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \
01070 \
01071 return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
01072 VEC_CHECK_PASS); \
01073 }
01074
01075 #define DEF_VEC_ALLOC_FUNC_I(T,A) \
01076 static inline VEC(T,A) *VEC_OP (T,A,alloc) \
01077 (int alloc_ MEM_STAT_DECL) \
01078 { \
01079 return (VEC(T,A) *) vec_##A##_o_reserve_exact \
01080 (NULL, alloc_, offsetof (VEC(T,A),base.vec), \
01081 sizeof (T) PASS_MEM_STAT); \
01082 } \
01083 \
01084 static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
01085 { \
01086 size_t len_ = vec_ ? vec_->num : 0; \
01087 VEC (T,A) *new_vec_ = NULL; \
01088 \
01089 if (len_) \
01090 { \
01091 new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \
01092 (NULL, len_, \
01093 offsetof (VEC(T,A),base.vec), sizeof (T) \
01094 PASS_MEM_STAT)); \
01095 \
01096 new_vec_->base.num = len_; \
01097 memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \
01098 } \
01099 return new_vec_; \
01100 } \
01101 \
01102 static inline void VEC_OP (T,A,free) \
01103 (VEC(T,A) **vec_) \
01104 { \
01105 if (*vec_) \
01106 vec_##A##_free (*vec_); \
01107 *vec_ = NULL; \
01108 } \
01109 \
01110 static inline int VEC_OP (T,A,reserve) \
01111 (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
01112 { \
01113 int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
01114 VEC_CHECK_PASS); \
01115 \
01116 if (extend) \
01117 *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_, \
01118 offsetof (VEC(T,A),base.vec),\
01119 sizeof (T) \
01120 PASS_MEM_STAT); \
01121 \
01122 return extend; \
01123 } \
01124 \
01125 static inline int VEC_OP (T,A,reserve_exact) \
01126 (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
01127 { \
01128 int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
01129 VEC_CHECK_PASS); \
01130 \
01131 if (extend) \
01132 *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \
01133 (*vec_, alloc_, offsetof (VEC(T,A),base.vec), \
01134 sizeof (T) PASS_MEM_STAT); \
01135 \
01136 return extend; \
01137 } \
01138 \
01139 static inline void VEC_OP (T,A,safe_grow) \
01140 (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
01141 { \
01142 VEC_ASSERT (size_ >= 0 \
01143 && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
01144 "grow", T, A); \
01145 VEC_OP (T,A,reserve_exact) (vec_, \
01146 size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
01147 VEC_CHECK_PASS PASS_MEM_STAT); \
01148 VEC_BASE (*vec_)->num = size_; \
01149 } \
01150 \
01151 static inline T *VEC_OP (T,A,safe_push) \
01152 (VEC(T,A) **vec_, const T obj_ VEC_CHECK_DECL MEM_STAT_DECL) \
01153 { \
01154 VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \
01155 \
01156 return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \
01157 } \
01158 \
01159 static inline T *VEC_OP (T,A,safe_insert) \
01160 (VEC(T,A) **vec_, unsigned ix_, const T obj_ \
01161 VEC_CHECK_DECL MEM_STAT_DECL) \
01162 { \
01163 VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \
01164 \
01165 return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
01166 VEC_CHECK_PASS); \
01167 }
01168
01169 #endif