• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ARRAY_HPP_
16 #define RUNTIME_INCLUDE_TAIHE_ARRAY_HPP_
17 // NOLINTBEGIN
18 
19 #include <taihe/array.abi.h>
20 #include <taihe/common.hpp>
21 
22 #include <array>
23 #include <cstddef>
24 #include <cstdlib>
25 #include <memory>
26 #include <stdexcept>
27 #include <type_traits>
28 #include <utility>
29 #include <vector>
30 
31 namespace taihe {
32 template <typename cpp_owner_t>
33 struct array_view;
34 
35 template <typename cpp_owner_t>
36 struct array;
37 
38 template <typename cpp_owner_t>
39 struct array_view {
40     using value_type = cpp_owner_t;
41     using size_type = std::size_t;
42     using reference = value_type &;
43     using const_reference = value_type const &;
44     using pointer = value_type *;
45     using const_pointer = value_type const *;
46     using iterator = value_type *;
47     using const_iterator = value_type const *;
48     using reverse_iterator = std::reverse_iterator<iterator>;
49     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
50 
array_viewtaihe::array_view51     array_view(pointer data, size_type size) noexcept : m_size(size), m_data(data) {}  // main constructor
52 
array_viewtaihe::array_view53     array_view() noexcept : m_size(0), m_data(nullptr) {}
54 
55     template <typename C, size_type N>
array_viewtaihe::array_view56     array_view(C (&value)[N]) noexcept : array_view(value, N)
57     {
58     }
59 
60     template <typename C>
array_viewtaihe::array_view61     array_view(std::vector<C> &value) noexcept : array_view(value.data(), static_cast<size_type>(value.size()))
62     {
63     }
64 
65     template <typename C>
array_viewtaihe::array_view66     array_view(std::vector<C> const &value) noexcept : array_view(value.data(), static_cast<size_type>(value.size()))
67     {
68     }
69 
70     template <typename C, std::size_t N>
array_viewtaihe::array_view71     array_view(std::array<C, N> &value) noexcept : array_view(value.data(), static_cast<size_type>(value.size()))
72     {
73     }
74 
75     template <typename C, std::size_t N>
array_viewtaihe::array_view76     array_view(std::array<C, N> const &value) noexcept : array_view(value.data(), static_cast<size_type>(value.size()))
77     {
78     }
79 
80     template <typename C>
array_viewtaihe::array_view81     array_view(array_view<C> const &other) noexcept : array_view(other.data(), other.size())
82     {
83     }
84 
85     template <typename C>
array_viewtaihe::array_view86     array_view(array<C> const &other) noexcept : array_view(other.data(), other.size())
87     {
88     }
89 
operator []taihe::array_view90     reference operator[](size_type const pos) const noexcept
91     {
92         TH_ASSERT(pos < size(), "Pos should be less than array's size");
93         return m_data[pos];
94     }
95 
attaihe::array_view96     reference at(size_type const pos) const
97     {
98         if (size() <= pos) {
99             TH_THROW(std::out_of_range, "Invalid array subscript");
100         }
101         return m_data[pos];
102     }
103 
fronttaihe::array_view104     reference front() const noexcept
105     {
106         TH_ASSERT(m_size > 0, "Array's size should be greater than 0");
107         return *m_data;
108     }
109 
backtaihe::array_view110     reference back() const noexcept
111     {
112         TH_ASSERT(m_size > 0, "Array's size should be greater than 0");
113         return m_data[m_size - 1];
114     }
115 
datataihe::array_view116     pointer data() const noexcept
117     {
118         return m_data;
119     }
120 
emptytaihe::array_view121     bool empty() const noexcept
122     {
123         return m_size == 0;
124     }
125 
sizetaihe::array_view126     size_type size() const noexcept
127     {
128         return m_size;
129     }
130 
begintaihe::array_view131     iterator begin() const noexcept
132     {
133         return m_data;
134     }
135 
endtaihe::array_view136     iterator end() const noexcept
137     {
138         return m_data + m_size;
139     }
140 
rbegintaihe::array_view141     reverse_iterator rbegin() const noexcept
142     {
143         return m_data + m_size;
144     }
145 
rendtaihe::array_view146     reverse_iterator rend() const noexcept
147     {
148         return m_data;
149     }
150 
cbegintaihe::array_view151     const_iterator cbegin() const noexcept
152     {
153         return m_data;
154     }
155 
cendtaihe::array_view156     const_iterator cend() const noexcept
157     {
158         return m_data + m_size;
159     }
160 
crbegintaihe::array_view161     const_reverse_iterator crbegin() const noexcept
162     {
163         return m_data + m_size;
164     }
165 
crendtaihe::array_view166     const_reverse_iterator crend() const noexcept
167     {
168         return m_data;
169     }
170 
operator ==(array_view left,array_view right)171     friend bool operator==(array_view left, array_view right) noexcept
172     {
173         return std::equal(left.begin(), left.end(), right.begin(), right.end());
174     }
175 
operator !=(array_view left,array_view right)176     friend bool operator!=(array_view left, array_view right) noexcept
177     {
178         return !(left == right);
179     }
180 
operator <(array_view left,array_view right)181     friend bool operator<(array_view left, array_view right) noexcept
182     {
183         return std::lexicographical_compare(left.begin(), left.end(), right.begin(), right.end());
184     }
185 
operator >(array_view left,array_view right)186     friend bool operator>(array_view left, array_view right) noexcept
187     {
188         return right < left;
189     }
190 
operator <=(array_view left,array_view right)191     friend bool operator<=(array_view left, array_view right) noexcept
192     {
193         return !(right < left);
194     }
195 
operator >=(array_view left,array_view right)196     friend bool operator>=(array_view left, array_view right) noexcept
197     {
198         return !(left < right);
199     }
200 
201 protected:
202     std::size_t m_size;
203     cpp_owner_t *m_data;
204 };
205 
206 struct copy_data_t {};
207 
208 constexpr inline copy_data_t copy_data;
209 
210 struct move_data_t {};
211 
212 constexpr inline move_data_t move_data;
213 
214 template <typename cpp_owner_t>
215 struct array : public array_view<cpp_owner_t> {
216     using typename array_view<cpp_owner_t>::pointer;
217     using typename array_view<cpp_owner_t>::size_type;
218 
arraytaihe::array219     explicit array(pointer data, size_type size) noexcept : array_view<cpp_owner_t>(data, size) {}  // main constructor
220 
221     template <typename Iterator>
arraytaihe::array222     array(copy_data_t, Iterator begin, size_type size) noexcept
223         : array_view<cpp_owner_t>(reinterpret_cast<cpp_owner_t *>(malloc(size * sizeof(cpp_owner_t))), size)
224     {
225         std::uninitialized_copy_n(begin, size, this->m_data);
226     }
227 
228     template <typename Iterator>
arraytaihe::array229     array(move_data_t, Iterator begin, size_type size) noexcept
230         : array_view<cpp_owner_t>(reinterpret_cast<cpp_owner_t *>(malloc(size * sizeof(cpp_owner_t))), size)
231     {
232         std::uninitialized_move_n(begin, size, this->m_data);
233     }
234 
arraytaihe::array235     explicit array(size_type size) : array(reinterpret_cast<cpp_owner_t *>(malloc(size * sizeof(cpp_owner_t))), size)
236     {
237         std::uninitialized_default_construct_n(this->m_data, size);
238     }
239 
arraytaihe::array240     explicit array(size_type size, cpp_owner_t const &value)
241         : array(reinterpret_cast<cpp_owner_t *>(malloc(size * sizeof(cpp_owner_t))), size)
242     {
243         std::uninitialized_fill_n(this->m_data, size, value);
244     }
245 
maketaihe::array246     static array make(size_type size)
247     {
248         return array(size);
249     }
250 
maketaihe::array251     static array make(size_type size, cpp_owner_t const &value)
252     {
253         return array(size, value);
254     }
255 
arraytaihe::array256     array(std::initializer_list<cpp_owner_t> value) noexcept : array(copy_data, value.begin(), value.size()) {}
257 
arraytaihe::array258     array(array_view<cpp_owner_t> const &other) : array(copy_data, other.data(), other.size()) {}
259 
arraytaihe::array260     array(array<cpp_owner_t> const &other) : array(copy_data, other.data(), other.size()) {}
261 
arraytaihe::array262     array(array<cpp_owner_t> &&other) : array(std::exchange(other.m_data, nullptr), std::exchange(other.m_size, 0)) {}
263 
operator =taihe::array264     array &operator=(array other)
265     {
266         std::swap(this->m_size, other.m_size);
267         std::swap(this->m_data, other.m_data);
268         return *this;
269     }
270 
~arraytaihe::array271     ~array()
272     {
273         if (this->m_data) {
274             std::destroy_n(this->m_data, this->m_size);
275             free(this->m_data);
276             this->m_size = 0;
277             this->m_data = nullptr;
278         }
279     }
280 };
281 
282 template <typename cpp_owner_t>
283 struct as_abi<array_view<cpp_owner_t>> {
284     using type = TArray;
285 };
286 
287 template <typename cpp_owner_t>
288 struct as_abi<array<cpp_owner_t>> {
289     using type = TArray;
290 };
291 
292 template <typename cpp_owner_t>
293 struct as_param<array<cpp_owner_t>> {
294     using type = array_view<cpp_owner_t>;
295 };
296 }  // namespace taihe
297 
298 template <typename cpp_owner_t>
299 struct std::hash<taihe::array<cpp_owner_t>> {
operator ()std::hash300     std::size_t operator()(taihe::array_view<cpp_owner_t> val) const
301     {
302         std::size_t seed = 0;
303         static constexpr std::size_t GOLDEN_RATIO_CONSTANT = 0x9e3779b9;
304         static constexpr std::size_t LEFT_SHIFT_BITS = 6;
305         static constexpr std::size_t RIGHT_SHIFT_BITS = 2;
306         for (std::size_t i = 0; i < val.size(); i++) {
307             seed ^= (seed << LEFT_SHIFT_BITS) + (seed >> RIGHT_SHIFT_BITS) + GOLDEN_RATIO_CONSTANT +
308                     std::hash<cpp_owner_t>()(val[i]);
309         }
310         return seed;
311     }
312 };
313 // NOLINTEND
314 #endif  // RUNTIME_INCLUDE_TAIHE_ARRAY_HPP_