-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathArray.cpp
124 lines (107 loc) · 3.15 KB
/
Array.cpp
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
#include "Array.h"
#include "Reflection.h"
namespace sf {
struct ArrayType final : Type
{
ArrayType(const TypeInfo &info, Type *elemType)
: Type("sf::Array", info, HasArray | HasArrayResize)
{
elementType = elemType;
}
virtual void getName(sf::StringBuf &buf) override
{
buf.append("sf::Array<");
elementType->getName(buf);
buf.append(">");
}
virtual VoidSlice instGetArray(void *inst, sf::Array<char> *scratch) override
{
ArrayBase *arr = (ArrayBase*)inst;
return { arr->data, arr->size };
}
virtual VoidSlice instArrayReserve(void *inst, size_t size, sf::Array<char> *scratch) override
{
ArrayBase *arr = (ArrayBase*)inst;
if (arr->capacity < size) {
sf_assert(size <= UINT32_MAX);
arr->capacity = (uint32_t)size;
void *newData = memAlloc(size * elementType->info.size);
if (arr->size) {
elementType->info.moveRange(newData, arr->data, arr->size);
}
arr->data = newData;
}
if (size > arr->size) {
char *base = (char*)arr->data + arr->size * elementType->info.size;
elementType->info.constructRange(base, size - arr->size);
}
return { arr->data, arr->capacity };
}
virtual void instArrayResize(void *inst, size_t size, VoidSlice elements) override
{
ArrayBase *arr = (ArrayBase*)inst;
sf_assert(arr->capacity >= size);
if (size < arr->size) {
char *base = (char*)arr->data + size * elementType->info.size;
elementType->info.destructRange(base, arr->size - size);
}
arr->size = (uint32_t)size;
}
};
struct SmallArrayType final : Type
{
uint32_t n;
SmallArrayType(const TypeInfo &info, Type *elemType, uint32_t n)
: Type("sf::SmallArray", info, HasArray | HasArrayResize), n(n)
{
elementType = elemType;
}
virtual void getName(sf::StringBuf &buf) override
{
buf.append("sf::SmallArray<");
elementType->getName(buf);
buf.format(", %u>", n);
}
virtual VoidSlice instGetArray(void *inst, sf::Array<char> *scratch) override
{
ArrayBase *arr = (ArrayBase*)inst;
return { arr->data, arr->size };
}
virtual VoidSlice instArrayReserve(void *inst, size_t size, sf::Array<char> *scratch) override
{
ArrayBase *arr = (ArrayBase*)inst;
if (arr->capacity < size) {
sf_assert(size <= UINT32_MAX);
arr->capacity = (uint32_t)size;
void *newData = memAlloc(size * elementType->info.size);
if (arr->size) {
elementType->info.moveRange(newData, arr->data, arr->size);
}
arr->data = newData;
}
if (size > arr->size) {
char *base = (char*)arr->data + arr->size * elementType->info.size;
elementType->info.constructRange(base, size - arr->size);
}
return { arr->data, arr->capacity };
}
virtual void instArrayResize(void *inst, size_t size, VoidSlice elements) override
{
ArrayBase *arr = (ArrayBase*)inst;
sf_assert(arr->capacity >= size);
if (size < arr->size) {
char *base = (char*)arr->data + size * elementType->info.size;
elementType->info.destructRange(base, arr->size - size);
}
arr->size = (uint32_t)size;
}
};
void initArrayType(Type *t, const TypeInfo &info, Type *elemType)
{
new (t) ArrayType(info, elemType);
}
void initSmallArrayType(Type *t, const TypeInfo &info, Type *elemType, uint32_t n)
{
new (t) SmallArrayType(info, elemType, n);
}
}