|
5 | 5 |
|
6 | 6 | namespace builder {
|
7 | 7 |
|
| 8 | + |
| 9 | +// If the array is of dyn_vars, we initialize with a |
| 10 | +// builder, anything else and we directly initialize with T |
| 11 | +// This avoids unnecessary copies unless entirely necessary |
| 12 | +template <typename T> |
| 13 | +struct initializer_selector { |
| 14 | + typedef const T type; |
| 15 | +}; |
| 16 | + |
| 17 | +template <typename T> |
| 18 | +struct initializer_selector<dyn_var<T>> { |
| 19 | + typedef builder type; |
| 20 | +}; |
| 21 | + |
| 22 | + |
| 23 | + |
8 | 24 | template <typename T, size_t size = 0>
|
9 |
| -class dyn_arr { |
| 25 | +class array { |
10 | 26 | private:
|
11 |
| - dyn_var<T> *m_arr = nullptr; |
| 27 | + T *m_arr = nullptr; |
12 | 28 | size_t actual_size = 0;
|
13 | 29 |
|
14 | 30 | public:
|
15 |
| - dyn_arr() { |
| 31 | + array() { |
16 | 32 | if (size) {
|
17 | 33 | actual_size = size;
|
18 |
| - m_arr = (dyn_var<T> *)new char[sizeof(dyn_var<T>) * actual_size]; |
| 34 | + m_arr = (T *)new char[sizeof(T) * actual_size]; |
19 | 35 | for (static_var<size_t> i = 0; i < actual_size; i++) {
|
20 |
| - new (m_arr + i) dyn_var<T>(); |
| 36 | + new (m_arr + i) T(); |
21 | 37 | }
|
| 38 | + |
22 | 39 | // static tags for array nodes need to be adjusted
|
23 | 40 | // so they are treated different from each other despite
|
24 | 41 | // being declared at the same location.
|
25 | 42 | // dyn_arr are special case of vars that escape their static scope but still
|
26 | 43 | // shouldn't be treated together
|
27 | 44 | // We do this by adding additional metadata on all of them
|
28 |
| - for (static_var<size_t> i = 0; i < actual_size; i++) { |
29 |
| - m_arr[i].block_var->template setMetadata<int>("allow_escape_scope", 1); |
30 |
| - } |
| 45 | + |
| 46 | + // We are removing the metadata for allow_escape_scope because it is not being |
| 47 | + // used anyway right now. Enabling this would require us to set it as a variable |
| 48 | + // inside the context so all the dynamic variables constructed in this block would have |
| 49 | + // the metadata set |
| 50 | + |
31 | 51 | }
|
32 | 52 | }
|
33 |
| - dyn_arr(const std::initializer_list<builder> &init) { |
| 53 | + // We need a SFINAE constructor of anything that is convertible to T |
| 54 | + // but let's stick with T for now |
| 55 | + array(const std::initializer_list<typename initializer_selector<T>::type> &init) { |
34 | 56 | if (size) {
|
35 | 57 | actual_size = size;
|
36 | 58 | } else {
|
37 | 59 | actual_size = init.size();
|
38 | 60 | }
|
39 |
| - m_arr = (dyn_var<T> *)new char[sizeof(dyn_var<T>) * actual_size]; |
| 61 | + m_arr = (T *)new char[sizeof(T) * actual_size]; |
40 | 62 | for (static_var<size_t> i = 0; i < actual_size; i++) {
|
41 | 63 | if (i < init.size())
|
42 |
| - new (m_arr + i) dyn_var<T>(*(init.begin() + i)); |
| 64 | + new (m_arr + i) T(*(init.begin() + i)); |
43 | 65 | else
|
44 |
| - new (m_arr + i) dyn_var<T>(); |
45 |
| - } |
46 |
| - for (static_var<size_t> i = 0; i < actual_size; i++) { |
47 |
| - m_arr[i].block_var->template setMetadata<int>("allow_escape_scope", 1); |
| 66 | + new (m_arr + i) T(); |
48 | 67 | }
|
49 | 68 | }
|
| 69 | + |
| 70 | + |
50 | 71 | void set_size(size_t new_size) {
|
51 | 72 | assert(size == 0 && "set_size should be only called for dyn_arr without size");
|
52 | 73 | assert(m_arr == nullptr && "set_size should be only called once");
|
53 | 74 | actual_size = new_size;
|
54 |
| - m_arr = (dyn_var<T> *)new char[sizeof(dyn_var<T>) * actual_size]; |
55 |
| - for (static_var<size_t> i = 0; i < actual_size; i++) { |
56 |
| - new (m_arr + i) dyn_var<T>(); |
57 |
| - } |
| 75 | + m_arr = (T *)new char[sizeof(T) * actual_size]; |
58 | 76 | for (static_var<size_t> i = 0; i < actual_size; i++) {
|
59 |
| - m_arr[i].block_var->template setMetadata<int>("allow_escape_scope", 1); |
| 77 | + new (m_arr + i) T(); |
60 | 78 | }
|
61 | 79 | }
|
62 | 80 |
|
63 | 81 | template <typename T2, size_t N>
|
64 |
| - void initialize_from_other(const dyn_arr<T2, N> &other) { |
| 82 | + void initialize_from_other(const array<T2, N> &other) { |
65 | 83 | if (size) {
|
66 | 84 | actual_size = size;
|
67 | 85 | } else {
|
68 | 86 | actual_size = other.actual_size;
|
69 | 87 | }
|
70 |
| - m_arr = (dyn_var<T> *)new char[sizeof(dyn_var<T>) * actual_size]; |
| 88 | + m_arr = (T*)new char[sizeof(T) * actual_size]; |
71 | 89 | for (static_var<size_t> i = 0; i < actual_size; i++) {
|
72 | 90 | if (i < other.actual_size)
|
73 |
| - new (m_arr + i) dyn_var<T>(other[i]); |
| 91 | + new (m_arr + i) T(other[i]); |
74 | 92 | else
|
75 |
| - new (m_arr + i) dyn_var<T>(); |
76 |
| - } |
77 |
| - for (static_var<size_t> i = 0; i < actual_size; i++) { |
78 |
| - m_arr[i].block_var->template setMetadata<int>("allow_escape_scope", 1); |
| 93 | + new (m_arr + i) T(); |
79 | 94 | }
|
80 | 95 | }
|
81 | 96 |
|
82 |
| - dyn_arr(const dyn_arr &other) { |
| 97 | + array(const array &other) { |
83 | 98 | initialize_from_other(other);
|
84 | 99 | }
|
85 | 100 | template <typename T2, size_t N>
|
86 |
| - dyn_arr(const dyn_arr<T2, N> &other) { |
| 101 | + array(const array<T2, N> &other) { |
87 | 102 | initialize_from_other(other);
|
88 | 103 | }
|
89 | 104 |
|
90 |
| - dyn_arr &operator=(const dyn_arr &other) = delete; |
| 105 | + array &operator=(const array &other) = delete; |
91 | 106 |
|
92 |
| - dyn_var<T> &operator[](size_t index) { |
| 107 | + T &operator[](size_t index) { |
93 | 108 | assert(m_arr != nullptr && "Should call set_size for arrays that don't have a size");
|
94 | 109 | return m_arr[index];
|
95 | 110 | }
|
96 |
| - const dyn_var<T> &operator[](size_t index) const { |
| 111 | + const T &operator[](size_t index) const { |
97 | 112 | assert(m_arr != nullptr && "Should call set_size for arrays that don't have a size");
|
98 | 113 | return m_arr[index];
|
99 | 114 | }
|
100 | 115 |
|
101 |
| - ~dyn_arr() { |
| 116 | + ~array() { |
102 | 117 | if (m_arr) {
|
103 | 118 | for (static_var<size_t> i = 0; i < actual_size; i++) {
|
104 |
| - m_arr[i].~dyn_var<T>(); |
| 119 | + m_arr[i].~T(); |
105 | 120 | }
|
106 | 121 |
|
107 | 122 | delete[](char *) m_arr;
|
108 | 123 | }
|
109 | 124 | }
|
110 | 125 |
|
111 | 126 | template <typename T2, size_t N>
|
112 |
| - friend class dyn_arr; |
| 127 | + friend class array; |
113 | 128 | };
|
114 | 129 |
|
| 130 | +template <typename T, size_t N = 0> |
| 131 | +using dyn_arr = array<dyn_var<T>, N>; |
| 132 | + |
| 133 | +template <typename T, size_t N = 0> |
| 134 | +using arr = array<T, N>; |
| 135 | + |
115 | 136 | } // namespace builder
|
116 | 137 |
|
117 | 138 | #endif
|
0 commit comments