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

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

closes #342: object caching

  • Property svn:eol-style set to native
File size: 3.1 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    vector->size = 0;
42    if (vector->data) {
43        pefree(vector->data, vector->persistent);
44        vector->data = NULL;
45    }
46    vector->capacity = 0;
47    vector->data_size = 0;
48}
49
50#define xc_vector_destroy(vector) xc_vector_destroy_impl(vector TSRMLS_CC)
51
52#define xc_vector_size(vector) ((vector)->size)
53#define xc_vector_initialized(vector) ((vector)->data_size != 0)
54#define xc_vector_element_ptr_(vector, index) ( \
55    (void *) ( \
56        ((char *) (vector)->data) + (index) * (vector)->data_size \
57    ) \
58)
59
60static inline xc_vector_t *xc_vector_check_type_(xc_vector_t *vector, size_t data_size)
61{
62    assert(vector->data_size = data_size);
63    return vector;
64}
65
66#define xc_vector_data(type, vector) ((type *) xc_vector_check_type_(vector, sizeof(type))->data)
67
68static inline void xc_vector_check_reserve_(xc_vector_t *vector TSRMLS_DC)
69{
70    if (vector->size == vector->capacity) {
71        if (vector->capacity) {
72            vector->capacity <<= 1;
73            vector->data = perealloc(vector->data, vector->data_size * vector->capacity, vector->persistent);
74        }
75        else {
76            vector->capacity = 8;
77            vector->data = pemalloc(vector->data_size * vector->capacity, vector->persistent);
78        }
79    }
80}
81
82#define xc_vector_push_back(vector, value_ptr) do { \
83    xc_vector_check_reserve_(vector TSRMLS_CC); \
84    memcpy(xc_vector_element_ptr_(vector, (vector)->size++), value_ptr, (vector)->data_size); \
85} while (0)
86
87static inline void *xc_vector_detach_impl(xc_vector_t *vector)
88{
89    void *data = vector->data;
90
91    vector->data = NULL;
92    vector->capacity = 0;
93    vector->size = 0;
94    return data;
95}
96
97#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(xc_vector_check_type_(vector, sizeof(type))))
98
99static inline xc_vector_t *xc_vector_pop_back_check_(xc_vector_t *vector, size_t data_size)
100{
101    assert(vector);
102    assert(vector->data_size == data_size);
103    assert(vector->capacity > 0);
104    return vector;
105}
106
107#define xc_vector_pop_back(type, vector) xc_vector_data(type, \
108    xc_vector_pop_back_check_(vector, sizeof(type)) \
109)[--(vector)->size]
110
111static inline void xc_vector_reverse(xc_vector_t *vector)
112{
113    char *left, *right;
114    void *tmp;
115
116    assert(vector);
117    tmp = alloca(vector->data_size);
118    for (left = vector->data, right = xc_vector_element_ptr_(vector, vector->size - 1); left < right; left += vector->data_size, right -= vector->data_size) {
119        memcpy(tmp, left, vector->data_size);
120        memcpy(left, right, vector->data_size);
121        memcpy(right, tmp, vector->data_size);
122    }
123}
124
125#endif /* XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B */
Note: See TracBrowser for help on using the repository browser.