File: array.c

package info (click to toggle)
ruby-ferret 0.11.8.4%2Bdebian-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,368 kB
  • sloc: ansic: 69,786; ruby: 8,131; makefile: 5
file content (125 lines) | stat: -rw-r--r-- 2,860 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "array.h"
#include <string.h>
#include "internal.h"

#define META_CNT ARY_META_CNT
#define DATA_SZ sizeof(int) * META_CNT

void **ary_new_i(int type_size, int init_capa)
{
    void **ary;
    if (init_capa <= 0) {
        init_capa = ARY_INIT_CAPA;
    }
    ary = (void **)&(((int *)ecalloc(DATA_SZ +
                                        init_capa * type_size))[META_CNT]);
    ary_type_size(ary) = type_size;
    ary_capa(ary) = init_capa;
    return ary;
}

INLINE void ary_resize_i(void ***ary, int size)
{
    size++;
    if (size > ary_sz(*ary)) {
        int capa = ary_capa(*ary);
        if (size >= capa) {
            int *ary_start = &((int *)*ary)[-META_CNT];
            while (size >= capa) {
                capa <<= 1;
            }

            ary_start = (int *)erealloc(ary_start,
                                        DATA_SZ + capa * ary_type_size(*ary));
            *ary = (void **)&(ary_start[META_CNT]);
            memset(((char *)*ary) + ary_type_size(*ary) * ary_sz(*ary), 0,
                   (capa - ary_sz(*ary)) * ary_type_size(*ary));
            ary_capa(*ary) = capa;
        }
        ary_sz(*ary) = size;
    }
}

void ary_set_i(void ***ary, int index, void *value)
{
    if (index < 0) {
        index += ary_sz(*ary);
        if (index < 0) {
            RAISE(INDEX_ERROR, "index %d out array", index);
        }
    }
    ary_resize_i(ary, index);
    (*ary)[index] = value;
}

void *ary_get_i(void **ary, int index)
{
    if (index < 0) {
        index += ary_sz(ary);
    }
    if (index >= 0 && index < ary_sz(ary)) {
        return ary[index];
    }
    else {
        return NULL;
    }
}

void ary_push_i(void ***ary, void *value)
{
    int size = ary_sz(*ary);
    ary_resize_i(ary, size);
    (*ary)[size] = value;
}

void *ary_pop_i(void **ary)
{
    void *val = ary[--ary_sz(ary)];
    ary[ary_sz(ary)] = NULL;
    return val;
}

void ary_unshift_i(void ***ary, void *value)
{
    int size = ary_sz(*ary);
    ary_resize_i(ary, size);
    memmove(*ary + 1, *ary, size * sizeof(void *));
    (*ary)[0] = value;
}

void *ary_shift_i(void **ary)
{
    void *val = ary[0];
    int size = --ary_sz(ary);
    memmove(ary, ary + 1, size * sizeof(void *));
    ary[size] = NULL;
    return val;
}

void *ary_remove_i(void **ary, int index)
{
    if (index >= 0 && index < ary_sz(ary)) {
        void *val = ary[index];
        memmove(ary + index, ary + index + 1,
                (ary_sz(ary) - index + 1) * sizeof(void *));
        ary_sz(ary)--;
        return val;
    }
    else {
        return NULL;
    }
}

void ary_delete_i(void **ary, int index, void (*free_elem)(void *p))
{
    free_elem(ary_remove(ary, index));
}

void ary_destroy_i(void **ary, void (*free_elem)(void *p))
{
    int i;
    for (i = ary_sz(ary) - 1; i >= 0; i--) {
        free_elem(ary[i]);
    }
    ary_free(ary);
}