Skip to content

Commit fd9c4c4

Browse files
authored
Add convertation to span from other base types (#98)
1 parent 164aaf1 commit fd9c4c4

File tree

3 files changed

+163
-88
lines changed

3 files changed

+163
-88
lines changed

include/dsplib/array.h

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,30 @@ class base_array
2626
static_assert(support_type_for_array<T>(), "type is not supported");
2727

2828
public:
29-
base_array() = default;
29+
base_array() noexcept = default;
3030

3131
explicit base_array(int n)
3232
: _vec(n, 0) {
3333
}
3434

35-
base_array(const slice_t<T>& rhs)
36-
: base_array(rhs.size()) {
37-
this->slice(0, indexing::end) = rhs;
38-
}
39-
40-
base_array(const mut_slice_t<T>& rhs)
41-
: base_array(slice_t<T>(rhs)) {
42-
}
43-
4435
base_array(const std::vector<T>& v)
4536
: _vec(v) {
4637
}
4738

48-
template<typename T2>
39+
template<typename T2, std::enable_if_t<is_array_convertible<T2, T>(), bool> = true>
4940
base_array(const std::vector<T2>& v)
5041
: base_array(make_span(v)) {
5142
}
5243

53-
base_array(std::vector<T>&& v)
44+
base_array(std::vector<T>&& v) noexcept
5445
: _vec(std::move(v)) {
5546
}
5647

5748
base_array(const base_array<T>& v)
5849
: _vec(v._vec) {
5950
}
6051

61-
template<class T2>
52+
template<class T2, std::enable_if_t<is_array_convertible<T2, T>(), bool> = true>
6253
base_array(const base_array<T2>& v) {
6354
_vec.assign(v.begin(), v.end());
6455
}
@@ -71,18 +62,37 @@ class base_array
7162
: _vec(list) {
7263
}
7364

74-
template<typename T2>
75-
explicit base_array(const span_t<T2>& v) {
76-
static_assert(is_array_convertible<T2, T>(), "Only real2real/cmplx2cmplx array cast support");
65+
base_array(const span_t<T>& v)
66+
: _vec(v.data(), v.data() + v.size()) {
67+
}
68+
69+
base_array(const mut_span_t<T>& v)
70+
: _vec(v.data(), v.data() + v.size()) {
71+
}
72+
73+
base_array(const slice_t<T>& rhs)
74+
: base_array(rhs.size()) {
75+
this->slice(0, indexing::end) = rhs;
76+
}
77+
78+
base_array(const mut_slice_t<T>& rhs)
79+
: base_array(slice_t<T>(rhs)) {
80+
}
81+
82+
template<typename T2, std::enable_if_t<is_array_convertible<T2, T>(), bool> = true>
83+
base_array(const span_t<T2>& v) {
7784
_vec.assign(v.begin(), v.end());
7885
}
7986

80-
template<typename T2>
81-
explicit base_array(const mut_span_t<T2>& v) {
82-
static_assert(is_array_convertible<T2, T>(), "Only real2real/cmplx2cmplx array cast support");
87+
template<typename T2, std::enable_if_t<is_array_convertible<T2, T>(), bool> = true>
88+
base_array(const mut_span_t<T2>& v) {
8389
_vec.assign(v.begin(), v.end());
8490
}
8591

92+
explicit base_array(const T* ptr, size_t size)
93+
: base_array(make_span(ptr, size)) {
94+
}
95+
8696
//--------------------------------------------------------------------
8797
base_array<T>& operator=(const base_array<T>& rhs) {
8898
if (this == &rhs) {
@@ -101,27 +111,22 @@ class base_array
101111
}
102112

103113
//--------------------------------------------------------------------
104-
const T& operator[](int i) const noexcept {
105-
const int idx = (i >= 0) ? (i) : (_vec.size() + i);
106-
assert((idx >= 0) && (idx < int(_vec.size())));
107-
return _vec[idx];
108-
}
109-
110-
T& operator[](int i) noexcept {
111-
const int idx = (i >= 0) ? (i) : (_vec.size() + i);
112-
assert((idx >= 0) && (idx < int(_vec.size())));
113-
return _vec[idx];
114-
}
115-
116-
//--------------------------------------------------------------------
117-
const T& operator[](size_t i) const noexcept {
118-
assert(i < _vec.size());
119-
return _vec[i];
114+
template<typename Index, std::enable_if_t<std::is_integral_v<Index>, bool> = true>
115+
const T& operator[](Index i) const noexcept {
116+
const size_t n = _vec.size();
117+
if constexpr (std::is_signed_v<Index>) {
118+
const size_t idx = (i >= 0) ? static_cast<size_t>(i) : (n + i);
119+
DSPLIB_ASSUME(idx < n);
120+
return _vec[idx];
121+
} else {
122+
DSPLIB_ASSUME(i < n);
123+
return _vec[i];
124+
}
120125
}
121126

122-
T& operator[](size_t i) noexcept {
123-
assert(i < _vec.size());
124-
return _vec[i];
127+
template<typename Index, std::enable_if_t<std::is_integral_v<Index>, bool> = true>
128+
T& operator[](Index i) noexcept {
129+
return const_cast<T&>(static_cast<const base_array<T>&>(*this)[i]);
125130
}
126131

127132
//--------------------------------------------------------------------
@@ -300,7 +305,7 @@ class base_array
300305

301306
base_array<T> operator-() const noexcept {
302307
base_array<T> r{_vec};
303-
for (int i = 0; i < r.size(); ++i) {
308+
for (size_t i = 0; i < r.size(); ++i) {
304309
r[i] = -r[i];
305310
}
306311
return r;
@@ -353,8 +358,8 @@ class base_array
353358
return make_span(_vec) / rhs;
354359
}
355360

356-
//concatenate syntax (deprecated)
357-
//TODO: mark as deprecated?
361+
//concatenate syntax
362+
//TODO: mark as deprecated
358363
template<class T2, class R = ResultType<T, T2>>
359364
base_array<R>& operator|=(const base_array<T2>& rhs) {
360365
_vec.insert(_vec.end(), rhs.begin(), rhs.end());
@@ -440,7 +445,7 @@ auto operator/(const S& lhs, const base_array<T>& rhs) {
440445
static_assert(std::is_convertible_v<S, R>, "convertable type error");
441446
auto r = base_array<R>(rhs.size());
442447
const auto d = R(lhs);
443-
for (int i = 0; i < r.size(); ++i) {
448+
for (size_t i = 0; i < r.size(); ++i) {
444449
r[i] = d / rhs[i];
445450
}
446451
return r;

0 commit comments

Comments
 (0)