autoarray.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "std-includes.h" | ||
| 4 | |||
| 5 | //Note: T must be a pointer type, or stuff will screw up. To make a pointer last longer than this object, assign nullptr to it and it won't free the old one. | ||
| 6 | template<typename T> class autoptr { | ||
| 7 | T ptr; | ||
| 8 | public: | ||
| 9 | 4188396 | operator T() const | |
| 10 | { | ||
| 11 | 4188396 | return ptr; | |
| 12 | } | ||
| 13 | |||
| 14 | 258 | autoptr& operator=(T ptr_) | |
| 15 | { | ||
| 16 | 258 | ptr = ptr_; | |
| 17 | 258 | return *this; | |
| 18 | } | ||
| 19 | |||
| 20 | 336 | autoptr() | |
| 21 | { | ||
| 22 | 336 | ptr = nullptr; | |
| 23 | 336 | } | |
| 24 | |||
| 25 | 1979436 | autoptr(T ptr_) | |
| 26 | { | ||
| 27 | 1979436 | ptr = ptr_; | |
| 28 | 1979436 | } | |
| 29 | |||
| 30 | autoptr(const autoptr<T>& ptr_) | ||
| 31 | { | ||
| 32 | ptr = ptr_.ptr; | ||
| 33 | } | ||
| 34 | |||
| 35 | 1979752 | ~autoptr() | |
| 36 | { | ||
| 37 | 1979752 | if (ptr) free((void*)ptr); | |
| 38 | 1979752 | } | |
| 39 | }; | ||
| 40 | |||
| 41 | template<typename T> class autoarray { | ||
| 42 | public: | ||
| 43 | int count; | ||
| 44 | |||
| 45 | private: | ||
| 46 | T* ptr; | ||
| 47 | int bufferlen; | ||
| 48 | |||
| 49 | T dummy; | ||
| 50 | static const int default_size = 128; | ||
| 51 | |||
| 52 | ✗ | const T& getconst(int id) const | |
| 53 | { | ||
| 54 | ✗ | if (id < 0) return dummy; | |
| 55 | ✗ | if (id >= count) return dummy; | |
| 56 | ✗ | return ptr[id]; | |
| 57 | } | ||
| 58 | |||
| 59 | 2072130 | T& get(int id) | |
| 60 | { | ||
| 61 | 2072130 | if (id < 0) return dummy; | |
| 62 | 2072130 | if (id >= bufferlen - 4) | |
| 63 | { | ||
| 64 | 44 | resize(id); | |
| 65 | } | ||
| 66 | 2072130 | if (id >= count) | |
| 67 | { | ||
| 68 | 155240 | for (int i = count;i <= id;i++) new(ptr + i) T(); | |
| 69 | 77584 | count = id + 1; | |
| 70 | } | ||
| 71 | 2072130 | return ptr[id]; | |
| 72 | } | ||
| 73 | |||
| 74 | 44 | void resize(int size) | |
| 75 | { | ||
| 76 | 44 | int oldlen = count; | |
| 77 | 88 | while (bufferlen <= size + 4) bufferlen *= 2; | |
| 78 | 44 | T *old = ptr; | |
| 79 | 44 | ptr = (T*)malloc(sizeof(T)*(size_t)bufferlen); | |
| 80 | 135324 | for(int i = 0; i < oldlen; i++){ | |
| 81 | 135280 | new(ptr + i) T(); | |
| 82 | 135280 | ptr[i] = static_cast<T &&>(old[i]); | |
| 83 | } | ||
| 84 | 44 | free(old); | |
| 85 | 44 | memset(ptr + oldlen, 0, (size_t)(bufferlen - oldlen) * sizeof(T)); | |
| 86 | 44 | } | |
| 87 | |||
| 88 | public: | ||
| 89 | |||
| 90 | 7152 | void reset(int keep = 0) | |
| 91 | { | ||
| 92 | 7152 | if (keep >= count) return; | |
| 93 | 1736 | for (int i = keep;i < count;i++) ptr[i].~T(); | |
| 94 | 728 | memset(ptr + keep, 0, (size_t)(count - keep) * sizeof(T)); | |
| 95 | 728 | if (keep < bufferlen / 2) | |
| 96 | { | ||
| 97 | 1970 | while (keep < bufferlen / 2 && bufferlen>8) bufferlen /= 2; | |
| 98 | 728 | T *old = ptr; | |
| 99 | 728 | ptr = (T*)malloc(sizeof(T)*(size_t)bufferlen); | |
| 100 | 734 | for(int i = 0; i < keep; i++){ | |
| 101 | 6 | new(ptr + i) T(); | |
| 102 | 6 | ptr[i] = static_cast<T &&>(old[i]); | |
| 103 | } | ||
| 104 | 728 | free(old); | |
| 105 | |||
| 106 | } | ||
| 107 | 728 | count = keep; | |
| 108 | } | ||
| 109 | |||
| 110 | 1995870 | T& operator[](int id) | |
| 111 | { | ||
| 112 | 1995870 | return get(id); | |
| 113 | } | ||
| 114 | |||
| 115 | ✗ | const T& operator[](int id) const | |
| 116 | { | ||
| 117 | ✗ | return getconst(id); | |
| 118 | } | ||
| 119 | |||
| 120 | operator T*() | ||
| 121 | { | ||
| 122 | return ptr; | ||
| 123 | } | ||
| 124 | |||
| 125 | operator const T*() const | ||
| 126 | { | ||
| 127 | return ptr; | ||
| 128 | } | ||
| 129 | |||
| 130 | 76260 | T& append(const T& item) | |
| 131 | { | ||
| 132 | 76260 | return (get(count) = item); | |
| 133 | } | ||
| 134 | |||
| 135 | //insert is not safe for non pod types!!! | ||
| 136 | void insert(int pos) | ||
| 137 | { | ||
| 138 | if (pos<0 || pos>count) return; | ||
| 139 | if (count >= bufferlen - 4) | ||
| 140 | { | ||
| 141 | resize(count); | ||
| 142 | } | ||
| 143 | memmove(ptr + pos + 1, ptr + pos, sizeof(T)*(count - pos)); | ||
| 144 | memset(ptr + pos, 0, sizeof(T)); | ||
| 145 | new(ptr + pos) T(); | ||
| 146 | count++; | ||
| 147 | } | ||
| 148 | |||
| 149 | void insert(int pos, const T& item) | ||
| 150 | { | ||
| 151 | if (pos<0 || pos>count) return; | ||
| 152 | if (count >= bufferlen - 4) | ||
| 153 | { | ||
| 154 | resize(count); | ||
| 155 | } | ||
| 156 | memmove(ptr + pos + 1, ptr + pos, sizeof(T)*(size_t)(count - pos)); | ||
| 157 | memset(ptr + pos, 0, sizeof(T)); | ||
| 158 | new(ptr + pos) T(); | ||
| 159 | ptr[pos] = item; | ||
| 160 | count++; | ||
| 161 | } | ||
| 162 | |||
| 163 | 54 | void remove(int id) | |
| 164 | { | ||
| 165 | 54 | if (id < 0 || id >= count) return; | |
| 166 | 54 | count--; | |
| 167 | 54 | ptr[id].~T(); | |
| 168 | 54 | for(int i = id; i < count; i++){ | |
| 169 | ✗ | ptr[i] = static_cast<T &&>(ptr[i+1]); | |
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | 4700 | autoarray() | |
| 174 | 2092 | { | |
| 175 | 4700 | ptr = (T*)malloc(sizeof(T) * default_size); | |
| 176 | 4700 | memset(ptr, 0, default_size*sizeof(T)); | |
| 177 | 4700 | bufferlen = default_size; | |
| 178 | 4700 | count = 0; | |
| 179 | 4700 | } | |
| 180 | |||
| 181 | 2999 | ~autoarray() | |
| 182 | { | ||
| 183 | 41807 | for (int i = 0;i < count;i++) ptr[i].~T(); | |
| 184 | 2999 | free(ptr); | |
| 185 | 2999 | } | |
| 186 | |||
| 187 | #ifdef SERIALIZER | ||
| 188 | void serialize(serializer& s) | ||
| 189 | { | ||
| 190 | if (s.serializing) s(count); | ||
| 191 | else | ||
| 192 | { | ||
| 193 | int i; | ||
| 194 | s(i); | ||
| 195 | get(i - 1); | ||
| 196 | } | ||
| 197 | for (int i = 0;i < count;i++) s(ptr[i]); | ||
| 198 | } | ||
| 199 | #endif | ||
| 200 | #define SERIALIZER_BANNED | ||
| 201 | }; | ||
| 202 |