Skip to content

Commit 1bd6d8c

Browse files
authored
Merge pull request #449 from serge-sans-paille/feature/load-complex
Support loading / storing complex numbers with empty imaginary part
2 parents 2267904 + 9e61471 commit 1bd6d8c

File tree

2 files changed

+64
-13
lines changed

2 files changed

+64
-13
lines changed

include/xsimd/types/xsimd_complex_base.hpp

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <cstddef>
1616
#include <limits>
1717
#include <ostream>
18+
#include <cassert>
1819

1920
#ifdef XSIMD_ENABLE_XTL_COMPLEX
2021
#include "xtl/xcomplex.hpp"
@@ -199,9 +200,18 @@ namespace xsimd
199200
load_unaligned(const T* src);
200201

201202
template <class T>
202-
void store_aligned(T* dst) const;
203+
inline typename std::enable_if<detail::is_complex<T>::value, void>::type
204+
store_aligned(T* dst) const;
203205
template <class T>
204-
void store_unaligned(T* dst) const;
206+
inline typename std::enable_if<detail::is_complex<T>::value, void>::type
207+
store_unaligned(T* dst) const;
208+
209+
template <class T>
210+
inline typename std::enable_if<!detail::is_complex<T>::value, void>::type
211+
store_aligned(T* dst) const;
212+
template <class T>
213+
inline typename std::enable_if<!detail::is_complex<T>::value, void>::type
214+
store_unaligned(T* dst) const;
205215

206216
value_type operator[](std::size_t index) const;
207217

@@ -824,12 +834,13 @@ namespace xsimd
824834
/// @endcond
825835

826836
/**
827-
* Stores the N values of the batch into a contiguous array
837+
* Stores the N values of the batch into a contiguous array of complex
828838
* pointed by \c dst. \c dst must be aligned.
829839
*/
830840
template <class X>
831841
template <class T>
832-
inline void simd_complex_batch<X>::store_aligned(T* dst) const
842+
inline typename std::enable_if<detail::is_complex<T>::value, void>::type
843+
simd_complex_batch<X>::store_aligned(T* dst) const
833844
{
834845
real_batch hi = (*this)().get_complex_high();
835846
real_batch lo = (*this)().get_complex_low();
@@ -840,12 +851,26 @@ namespace xsimd
840851
}
841852

842853
/**
843-
* Stores the N values of the batch into a contiguous array
854+
* Stores the N values of the batch into a contiguous array of reals
855+
* pointed by \c dst. \c dst must be aligned.
856+
*/
857+
template <class X>
858+
template <class T>
859+
inline typename std::enable_if<!detail::is_complex<T>::value, void>::type
860+
simd_complex_batch<X>::store_aligned(T* dst) const
861+
{
862+
m_real.store_aligned(dst);
863+
assert(all(m_imag == 0) && "no imaginary part");
864+
}
865+
866+
/**
867+
* Stores the N values of the batch into a contiguous array of complex
844868
* pointed by \c dst. \c dst is not required to be aligned.
845869
*/
846870
template <class X>
847871
template <class T>
848-
inline void simd_complex_batch<X>::store_unaligned(T* dst) const
872+
inline typename std::enable_if<detail::is_complex<T>::value, void>::type
873+
simd_complex_batch<X>::store_unaligned(T* dst) const
849874
{
850875
real_batch hi = (*this)().get_complex_high();
851876
real_batch lo = (*this)().get_complex_low();
@@ -854,6 +879,20 @@ namespace xsimd
854879
hi.store_unaligned(rbuf);
855880
lo.store_unaligned(rbuf + size);
856881
}
882+
883+
/**
884+
* Stores the N values of the batch into a contiguous array of reals
885+
* pointed by \c dst. \c dst is not required to be aligned.
886+
*/
887+
template <class X>
888+
template <class T>
889+
inline typename std::enable_if<!detail::is_complex<T>::value, void>::type
890+
simd_complex_batch<X>::store_unaligned(T* dst) const
891+
{
892+
m_real.store_aligned(dst);
893+
assert(all(m_imag == 0) && "no imaginary part");
894+
}
895+
857896
//@}
858897

859898
template <class X>

test/test_batch_complex.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,6 @@ class batch_complex_test : public testing::Test
7474
b.store_unaligned(res_real.data(), res_imag.data());
7575
EXPECT_EQ(res_real, real) << print_function_name("load_unaligned / store_unaligned (real*, real*)");
7676

77-
//b.load_unaligned(real.data());
78-
//b.store_unaligned(res_real.data());
79-
//EXPECT_EQ(res_real, real) << print_function_name("load_unaligned / store_unaligned (real*)");
80-
8177
alignas(XSIMD_DEFAULT_ALIGNMENT) real_array_type areal, aimag, ares_real, ares_imag;
8278
for (size_t i = 0; i < size; ++i)
8379
{
@@ -87,10 +83,26 @@ class batch_complex_test : public testing::Test
8783
b.load_aligned(areal.data(), aimag.data());
8884
b.store_aligned(ares_real.data(), ares_imag.data());
8985
EXPECT_EQ(ares_real, areal) << print_function_name("load_aligned / store_aligned (real*, real*)");
86+
}
87+
{
88+
real_array_type real, res_real;
89+
for (size_t i = 0; i < size; ++i)
90+
{
91+
real[i] = lhs[i].real();
92+
}
93+
batch_type b;
94+
b.load_unaligned(real.data());
95+
b.store_unaligned(res_real.data());
96+
EXPECT_EQ(res_real, real) << print_function_name("load_unaligned / store_unaligned (real*)");
9097

91-
//b.load_aligned(areal.data());
92-
//b.store_aligned(ares_real.data());
93-
//EXPECT_EQ(ares_real, areal) << print_function_name("load_aligned / store_aligned (real*)");
98+
alignas(XSIMD_DEFAULT_ALIGNMENT) real_array_type areal, ares_real;
99+
for (size_t i = 0; i < size; ++i)
100+
{
101+
areal[i] = lhs[i].real();
102+
}
103+
b.load_aligned(areal.data());
104+
b.store_aligned(ares_real.data());
105+
EXPECT_EQ(ares_real, areal) << print_function_name("load_aligned / store_aligned (real*)");
94106
}
95107
}
96108

0 commit comments

Comments
 (0)