source: trunk/util/xc_vector.h

Last change on this file was 1567, checked in by moo, 7 weeks ago

use vector for objects/object_handles

  • Property svn:eol-style set to native
File size: 4.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    void *data_;
14    size_t size_;
15    size_t capacity_;
16
17    size_t data_size_;
18    int persistent_;
19} xc_vector_t;
20
21#define xc_vector_initializer(type, persistent) { \
22    NULL, \
23    0, \
24    0, \
25\
26    sizeof(type), \
27    persistent, \
28}
29
30#define xc_vector_init_ex(type, vector, data, size, persistent) do { \
31    (vector)->data_ = data; \
32    (vector)->size_ = (vector)->capacity_ = size; \
33    (vector)->data_size_ = sizeof(type); \
34    (vector)->persistent_ = persistent; \
35} while (0)
36
37#define xc_vector_init(type, vector) xc_vector_init_ex(type, vector, NULL, 0, 0)
38#define xc_vector_init_persistent(type, vector) xc_vector_init_ex(type, vector, NULL, 0, 1)
39
40static inline void xc_vector_destroy_impl(xc_vector_t *vector TSRMLS_DC)
41{
42    vector->size_ = 0;
43    if (vector->data_) {
44        pefree(vector->data_, vector->persistent_);
45        vector->data_ = NULL;
46    }
47    vector->capacity_ = 0;
48    vector->data_size_ = 0;
49}
50
51#define xc_vector_destroy(vector) xc_vector_destroy_impl(vector TSRMLS_CC)
52#define xc_vector_clear(vector) do { (vector)->size_ = 0; } while (0)
53
54#define xc_vector_size(vector) ((vector)->size_)
55#define xc_vector_initialized(vector) ((vector)->data_size_ != 0)
56#define xc_vector_element_ptr_(vector, index) ( \
57    (void *) ( \
58        ((char *) (vector)->data_) + (index) * (vector)->data_size_ \
59    ) \
60)
61
62static inline xc_vector_t *xc_vector_check_type_(xc_vector_t *vector, size_t data_size)
63{
64    assert(vector->data_size_ = data_size);
65    return vector;
66}
67
68#define xc_vector_data(type, vector) ((type *) xc_vector_check_type_(vector, sizeof(type))->data_)
69
70static void xc_vector_reserve_impl(xc_vector_t *vector, size_t capacity TSRMLS_DC)
71{
72    assert(capacity);
73    if (!vector->capacity_) {
74        vector->capacity_ = 8;
75    }
76    while (vector->capacity_ <= capacity) {
77        vector->capacity_ <<= 1;
78    }
79    vector->data_ = perealloc(vector->data_, vector->data_size_ * vector->capacity_, vector->persistent_);
80}
81#define xc_vector_reserve(vector, capacity) xc_vector_reserve_impl(vector, capacity TSRMLS_CC)
82
83static void xc_vector_resize_impl(xc_vector_t *vector, size_t size TSRMLS_DC)
84{
85    assert(size);
86    xc_vector_reserve(vector, size);
87    vector->size_ = size;
88}
89#define xc_vector_resize(vector, size) xc_vector_resize_impl(vector, size TSRMLS_CC)
90
91static inline void xc_vector_check_reserve_(xc_vector_t *vector TSRMLS_DC)
92{
93    if (vector->size_ == vector->capacity_) {
94        if (vector->capacity_) {
95            vector->capacity_ <<= 1;
96        }
97        else {
98            vector->capacity_ = 8;
99        }
100        vector->data_ = perealloc(vector->data_, vector->data_size_ * vector->capacity_, vector->persistent_);
101    }
102}
103
104#define xc_vector_push_back(vector, value_ptr) do { \
105    xc_vector_check_reserve_(vector TSRMLS_CC); \
106    memcpy(xc_vector_element_ptr_(vector, (vector)->size_++), value_ptr, (vector)->data_size_); \
107} while (0)
108
109static inline void *xc_vector_detach_impl(xc_vector_t *vector)
110{
111    void *data = vector->data_;
112
113    vector->data_ = NULL;
114    vector->capacity_ = 0;
115    vector->size_ = 0;
116    return data;
117}
118
119#define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(xc_vector_check_type_(vector, sizeof(type))))
120
121static inline xc_vector_t *xc_vector_pop_back_check_(xc_vector_t *vector, size_t data_size)
122{
123    assert(vector);
124    assert(vector->data_size_ == data_size);
125    assert(vector->capacity_ > 0);
126    return vector;
127}
128
129#define xc_vector_pop_back(type, vector) xc_vector_data(type, \
130    xc_vector_pop_back_check_(vector, sizeof(type)) \
131)[--(vector)->size_]
132
133static inline void xc_vector_reverse(xc_vector_t *vector)
134{
135    char *left, *right;
136    void *tmp;
137
138    assert(vector);
139    assert(vector->data_size_);
140    tmp = alloca(vector->data_size_);
141    for (left = vector->data_, right = xc_vector_element_ptr_(vector, vector->size_ - 1); left < right; left += vector->data_size_, right -= vector->data_size_) {
142        memcpy(tmp, left, vector->data_size_);
143        memcpy(left, right, vector->data_size_);
144        memcpy(right, tmp, vector->data_size_);
145    }
146}
147
148#endif /* XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B */
Note: See TracBrowser for help on using the repository browser.