29 static_assert(!std::is_same_v<std::remove_cv_t<T>,
bool>,
"`bool` type is not supported");
30 static_assert(std::is_trivially_copyable<T>(),
"type must be trivially copyable");
43 template<typename U = T, std::enable_if_t<support_type_for_array<U>(),
bool> =
true>
52 [[nodiscard]] T* data()
noexcept {
56 [[nodiscard]]
const T* data()
const noexcept {
60 [[nodiscard]]
int size()
const noexcept {
64 T& operator[](
size_t i)
noexcept {
66 return this->data_[i];
79 template<
typename T2, std::enable_if_t<std::is_convertible_v<T2, T>,
bool> = true,
80 std::enable_if_t<is_scalar_v<T2>,
bool> = true>
93 template<
typename T2, std::enable_if_t<std::is_convertible_v<T2, T>,
bool> = true,
94 std::enable_if_t<is_scalar_v<T2>,
bool> = true>
101 template<typename T2, std::enable_if_t<support_type_for_array<T2>(),
bool> =
true>
103 this->assign(make_span(rhs));
108 std::fill(this->data_, (this->data_ + this->count_), rhs);
112 template<
typename T2, std::enable_if_t<std::is_convertible_v<T2, T>,
bool> = true,
113 std::enable_if_t<is_scalar_v<T2>,
bool> = true>
115 std::fill(this->data_, (this->data_ + this->count_), rhs);
130 mut_span_t& operator=(
const std::initializer_list<T>& rhs) {
136 using const_iterator =
const T*;
138 iterator begin()
noexcept {
142 iterator end()
noexcept {
143 return this->data_ + this->count_;
146 const_iterator begin()
const noexcept {
150 const_iterator end()
const noexcept {
151 return this->data_ + this->count_;
155 DSPLIB_ASSERT(this->size() == rhs.size(),
"span size is not equal");
156 if (!is_same_memory(rhs)) {
157 std::memcpy(this->data(), rhs.data(), size() *
sizeof(T));
159 std::memmove(this->data(), rhs.data(), size() *
sizeof(T));
163 template<
typename T2, std::enable_if_t<std::is_convertible_v<T2, T>,
bool> = true>
165 DSPLIB_ASSERT(this->size() == rhs.size(),
"span size is not equal");
167 const size_t n = size();
168 for (
size_t i = 0; i < n; ++i) {
175 DSPLIB_ASSERT((i1 >= 0) && (i1 < this->count_),
"invalid range");
176 DSPLIB_ASSERT((i2 > i1) && (i2 <= this->count_),
"invalid range");
177 return mut_span_t(this->data_ + i1, (i2 - i1));
182 template<
typename U = T,
class T2, std::enable_if_t<is_scalar_v<U>,
bool> = true>
183 mut_span_t& operator+=(
const T2& rhs)
noexcept(is_scalar_v<T2>) {
185 const size_t n = size();
186 using R = ResultType<T, T2>;
187 static_assert(std::is_same_v<T, R>,
"The operation changes the type");
188 if constexpr (is_scalar_v<T2>) {
189 for (
size_t i = 0; i < n; ++i) {
193 DSPLIB_ASSERT(n == rhs.size(),
"Array lengths must be equal");
194 for (
size_t i = 0; i < n; ++i) {
201 template<
typename U = T,
class T2, std::enable_if_t<is_scalar_v<U>,
bool> = true>
202 mut_span_t& operator-=(
const T2& rhs)
noexcept(is_scalar_v<T2>) {
204 const size_t n = size();
205 using R = ResultType<T, T2>;
206 static_assert(std::is_same_v<T, R>,
"The operation changes the type");
207 if constexpr (is_scalar_v<T2>) {
208 for (
size_t i = 0; i < n; ++i) {
212 DSPLIB_ASSERT(n == rhs.size(),
"Array lengths must be equal");
213 for (
size_t i = 0; i < n; ++i) {
220 template<
typename U = T,
class T2, std::enable_if_t<is_scalar_v<U>,
bool> = true>
221 mut_span_t& operator*=(
const T2& rhs)
noexcept(is_scalar_v<T2>) {
223 const size_t n = size();
224 using R = ResultType<T, T2>;
225 static_assert(std::is_same_v<T, R>,
"The operation changes the type");
226 if constexpr (is_scalar_v<T2>) {
227 for (
size_t i = 0; i < n; ++i) {
231 DSPLIB_ASSERT(n == rhs.size(),
"Array lengths must be equal");
232 for (
size_t i = 0; i < n; ++i) {
239 template<
typename U = T,
class T2, std::enable_if_t<is_scalar_v<U>,
bool> = true>
240 mut_span_t& operator/=(
const T2& rhs)
noexcept(is_scalar_v<T2>) {
242 const size_t n = size();
243 using R = ResultType<T, T2>;
244 static_assert(std::is_same_v<T, R>,
"The operation changes the type");
245 if constexpr (is_scalar_v<T2>) {
246 for (
size_t i = 0; i < n; ++i) {
250 DSPLIB_ASSERT(n == rhs.size(),
"Array lengths must be equal");
251 for (
size_t i = 0; i < n; ++i) {
260 auto operator+(
const T2& rhs)
const {
265 auto operator-(
const T2& rhs)
const {
270 auto operator*(
const T2& rhs)
const {
275 auto operator/(
const T2& rhs)
const {
280 bool is_same_memory(
span_t<T> rhs)
noexcept {
281 if (this->size() == 0 || rhs.size() == 0) {
284 auto start1 = this->data();
285 auto end1 = start1 + this->size();
286 auto start2 = rhs.data();
287 auto end2 = start2 + rhs.size();
288 return (start1 < end2) && (start2 < end1);
297 static_assert(!std::is_same_v<std::remove_cv_t<T>,
bool>,
"`bool` type is not supported");
298 static_assert(std::is_trivially_copyable<T>(),
"type must be trivially copyable");
304 explicit span_t(
const T* data,
int size)
309 :
span_t(v.data(), v.size()) {
312 template<typename U = T, std::enable_if_t<support_type_for_array<U>(),
bool> =
true>
314 :
span_t(v.data(), v.size()) {
317 span_t(
const std::vector<T>& v)
318 :
span_t(v.data(), v.size()) {
321 [[nodiscard]]
const T* data()
const noexcept {
325 [[nodiscard]]
int size()
const noexcept {
329 const T& operator[](
size_t i)
const noexcept {
331 return this->data_[i];
334 using const_iterator =
const T*;
336 const_iterator begin()
const noexcept {
340 const_iterator end()
const noexcept {
341 return this->data_ + this->count_;
344 span_t slice(
int i1,
int i2)
const {
345 DSPLIB_ASSERT((i1 >= 0) && (i1 < this->count_),
"invalid range");
346 DSPLIB_ASSERT((i2 > i1) && (i2 <= this->count_),
"invalid range");
347 return span_t(this->data_ + i1, (i2 - i1));
353 auto operator+(
const T2& rhs)
const {
355 const size_t n = size();
356 using R = ResultType<T, T2>;
358 if constexpr (is_scalar_v<T2>) {
359 for (
size_t i = 0; i < n; ++i) {
363 DSPLIB_ASSERT(n == rhs.size(),
"Array lengths must be equal");
364 for (
size_t i = 0; i < n; ++i) {
365 res[i] = x[i] + rhs[i];
372 auto operator-(
const T2& rhs)
const {
374 const size_t n = size();
375 using R = ResultType<T, T2>;
377 if constexpr (is_scalar_v<T2>) {
378 for (
size_t i = 0; i < n; ++i) {
382 DSPLIB_ASSERT(n == rhs.size(),
"Array lengths must be equal");
383 for (
size_t i = 0; i < n; ++i) {
384 res[i] = x[i] - rhs[i];
391 auto operator*(
const T2& rhs)
const {
393 const size_t n = size();
394 using R = ResultType<T, T2>;
396 if constexpr (is_scalar_v<T2>) {
397 for (
size_t i = 0; i < n; ++i) {
401 DSPLIB_ASSERT(n == rhs.size(),
"Array lengths must be equal");
402 for (
size_t i = 0; i < n; ++i) {
403 res[i] = x[i] * rhs[i];
410 auto operator/(
const T2& rhs)
const {
412 const size_t n = size();
413 using R = ResultType<T, T2>;
415 if constexpr (is_scalar_v<T2>) {
416 for (
size_t i = 0; i < n; ++i) {
420 DSPLIB_ASSERT(n == rhs.size(),
"Array lengths must be equal");
421 for (
size_t i = 0; i < n; ++i) {
422 res[i] = x[i] / rhs[i];