20 #if !defined (GDB_VEC_H)
124 #define VEC_length(T,V) (VEC_OP(T,length)(V))
132 #define VEC_empty(T,V) (VEC_length (T,V) == 0)
142 #define VEC_last(T,V) (VEC_OP(T,last)(V VEC_ASSERT_INFO))
151 #define VEC_index(T,V,I) (VEC_OP(T,index)(V,I VEC_ASSERT_INFO))
165 #define VEC_iterate(T,V,I,P) (VEC_OP(T,iterate)(V,I,&(P)))
173 #define VEC_alloc(T,N) (VEC_OP(T,alloc)(N))
180 #define VEC_free(T,V) (VEC_OP(T,free)(&V))
187 #define VEC_cleanup(T) (VEC_OP(T,cleanup))
197 #define VEC_embedded_size(T,N) (VEC_OP(T,embedded_size)(N))
198 #define VEC_embedded_init(T,O,N) (VEC_OP(T,embedded_init)(VEC_BASE(O),N))
206 #define VEC_copy(T,V) (VEC_OP(T,copy)(V))
213 #define VEC_merge(T,V1,V2) (VEC_OP(T,merge)(V1, V2))
225 #define VEC_space(T,V,R) (VEC_OP(T,space)(V,R VEC_ASSERT_INFO))
237 #define VEC_reserve(T,V,R) (VEC_OP(T,reserve)(&(V),R VEC_ASSERT_INFO))
249 #define VEC_quick_push(T,V,O) (VEC_OP(T,quick_push)(V,O VEC_ASSERT_INFO))
260 #define VEC_safe_push(T,V,O) (VEC_OP(T,safe_push)(&(V),O VEC_ASSERT_INFO))
270 #define VEC_pop(T,V) (VEC_OP(T,pop)(V VEC_ASSERT_INFO))
278 #define VEC_truncate(T,V,I) \
279 (VEC_OP(T,truncate)(V,I VEC_ASSERT_INFO))
288 #define VEC_safe_grow(T,V,I) \
289 (VEC_OP(T,safe_grow)(&(V),I VEC_ASSERT_INFO))
302 #define VEC_replace(T,V,I,O) (VEC_OP(T,replace)(V,I,O VEC_ASSERT_INFO))
314 #define VEC_quick_insert(T,V,I,O) \
315 (VEC_OP(T,quick_insert)(V,I,O VEC_ASSERT_INFO))
327 #define VEC_safe_insert(T,V,I,O) \
328 (VEC_OP(T,safe_insert)(&(V),I,O VEC_ASSERT_INFO))
339 #define VEC_ordered_remove(T,V,I) \
340 (VEC_OP(T,ordered_remove)(V,I VEC_ASSERT_INFO))
351 #define VEC_unordered_remove(T,V,I) \
352 (VEC_OP(T,unordered_remove)(V,I VEC_ASSERT_INFO))
360 #define VEC_block_remove(T,V,I,L) \
361 (VEC_OP(T,block_remove)(V,I,L VEC_ASSERT_INFO))
369 #define VEC_address(T,V) (VEC_OP(T,address)(V))
383 #define VEC_lower_bound(T,V,O,LT) \
384 (VEC_OP(T,lower_bound)(V,O,LT VEC_ASSERT_INFO))
389 #define vec_free_(V) xfree (V)
391 #define VEC_ASSERT_INFO ,__FILE__,__LINE__
392 #define VEC_ASSERT_DECL ,const char *file_,unsigned line_
393 #define VEC_ASSERT_PASS ,file_,line_
394 #define vec_assert(expr, op) \
395 ((void)((expr) ? 0 : (gdb_assert_fail (op, file_, line_, \
398 #define VEC(T) VEC_##T
399 #define VEC_OP(T,OP) VEC_##T##_##OP
402 typedef struct VEC(T) \
410 #define DEF_VEC_I(T) \
411 static inline void VEC_OP (T,must_be_integral_type) (void) \
418 DEF_VEC_ALLOC_FUNC_I(T) \
419 struct vec_swallow_trailing_semi
422 #define DEF_VEC_P(T) \
423 static inline void VEC_OP (T,must_be_pointer_type) (void) \
425 (void)((T)1 == (void *)1); \
430 DEF_VEC_ALLOC_FUNC_P(T) \
431 struct vec_swallow_trailing_semi
434 #define DEF_VEC_O(T) \
437 DEF_VEC_ALLOC_FUNC_O(T) \
438 struct vec_swallow_trailing_semi
440 #define DEF_VEC_ALLOC_FUNC_I(T) \
441 static inline VEC(T) *VEC_OP (T,alloc) \
445 return (VEC(T) *) vec_o_reserve (NULL, -alloc_, \
446 offsetof (VEC(T),vec), sizeof (T)); \
449 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
451 size_t len_ = vec_ ? vec_->num : 0; \
452 VEC (T) *new_vec_ = NULL; \
457 new_vec_ = (VEC (T) *) \
458 vec_o_reserve (NULL, -len_, offsetof (VEC(T),vec), sizeof (T)); \
460 new_vec_->num = len_; \
461 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
466 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
468 if (vec1_ && vec2_) \
470 size_t len_ = vec1_->num + vec2_->num; \
471 VEC (T) *new_vec_ = NULL; \
474 new_vec_ = (VEC (T) *) \
475 vec_o_reserve (NULL, -len_, offsetof (VEC(T),vec), sizeof (T)); \
477 new_vec_->num = len_; \
478 memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
479 memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
480 sizeof (T) * vec2_->num); \
485 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
488 static inline void VEC_OP (T,free) \
496 static inline void VEC_OP (T,cleanup) \
499 VEC(T) **vec_ = arg_; \
505 static inline int VEC_OP (T,reserve) \
506 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
508 int extend = !VEC_OP (T,space) \
509 (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS); \
512 *vec_ = (VEC(T) *) vec_o_reserve (*vec_, alloc_, \
513 offsetof (VEC(T),vec), sizeof (T)); \
518 static inline void VEC_OP (T,safe_grow) \
519 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
521 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
523 VEC_OP (T,reserve) (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ \
525 (*vec_)->num = size_; \
528 static inline T *VEC_OP (T,safe_push) \
529 (VEC(T) **vec_, const T obj_ VEC_ASSERT_DECL) \
531 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
533 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
536 static inline T *VEC_OP (T,safe_insert) \
537 (VEC(T) **vec_, unsigned ix_, const T obj_ VEC_ASSERT_DECL) \
539 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
541 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
544 #define DEF_VEC_FUNC_P(T) \
545 static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_) \
547 return vec_ ? vec_->num : 0; \
550 static inline T VEC_OP (T,last) \
551 (const VEC(T) *vec_ VEC_ASSERT_DECL) \
553 vec_assert (vec_ && vec_->num, "last"); \
555 return vec_->vec[vec_->num - 1]; \
558 static inline T VEC_OP (T,index) \
559 (const VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
561 vec_assert (vec_ && ix_ < vec_->num, "index"); \
563 return vec_->vec[ix_]; \
566 static inline int VEC_OP (T,iterate) \
567 (const VEC(T) *vec_, unsigned ix_, T *ptr) \
569 if (vec_ && ix_ < vec_->num) \
571 *ptr = vec_->vec[ix_]; \
581 static inline size_t VEC_OP (T,embedded_size) \
584 return offsetof (VEC(T),vec) + alloc_ * sizeof(T); \
587 static inline void VEC_OP (T,embedded_init) \
588 (VEC(T) *vec_, int alloc_) \
591 vec_->alloc = alloc_; \
594 static inline int VEC_OP (T,space) \
595 (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL) \
597 vec_assert (alloc_ >= 0, "space"); \
598 return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
601 static inline T *VEC_OP (T,quick_push) \
602 (VEC(T) *vec_, T obj_ VEC_ASSERT_DECL) \
606 vec_assert (vec_->num < vec_->alloc, "quick_push"); \
607 slot_ = &vec_->vec[vec_->num++]; \
613 static inline T VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL) \
617 vec_assert (vec_->num, "pop"); \
618 obj_ = vec_->vec[--vec_->num]; \
623 static inline void VEC_OP (T,truncate) \
624 (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL) \
626 vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate"); \
631 static inline T VEC_OP (T,replace) \
632 (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
636 vec_assert (ix_ < vec_->num, "replace"); \
637 old_obj_ = vec_->vec[ix_]; \
638 vec_->vec[ix_] = obj_; \
643 static inline T *VEC_OP (T,quick_insert) \
644 (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
648 vec_assert (vec_->num < vec_->alloc && ix_ <= vec_->num, "quick_insert"); \
649 slot_ = &vec_->vec[ix_]; \
650 memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T)); \
656 static inline T VEC_OP (T,ordered_remove) \
657 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
662 vec_assert (ix_ < vec_->num, "ordered_remove"); \
663 slot_ = &vec_->vec[ix_]; \
665 memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
670 static inline T VEC_OP (T,unordered_remove) \
671 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
676 vec_assert (ix_ < vec_->num, "unordered_remove"); \
677 slot_ = &vec_->vec[ix_]; \
679 *slot_ = vec_->vec[--vec_->num]; \
684 static inline void VEC_OP (T,block_remove) \
685 (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL) \
689 vec_assert (ix_ + len_ <= vec_->num, "block_remove"); \
690 slot_ = &vec_->vec[ix_]; \
692 memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
695 static inline T *VEC_OP (T,address) \
698 return vec_ ? vec_->vec : 0; \
701 static inline unsigned VEC_OP (T,lower_bound) \
702 (VEC(T) *vec_, const T obj_, \
703 int (*lessthan_)(const T, const T) VEC_ASSERT_DECL) \
705 unsigned int len_ = VEC_OP (T, length) (vec_); \
706 unsigned int half_, middle_; \
707 unsigned int first_ = 0; \
714 middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS); \
715 if (lessthan_ (middle_elem_, obj_)) \
719 len_ = len_ - half_ - 1; \
727 #define DEF_VEC_ALLOC_FUNC_P(T) \
728 static inline VEC(T) *VEC_OP (T,alloc) \
732 return (VEC(T) *) vec_p_reserve (NULL, -alloc_); \
735 static inline void VEC_OP (T,free) \
743 static inline void VEC_OP (T,cleanup) \
746 VEC(T) **vec_ = arg_; \
752 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
754 size_t len_ = vec_ ? vec_->num : 0; \
755 VEC (T) *new_vec_ = NULL; \
760 new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_)); \
762 new_vec_->num = len_; \
763 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
768 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
770 if (vec1_ && vec2_) \
772 size_t len_ = vec1_->num + vec2_->num; \
773 VEC (T) *new_vec_ = NULL; \
776 new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_)); \
778 new_vec_->num = len_; \
779 memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
780 memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
781 sizeof (T) * vec2_->num); \
786 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
789 static inline int VEC_OP (T,reserve) \
790 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
792 int extend = !VEC_OP (T,space) \
793 (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS); \
796 *vec_ = (VEC(T) *) vec_p_reserve (*vec_, alloc_); \
801 static inline void VEC_OP (T,safe_grow) \
802 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
804 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
807 (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS); \
808 (*vec_)->num = size_; \
811 static inline T *VEC_OP (T,safe_push) \
812 (VEC(T) **vec_, T obj_ VEC_ASSERT_DECL) \
814 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
816 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
819 static inline T *VEC_OP (T,safe_insert) \
820 (VEC(T) **vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
822 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
824 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
827 #define DEF_VEC_FUNC_O(T) \
828 static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_) \
830 return vec_ ? vec_->num : 0; \
833 static inline T *VEC_OP (T,last) (VEC(T) *vec_ VEC_ASSERT_DECL) \
835 vec_assert (vec_ && vec_->num, "last"); \
837 return &vec_->vec[vec_->num - 1]; \
840 static inline T *VEC_OP (T,index) \
841 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
843 vec_assert (vec_ && ix_ < vec_->num, "index"); \
845 return &vec_->vec[ix_]; \
848 static inline int VEC_OP (T,iterate) \
849 (VEC(T) *vec_, unsigned ix_, T **ptr) \
851 if (vec_ && ix_ < vec_->num) \
853 *ptr = &vec_->vec[ix_]; \
863 static inline size_t VEC_OP (T,embedded_size) \
866 return offsetof (VEC(T),vec) + alloc_ * sizeof(T); \
869 static inline void VEC_OP (T,embedded_init) \
870 (VEC(T) *vec_, int alloc_) \
873 vec_->alloc = alloc_; \
876 static inline int VEC_OP (T,space) \
877 (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL) \
879 vec_assert (alloc_ >= 0, "space"); \
880 return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
883 static inline T *VEC_OP (T,quick_push) \
884 (VEC(T) *vec_, const T *obj_ VEC_ASSERT_DECL) \
888 vec_assert (vec_->num < vec_->alloc, "quick_push"); \
889 slot_ = &vec_->vec[vec_->num++]; \
896 static inline void VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL) \
898 vec_assert (vec_->num, "pop"); \
902 static inline void VEC_OP (T,truncate) \
903 (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL) \
905 vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate"); \
910 static inline T *VEC_OP (T,replace) \
911 (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
915 vec_assert (ix_ < vec_->num, "replace"); \
916 slot_ = &vec_->vec[ix_]; \
923 static inline T *VEC_OP (T,quick_insert) \
924 (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
928 vec_assert (vec_->num < vec_->alloc && ix_ <= vec_->num, "quick_insert"); \
929 slot_ = &vec_->vec[ix_]; \
930 memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T)); \
937 static inline void VEC_OP (T,ordered_remove) \
938 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
942 vec_assert (ix_ < vec_->num, "ordered_remove"); \
943 slot_ = &vec_->vec[ix_]; \
944 memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
947 static inline void VEC_OP (T,unordered_remove) \
948 (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
950 vec_assert (ix_ < vec_->num, "unordered_remove"); \
951 vec_->vec[ix_] = vec_->vec[--vec_->num]; \
954 static inline void VEC_OP (T,block_remove) \
955 (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL) \
959 vec_assert (ix_ + len_ <= vec_->num, "block_remove"); \
960 slot_ = &vec_->vec[ix_]; \
962 memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
965 static inline T *VEC_OP (T,address) \
968 return vec_ ? vec_->vec : 0; \
971 static inline unsigned VEC_OP (T,lower_bound) \
972 (VEC(T) *vec_, const T *obj_, \
973 int (*lessthan_)(const T *, const T *) VEC_ASSERT_DECL) \
975 unsigned int len_ = VEC_OP (T, length) (vec_); \
976 unsigned int half_, middle_; \
977 unsigned int first_ = 0; \
984 middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS); \
985 if (lessthan_ (middle_elem_, obj_)) \
989 len_ = len_ - half_ - 1; \
997 #define DEF_VEC_ALLOC_FUNC_O(T) \
998 static inline VEC(T) *VEC_OP (T,alloc) \
1002 return (VEC(T) *) vec_o_reserve (NULL, -alloc_, \
1003 offsetof (VEC(T),vec), sizeof (T)); \
1006 static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
1008 size_t len_ = vec_ ? vec_->num : 0; \
1009 VEC (T) *new_vec_ = NULL; \
1014 new_vec_ = (VEC (T) *) \
1015 vec_o_reserve (NULL, -len_, offsetof (VEC(T),vec), sizeof (T)); \
1017 new_vec_->num = len_; \
1018 memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
1023 static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
1025 if (vec1_ && vec2_) \
1027 size_t len_ = vec1_->num + vec2_->num; \
1028 VEC (T) *new_vec_ = NULL; \
1031 new_vec_ = (VEC (T) *) \
1032 vec_o_reserve (NULL, -len_, offsetof (VEC(T),vec), sizeof (T)); \
1034 new_vec_->num = len_; \
1035 memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
1036 memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
1037 sizeof (T) * vec2_->num); \
1042 return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
1045 static inline void VEC_OP (T,free) \
1049 vec_free_ (*vec_); \
1053 static inline void VEC_OP (T,cleanup) \
1056 VEC(T) **vec_ = arg_; \
1058 vec_free_ (*vec_); \
1062 static inline int VEC_OP (T,reserve) \
1063 (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
1065 int extend = !VEC_OP (T,space) (*vec_, alloc_ < 0 ? -alloc_ : alloc_ \
1069 *vec_ = (VEC(T) *) \
1070 vec_o_reserve (*vec_, alloc_, offsetof (VEC(T),vec), sizeof (T)); \
1075 static inline void VEC_OP (T,safe_grow) \
1076 (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
1078 vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
1080 VEC_OP (T,reserve) \
1081 (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS); \
1082 (*vec_)->num = size_; \
1085 static inline T *VEC_OP (T,safe_push) \
1086 (VEC(T) **vec_, const T *obj_ VEC_ASSERT_DECL) \
1088 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
1090 return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
1093 static inline T *VEC_OP (T,safe_insert) \
1094 (VEC(T) **vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
1096 VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
1098 return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
void * vec_o_reserve(void *, int, size_t, size_t)
void * vec_p_reserve(void *, int)