source: svn/trunk/util/xc_vector.h @ 1551

Last change on this file since 1551 was 1551, checked in by Xuefer, 5 years ago

merge stack/vector to 1 impl, avoid possible memory leak using malloc

  • Property svn:eol-style set to native
File size: 3.0 KB
Line 
1#ifndef XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B
2#define XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B
3
4#if _MSC_VER > 1000
5#pragma once
6#endif /* _MSC_VER > 1000 */
7
8#include <string.h>
9#include <stdlib.h>
10#include <assert.h>
11
12typedef struct {
13    size_t size;
14    void *data;
15
16    size_t capacity;
17    size_t data_size;
18    int persistent;
19} xc_vector_t;
20
21#define xc_vector_initializer(type, persistent_) { \
22    0, \
23    NULL, \
24\
25    0, \
26    sizeof(type), \
27    persistent_, \
28}
29
30#define xc_vector_init(type, vector, persistent_) do { \
31    (vector)->size = 0; \
32    (vector)->data = NULL; \
33\
34    (vector)->capacity = 0; \
35    (vector)->data_size = sizeof(type); \
36    (vector)->persistent = persistent_; \
37} while (0)
38
39static inline void xc_vector_destroy_impl(xc_vector_t *vector TSRMLS_DC)
40{
41    if (vector->data) {
42        pefree(vector->data, vector->persistent);
43    }
44    vector->capacity = 0;
45    vector->size = 0;
46}
47
48#define xc_vector_destroy(vector) xc_vector_destroy_impl(vector TSRMLS_CC)
49
50#define xc_vector_size(vector) ((vector)->size)
51#define xc_vector_element_ptr_(vector, index) ( \
52    (void *) ( \
53        ((char *) (vector)->data) + (index) * (vector)->data_size \
54    ) \
55)
56
57static inline xc_vector_t *xc_vector_check_type_(xc_vector_t *vector, size_t data_size)
58{
59    assert(vector->data_size = data_size);
60    return vector;
61}
62
63#define xc_vector_data(type, vector) ((type *) xc_vector_check_type_(vector, sizeof(type))->data)
64
65static inline void xc_vector_check_reserve_(xc_vector_t *vector TSRMLS_DC)
66{
67    if (vector->size == vector->capacity) {
68        if (vector->capacity) {
69            vector->capacity <<= 1;
70            vector->data = perealloc(vector->data, vector->data_size * vector->capacity, vector->persistent);
71        }
72        else {
73            vector->capacity = 8;
74            vector->data = pemalloc(vector->data_size * vector->capacity, vector->persistent);
75        }
76    }
77}
78
79#define xc_vector_push_back(vector, value_ptr) do { \
80    xc_vector_check_reserve_(vector TSRMLS_CC); \
81    memcpy(xc_vector_element_ptr_(vector, (vector)->size++), value_ptr, (vector)->data_size); \
82} while (0)
83
84static inline void *xc_vector_detach_impl(xc_vector_t *vector)
85{
86    void *data = vector->data;
87
88    vector->data = NULL;
89    vector->capacity = 0;
90    vector->size = 0;
91    return data;
92}
93
94#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(xc_vector_check_type_(vector, sizeof(type))))
95
96static inline xc_vector_t *xc_vector_pop_back_check_(xc_vector_t *vector, size_t data_size)
97{
98    assert(vector);
99    assert(vector->data_size == data_size);
100    assert(vector->capacity > 0);
101    return vector;
102}
103
104#define xc_vector_pop_back(type, vector) xc_vector_data(type, \
105    xc_vector_pop_back_check_(vector, sizeof(type)) \
106)[--(vector)->size]
107
108static inline void xc_vector_reverse(xc_vector_t *vector)
109{
110    char *left, *right;
111    void *tmp;
112
113    assert(vector);
114    tmp = alloca(vector->data_size);
115    for (left = vector->data, right = xc_vector_element_ptr_(vector, vector->size - 1); left < right; left += vector->data_size, right -= vector->data_size) {
116        memcpy(tmp, left, vector->data_size);
117        memcpy(left, right, vector->data_size);
118        memcpy(right, tmp, vector->data_size);
119    }
120}
121
122#endif /* XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B */
Note: See TracBrowser for help on using the repository browser.