]> git.lizzy.rs Git - rust.git/blob - src/rt/rust_util.h
Populate tree.
[rust.git] / src / rt / rust_util.h
1 #ifndef RUST_UTIL_H
2 #define RUST_UTIL_H
3
4 // Reference counted objects
5
6 template <typename T>
7 rc_base<T>::rc_base() :
8     refcnt(1)
9 {
10 }
11
12 template <typename T>
13 rc_base<T>::~rc_base()
14 {
15 }
16
17 // Utility type: pointer-vector.
18
19 template <typename T>
20 ptr_vec<T>::ptr_vec(rust_dom *dom) :
21     dom(dom),
22     alloc(INIT_SIZE),
23     fill(0),
24     data(new (dom) T*[alloc])
25 {
26     I(dom, data);
27     dom->log(rust_log::MEM,
28              "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR,
29              (uintptr_t)data, (uintptr_t)this);
30 }
31
32 template <typename T>
33 ptr_vec<T>::~ptr_vec()
34 {
35     I(dom, data);
36     dom->log(rust_log::MEM,
37              "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR,
38              (uintptr_t)this, (uintptr_t)data);
39     I(dom, fill == 0);
40     dom->free(data);
41 }
42
43 template <typename T> T *&
44 ptr_vec<T>::operator[](size_t offset) {
45     I(dom, data[offset]->idx == offset);
46     return data[offset];
47 }
48
49 template <typename T>
50 void
51 ptr_vec<T>::push(T *p)
52 {
53     I(dom, data);
54     I(dom, fill <= alloc);
55     if (fill == alloc) {
56         alloc *= 2;
57         data = (T **)dom->realloc(data, alloc * sizeof(T*));
58         I(dom, data);
59     }
60     I(dom, fill < alloc);
61     p->idx = fill;
62     data[fill++] = p;
63 }
64
65 template <typename T>
66 T *
67 ptr_vec<T>::pop()
68 {
69     return data[--fill];
70 }
71
72 template <typename T>
73 void
74 ptr_vec<T>::trim(size_t sz)
75 {
76     I(dom, data);
77     if (sz <= (alloc / 4) &&
78         (alloc / 2) >= INIT_SIZE) {
79         alloc /= 2;
80         I(dom, alloc >= fill);
81         data = (T **)dom->realloc(data, alloc * sizeof(T*));
82         I(dom, data);
83     }
84 }
85
86 template <typename T>
87 void
88 ptr_vec<T>::swapdel(T *item)
89 {
90     /* Swap the endpoint into i and decr fill. */
91     I(dom, data);
92     I(dom, fill > 0);
93     I(dom, item->idx < fill);
94     fill--;
95     if (fill > 0) {
96         T *subst = data[fill];
97         size_t idx = item->idx;
98         data[idx] = subst;
99         subst->idx = idx;
100     }
101 }
102
103 // Inline fn used regularly elsewhere.
104
105 static inline size_t
106 next_power_of_two(size_t s)
107 {
108     size_t tmp = s - 1;
109     tmp |= tmp >> 1;
110     tmp |= tmp >> 2;
111     tmp |= tmp >> 4;
112     tmp |= tmp >> 8;
113     tmp |= tmp >> 16;
114 #if SIZE_MAX == UINT64_MAX
115     tmp |= tmp >> 32;
116 #endif
117     return tmp + 1;
118 }
119
120 // Vectors (rust-user-code level).
121
122 struct
123 rust_vec : public rc_base<rust_vec>
124 {
125     size_t alloc;
126     size_t fill;
127     uint8_t data[];
128     rust_vec(rust_dom *dom, size_t alloc, size_t fill, uint8_t const *d) :
129         alloc(alloc),
130         fill(fill)
131     {
132         if (d || fill) {
133             I(dom, d);
134             I(dom, fill);
135             memcpy(&data[0], d, fill);
136         }
137     }
138     ~rust_vec() {}
139 };
140
141 // Rust types vec and str look identical from our perspective.
142 typedef rust_vec rust_str;
143
144 //
145 // Local Variables:
146 // mode: C++
147 // fill-column: 78;
148 // indent-tabs-mode: nil
149 // c-basic-offset: 4
150 // buffer-file-coding-system: utf-8-unix
151 // compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
152 // End:
153 //
154
155 #endif