@@ -120,17 +120,17 @@ class mut_slice_t
120120 }
121121
122122 mut_slice_t & operator =(const slice_t <T>& rhs) {
123- this ->copy (* this , rhs);
123+ this ->assign ( rhs);
124124 return *this ;
125125 }
126126
127127 mut_slice_t & operator =(const mut_slice_t <T>& rhs) {
128- * this = slice_t <T>(rhs);
128+ this -> assign ( slice_t <T>(rhs) );
129129 return *this ;
130130 }
131131
132132 mut_slice_t & operator =(const base_array<T>& rhs) {
133- DSPLIB_ASSERT (!is_same_memory (rhs.slice (0 , rhs.size ()), * this ), " Assigned array to same slice" );
133+ DSPLIB_ASSERT (!is_same_memory (rhs.slice (0 , rhs.size ())), " Assigned array to same slice" );
134134 *this = rhs.slice (0 , rhs.size ());
135135 return *this ;
136136 }
@@ -165,19 +165,42 @@ class mut_slice_t
165165 return current;
166166 }
167167
168+ // TODO: replace to `copy` or `to_arr` function
168169 base_array<T> operator *() const noexcept {
169170 return base_array<T>(*this );
170171 }
171172
172- static bool is_same_memory (slice_t <T> r1, slice_t <T> r2) noexcept {
173- if (r1.empty () || r2.empty ()) {
174- return false ;
173+ void assign (slice_t <T> rhs) {
174+ DSPLIB_ASSERT (size () == rhs.size (), " Slices size must be equal" );
175+ const int count = size ();
176+
177+ // empty slice assign
178+ if (count == 0 ) {
179+ return ;
175180 }
176- auto start1 = r1.begin ();
177- auto end1 = r1.end ();
178- auto start2 = r2.begin ();
179- auto end2 = r2.end ();
180- return (start1 < end2) && (start2 < end1);
181+
182+ // simple block copy/move (optimization)
183+ const bool is_same = is_same_memory (rhs);
184+
185+ // check all slices is span
186+ if ((stride () == 1 ) && (rhs.stride () == 1 )) {
187+ const auto * src = rhs.data_ ;
188+ auto * dst = data_;
189+ if (!is_same) {
190+ std::memcpy (dst, src, count * sizeof (*src));
191+ } else {
192+ std::memmove (dst, src, count * sizeof (*src));
193+ }
194+ return ;
195+ }
196+
197+ // same array, specific indexing
198+ if (is_same) {
199+ *this = base_array<T>(rhs);
200+ return ;
201+ }
202+
203+ std::copy (rhs.begin (), rhs.end (), begin ());
181204 }
182205
183206 static mut_slice_t make_slice (T* data, int size, int i1, int i2, int step) {
@@ -202,38 +225,6 @@ class mut_slice_t
202225 return mut_slice_t (data + i1, step, count);
203226 }
204227
205- static void copy (mut_slice_t <T> lhs, slice_t <T> rhs) {
206- DSPLIB_ASSERT (lhs.size () == rhs.size (), " Slices size must be equal" );
207- const int count = lhs.size ();
208-
209- // empty slice assign
210- if (count == 0 ) {
211- return ;
212- }
213-
214- // simple block copy/move (optimization)
215- const bool is_same = is_same_memory (rhs, slice_t (lhs));
216- if ((lhs.stride () == 1 ) && (rhs.stride () == 1 )) {
217- const auto * src = &(*rhs.begin ());
218- auto * dst = &(*lhs.begin ());
219- if (!is_same) {
220- std::memcpy (dst, src, count * sizeof (*src));
221- } else {
222- // overlapped
223- std::memmove (dst, src, count * sizeof (*src));
224- }
225- return ;
226- }
227-
228- // same array, specific indexing
229- if (is_same) {
230- lhs = base_array<T>(rhs);
231- return ;
232- }
233-
234- std::copy (rhs.begin (), rhs.end (), lhs.begin ());
235- }
236-
237228protected:
238229 explicit mut_slice_t (T* data, int stride, int count)
239230 : data_{data}
@@ -242,6 +233,25 @@ class mut_slice_t
242233 DSPLIB_ASSERT (count >= 0 , " Count of elements must be positive" );
243234 }
244235
236+ bool is_same_memory (slice_t <T> rhs) noexcept {
237+ if (empty () || rhs.empty ()) {
238+ return false ;
239+ }
240+ auto start1 = rhs.data_ ;
241+ auto end1 = start1 + (rhs.count_ * rhs.stride_ );
242+ if (start1 > end1) {
243+ std::swap (start1, end1);
244+ }
245+
246+ auto start2 = data_;
247+ auto end2 = start2 + (count_ * stride_);
248+ if (start2 > end2) {
249+ std::swap (start2, end2);
250+ }
251+
252+ return (start1 < end2) && (start2 < end1);
253+ }
254+
245255 T* data_{nullptr };
246256 int stride_{0 };
247257 int count_{0 };
0 commit comments