@@ -307,148 +307,54 @@ class base_array
307307 }
308308
309309 // --------------------------------------------------------------------
310- template <class T2 , class R = ResultType<T, T2>>
311- base_array<R>& operator +=(const T2& rhs) noexcept {
312- static_assert (is_scalar_v<T2>, " Type must be scalar" );
313- static_assert (std::is_same_v<T, R>, " The operation changes the type" );
314- for (auto & x : _vec) {
315- x += rhs;
316- }
317- return *this ;
318- }
319-
320- template <class T2 , class R = ResultType<T, T2>>
321- base_array<R>& operator -=(const T2& rhs) noexcept {
322- static_assert (is_scalar_v<T2>, " Type must be scalar" );
323- static_assert (std::is_same_v<T, R>, " The operation changes the type" );
324- for (auto & x : _vec) {
325- x -= rhs;
326- }
327- return *this ;
328- }
329-
330- template <class T2 , class R = ResultType<T, T2>>
331- base_array<R>& operator *=(const T2& rhs) noexcept {
332- static_assert (is_scalar_v<T2>, " Type must be scalar" );
333- static_assert (std::is_same_v<T, R>, " The operation changes the type" );
334- for (auto & x : _vec) {
335- x *= rhs;
336- }
337- return *this ;
338- }
339-
340- template <class T2 , class R = ResultType<T, T2>>
341- base_array<R>& operator /=(const T2& rhs) {
342- static_assert (is_scalar_v<T2>, " Type must be scalar" );
343- static_assert (std::is_same_v<T, R>, " The operation changes the type" );
344- for (auto & x : _vec) {
345- x /= rhs;
346- }
347- return *this ;
348- }
349-
350- // --------------------------------------------------------------------
351- template <class T2 , class R = ResultType<T, T2>>
352- base_array<R> operator +(const T2& rhs) const {
353- auto temp = array_cast<R>(*this );
354- // TODO: optimize, not optimal for arr_cmplx + real_t
355- temp += rhs;
356- return temp;
357- }
358-
359- template <class T2 , class R = ResultType<T, T2>>
360- base_array<R> operator -(const T2& rhs) const {
361- auto temp = array_cast<R>(*this );
362- temp -= rhs;
363- return temp;
364- }
365-
366- template <class T2 , class R = ResultType<T, T2>>
367- base_array<R> operator *(const T2& rhs) const {
368- auto temp = array_cast<R>(*this );
369- temp *= rhs;
370- return temp;
371- }
372-
373- template <class T2 , class R = ResultType<T, T2>>
374- base_array<R> operator /(const T2& rhs) const {
375- auto temp = array_cast<R>(*this );
376- temp /= rhs;
377- return temp;
378- }
379-
380- // --------------------------------------------------------------------
381- template <class T2 , class R = ResultType<T, T2>>
382- base_array<R>& operator +=(const base_array<T2>& rhs) {
383- static_assert (std::is_same_v<T, R>, " The operation changes the type" );
384- DSPLIB_ASSERT (this ->size () == rhs.size (), " array lengths must be equal" );
385- for (size_t i = 0 ; i < _vec.size (); ++i) {
386- _vec[i] += rhs[i];
387- }
310+ template <class T2 >
311+ base_array<T>& operator +=(const T2& rhs) noexcept {
312+ make_span (_vec) += rhs;
388313 return *this ;
389314 }
390315
391- template <class T2 , class R = ResultType<T, T2>>
392- base_array<R>& operator -=(const base_array<T2>& rhs) {
393- static_assert (std::is_same_v<T, R>, " The operation changes the type" );
394- DSPLIB_ASSERT (this ->size () == rhs.size (), " array lengths must be equal" );
395- for (size_t i = 0 ; i < _vec.size (); ++i) {
396- _vec[i] -= rhs[i];
397- }
316+ template <class T2 >
317+ base_array<T>& operator -=(const T2& rhs) noexcept {
318+ make_span (_vec) -= rhs;
398319 return *this ;
399320 }
400321
401- template <class T2 , class R = ResultType<T, T2>>
402- base_array<R>& operator *=(const base_array<T2>& rhs) {
403- static_assert (std::is_same_v<T, R>, " The operation changes the type" );
404- DSPLIB_ASSERT (this ->size () == rhs.size (), " array lengths must be equal" );
405- for (size_t i = 0 ; i < _vec.size (); ++i) {
406- _vec[i] *= rhs[i];
407- }
322+ template <class T2 >
323+ base_array<T>& operator *=(const T2& rhs) noexcept {
324+ make_span (_vec) *= rhs;
408325 return *this ;
409326 }
410327
411- template <class T2 , class R = ResultType<T, T2>>
412- base_array<R>& operator /=(const base_array<T2>& rhs) {
413- static_assert (std::is_same_v<T, R>, " The operation changes the type" );
414- DSPLIB_ASSERT (this ->size () == rhs.size (), " array lengths must be equal" );
415- for (size_t i = 0 ; i < _vec.size (); ++i) {
416- _vec[i] /= rhs[i];
417- }
328+ template <class T2 >
329+ base_array<T>& operator /=(const T2& rhs) {
330+ make_span (_vec) /= rhs;
418331 return *this ;
419332 }
420333
421334 // --------------------------------------------------------------------
422- template <class T2 , class R = ResultType<T, T2>>
423- base_array<R> operator +(const base_array<T2>& rhs) const {
424- auto temp = array_cast<R>(*this );
425- temp += rhs;
426- return temp;
335+ // TODO: add lvalue + rvalue, rvalue + lvalue
336+ template <class T2 >
337+ auto operator +(const T2& rhs) const {
338+ return make_span (_vec) + rhs;
427339 }
428340
429- template <class T2 , class R = ResultType<T, T2>>
430- base_array<R> operator -(const base_array<T2>& rhs) const {
431- auto temp = array_cast<R>(*this );
432- temp -= rhs;
433- return temp;
341+ template <class T2 >
342+ auto operator -(const T2& rhs) const {
343+ return make_span (_vec) - rhs;
434344 }
435345
436- template <class T2 , class R = ResultType<T, T2>>
437- base_array<R> operator *(const base_array<T2>& rhs) const {
438- auto temp = array_cast<R>(*this );
439- temp *= rhs;
440- return temp;
346+ template <class T2 >
347+ auto operator *(const T2& rhs) const {
348+ return make_span (_vec) * rhs;
441349 }
442350
443- template <class T2 , class R = ResultType<T, T2>>
444- base_array<R> operator /(const base_array<T2>& rhs) const {
445- auto temp = array_cast<R>(*this );
446- temp /= rhs;
447- return temp;
351+ template <class T2 >
352+ auto operator /(const T2& rhs) const {
353+ return make_span (_vec) / rhs;
448354 }
449355
450- // --------------------------------------------------------------------
451- // concatenate syntax
356+ // concatenate syntax (deprecated)
357+ // TODO: mark as deprecated?
452358 template <class T2 , class R = ResultType<T, T2>>
453359 base_array<R>& operator |=(const base_array<T2>& rhs) {
454360 _vec.insert (_vec.end (), rhs.begin (), rhs.end ());
@@ -507,34 +413,35 @@ class base_array
507413
508414// --------------------------------------------------------------------------------
509415// left oriented scalar * array
510- template <class T , class Scalar , class R = ResultType<T, Scalar>, class S_ = enable_scalar_t <Scalar>,
511- class C_ = enable_convertible_t <Scalar, R>>
512- inline base_array<R> operator +(const Scalar& lhs, const base_array<T>& rhs) {
513- return rhs + R (lhs);
416+ template <class T , class Scalar , class = enable_scalar_t <Scalar>>
417+ auto operator +(const Scalar& lhs, const base_array<T>& rhs) {
418+ using R = ResultType<T, Scalar>;
419+ static_assert (std::is_convertible_v<Scalar, R>, " convertable type error" );
420+ return rhs + lhs;
514421}
515422
516- template <class T , class Scalar , class R = ResultType<T, Scalar>, class S_ = enable_scalar_t <Scalar>,
517- class C_ = enable_convertible_t <Scalar, R>>
518- inline base_array<R> operator -(const Scalar& lhs, const base_array<T>& rhs) {
519- auto r = array_cast<R>(rhs);
520- for (int i = 0 ; i < r.size (); ++i) {
521- r[i] = R (lhs) - rhs[i];
522- }
523- return r;
423+ template <class T , class S , class = enable_scalar_t <S>>
424+ auto operator -(const S& lhs, const base_array<T>& rhs) {
425+ using R = ResultType<T, S>;
426+ static_assert (std::is_convertible_v<S, R>, " convertable type error" );
427+ return (-rhs) + lhs;
524428}
525429
526- template <class T , class Scalar , class R = ResultType<T, Scalar>, class S_ = enable_scalar_t <Scalar>,
527- class C_ = enable_convertible_t <Scalar, R>>
528- inline base_array<R> operator *(const Scalar& lhs, const base_array<T>& rhs) {
529- return rhs * R (lhs);
430+ template <class T , class S , class = enable_scalar_t <S>>
431+ auto operator *(const S& lhs, const base_array<T>& rhs) {
432+ using R = ResultType<T, S>;
433+ static_assert (std::is_convertible_v<S, R>, " convertable type error" );
434+ return rhs * lhs;
530435}
531436
532- template <class T , class Scalar , class R = ResultType<T, Scalar>, class S_ = enable_scalar_t <Scalar>,
533- class C_ = enable_convertible_t <Scalar, R>>
534- inline base_array<R> operator /(const Scalar& lhs, const base_array<T>& rhs) {
535- auto r = array_cast<R>(rhs);
437+ template <class T , class S , class = enable_scalar_t <S>>
438+ auto operator /(const S& lhs, const base_array<T>& rhs) {
439+ using R = ResultType<T, S>;
440+ static_assert (std::is_convertible_v<S, R>, " convertable type error" );
441+ auto r = base_array<R>(rhs.size ());
442+ const auto d = R (lhs);
536443 for (int i = 0 ; i < r.size (); ++i) {
537- r[i] = R (lhs) / rhs[i];
444+ r[i] = d / rhs[i];
538445 }
539446 return r;
540447}
0 commit comments