1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef RUNTIME_INCLUDE_TAIHE_VECTOR_HPP_ 16 #define RUNTIME_INCLUDE_TAIHE_VECTOR_HPP_ 17 // NOLINTBEGIN 18 19 #include <taihe/common.hpp> 20 21 #include <algorithm> 22 #include <utility> 23 24 #define VEC_GROWTH_FACTOR 2 25 26 namespace taihe { 27 template <typename T> 28 struct vector_view; 29 30 template <typename T> 31 struct vector; 32 33 template <typename T> 34 struct vector_view { 35 public: 36 using value_type = T; 37 using size_type = std::size_t; 38 using reference = T &; 39 using pointer = T *; 40 reservetaihe::vector_view41 void reserve(std::size_t cap) const 42 { 43 if (cap < m_handle->len) { 44 return; 45 } 46 m_handle->cap = cap; 47 m_handle->buffer = reinterpret_cast<T *>(realloc(m_handle->buffer, sizeof(T) * cap)); 48 } 49 sizetaihe::vector_view50 std::size_t size() const noexcept 51 { 52 return m_handle->len; 53 } 54 emptytaihe::vector_view55 bool empty() const noexcept 56 { 57 return m_handle->len == 0; 58 } 59 capacitytaihe::vector_view60 std::size_t capacity() const noexcept 61 { 62 return m_handle->cap; 63 } 64 65 template <typename... Args> emplace_backtaihe::vector_view66 T &emplace_back(Args &&...args) const 67 { 68 std::size_t required_cap = m_handle->len + 1; 69 if (required_cap > m_handle->cap) { 70 this->reserve(std::max(required_cap, m_handle->cap * VEC_GROWTH_FACTOR)); 71 } 72 T *location = &m_handle->buffer[m_handle->len]; 73 new (location) T {std::forward<Args>(args)...}; 74 ++m_handle->len; 75 return *location; 76 } 77 push_backtaihe::vector_view78 T &push_back(T &&value) const 79 { 80 return emplace_back(std::move(value)); 81 } 82 push_backtaihe::vector_view83 T &push_back(T const &value) const 84 { 85 return emplace_back(value); 86 } 87 operator []taihe::vector_view88 T &operator[](std::size_t index) const 89 { 90 return m_handle->buffer[index]; 91 } 92 pop_backtaihe::vector_view93 void pop_back() const 94 { 95 if (m_handle->len == 0) { 96 return; 97 } 98 std::destroy_at(&m_handle->buffer[m_handle->len]); 99 --m_handle->len; 100 } 101 cleartaihe::vector_view102 void clear() const noexcept 103 { 104 for (std::size_t i = 0; i < m_handle->len; i++) { 105 std::destroy_at(&m_handle->buffer[i]); 106 } 107 m_handle->len = 0; 108 } 109 110 using iterator = T *; 111 using const_iterator = T const *; 112 begintaihe::vector_view113 iterator begin() const 114 { 115 return m_handle->buffer; 116 } 117 endtaihe::vector_view118 iterator end() const 119 { 120 return m_handle->buffer + m_handle->len; 121 } 122 cbegintaihe::vector_view123 const_iterator cbegin() const 124 { 125 return begin(); 126 } 127 cendtaihe::vector_view128 const_iterator cend() const 129 { 130 return end(); 131 } 132 133 protected: 134 struct data_t { 135 TRefCount count; 136 std::size_t cap; 137 T *buffer; 138 std::size_t len; 139 } *m_handle; 140 vector_viewtaihe::vector_view141 explicit vector_view(data_t *handle) : m_handle(handle) {} 142 143 friend struct vector<T>; 144 145 friend struct std::hash<vector<T>>; 146 operator ==(vector_view lhs,vector_view rhs)147 friend bool operator==(vector_view lhs, vector_view rhs) 148 { 149 return lhs.m_handle == rhs.m_handle; 150 } 151 }; 152 153 template <typename T> 154 struct vector : vector_view<T> { 155 using typename vector_view<T>::data_t; 156 using vector_view<T>::m_handle; 157 vectortaihe::vector158 explicit vector(std::size_t cap = 0) : vector(reinterpret_cast<data_t *>(malloc(sizeof(data_t)))) 159 { 160 tref_set(&m_handle->count, 1); 161 m_handle->cap = cap; 162 m_handle->buffer = reinterpret_cast<T *>(malloc(sizeof(T) * cap)); 163 m_handle->len = 0; 164 } 165 vectortaihe::vector166 vector(vector<T> &&other) noexcept : vector(other.m_handle) 167 { 168 other.m_handle = nullptr; 169 } 170 vectortaihe::vector171 vector(vector<T> const &other) : vector(other.m_handle) 172 { 173 if (m_handle) { 174 tref_inc(&m_handle->count); 175 } 176 } 177 vectortaihe::vector178 vector(vector_view<T> const &other) : vector(other.m_handle) 179 { 180 if (m_handle) { 181 tref_inc(&m_handle->count); 182 } 183 } 184 operator =taihe::vector185 vector &operator=(vector other) 186 { 187 std::swap(this->m_handle, other.m_handle); 188 return *this; 189 } 190 ~vectortaihe::vector191 ~vector() 192 { 193 if (m_handle && tref_dec(&m_handle->count)) { 194 this->clear(); 195 free(m_handle->buffer); 196 free(m_handle); 197 } 198 } 199 200 private: vectortaihe::vector201 explicit vector(data_t *handle) : vector_view<T>(handle) {} 202 }; 203 204 template <typename T> 205 struct as_abi<vector<T>> { 206 using type = void *; 207 }; 208 209 template <typename T> 210 struct as_abi<vector_view<T>> { 211 using type = void *; 212 }; 213 214 template <typename T> 215 struct as_param<vector<T>> { 216 using type = vector_view<T>; 217 }; 218 } // namespace taihe 219 220 template <typename T> 221 struct std::hash<taihe::vector<T>> { operator ()std::hash222 std::size_t operator()(taihe::vector_view<T> val) const noexcept 223 { 224 return reinterpret_cast<std::size_t>(val.m_handle); 225 } 226 }; 227 228 #ifdef VEC_GROWTH_FACTOR 229 #undef VEC_GROWTH_FACTOR 230 #endif 231 // NOLINTEND 232 #endif // RUNTIME_INCLUDE_TAIHE_VECTOR_HPP_