Skip to content

Commit 2d270b2

Browse files
authored
Merge pull request #545 from JohanMabille/traits
Fixed simd_traits implementation
2 parents 311d305 + e87d936 commit 2d270b2

File tree

3 files changed

+63
-23
lines changed

3 files changed

+63
-23
lines changed

include/xsimd/types/xsimd_register.hpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef XSIMD_REGISTER_HPP
22
#define XSIMD_REGISTER_HPP
33

4+
#include <type_traits>
5+
46
namespace xsimd
57
{
68

@@ -16,14 +18,22 @@ namespace xsimd
1618
template<class T, class Arch>
1719
struct simd_register;
1820

21+
template <class T, class A>
22+
struct has_simd_register : std::false_type
23+
{
24+
};
25+
1926
#define XSIMD_DECLARE_SIMD_REGISTER(SCALAR_TYPE, ISA, VECTOR_TYPE) \
2027
template<> \
2128
struct simd_register<SCALAR_TYPE, ISA>\
2229
{\
2330
using register_type = VECTOR_TYPE;\
2431
register_type data;\
2532
operator register_type() const { return data; }\
26-
}
33+
};\
34+
template <>\
35+
struct has_simd_register<SCALAR_TYPE, ISA> : std::true_type\
36+
{}
2737

2838
#define XSIMD_DECLARE_SIMD_REGISTER_ALIAS(ISA, ISA_BASE)\
2939
template<class T> \
@@ -32,7 +42,10 @@ namespace xsimd
3242
using register_type = typename simd_register<T, ISA_BASE>::register_type;\
3343
simd_register(register_type reg) : simd_register<T, ISA_BASE>{reg} {}\
3444
simd_register() = default;\
35-
}
45+
};\
46+
template<class T>\
47+
struct has_simd_register<T, ISA> : has_simd_register<T, ISA_BASE>\
48+
{}
3649

3750
template <class T, class Arch>
3851
struct get_bool_simd_register

include/xsimd/types/xsimd_traits.hpp

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,50 +17,72 @@
1717

1818
namespace xsimd
1919
{
20+
21+
/**************************************
22+
* simd_traits and revert_simd_traits *
23+
**************************************/
24+
25+
template <class T, class A = default_arch>
26+
struct has_simd_register : types::has_simd_register<T, A>
27+
{
28+
};
29+
2030
namespace detail
2131
{
22-
template <class T, class = void>
23-
struct has_batch : std::false_type
32+
template <class T, bool>
33+
struct simd_traits_impl;
34+
35+
template <class T>
36+
struct simd_traits_impl<T, false>
2437
{
38+
using type = T;
39+
using bool_type = bool;
40+
static constexpr size_t size = 1;
2541
};
2642

2743
template <class T>
28-
struct has_batch<T, check_size_t<sizeof(batch<T>)>> : std::true_type
44+
constexpr size_t simd_traits_impl<T, false>::size;
45+
46+
template <class T>
47+
struct simd_traits_impl<T, true>
2948
{
49+
using type = batch<T>;
50+
using bool_type = typename type::batch_bool_type;
51+
static constexpr size_t size = type::size;
3052
};
53+
54+
template <class T>
55+
constexpr size_t simd_traits_impl<T, true>::size;
3156
}
3257

33-
template <class T, bool = detail::has_batch<T>::value>
34-
struct simd_traits
58+
template <class T>
59+
struct simd_traits : detail::simd_traits_impl<T, has_simd_register<T>::value>
3560
{
36-
using type = T;
37-
using bool_type = bool;
38-
static constexpr size_t size = 1;
3961
};
4062

41-
template <class T, bool B>
42-
constexpr size_t simd_traits<T, B>::size;
43-
4463
template <class T>
45-
struct revert_simd_traits
64+
struct simd_traits<std::complex<T>>
65+
: detail::simd_traits_impl<std::complex<T>, has_simd_register<T>::value>
4666
{
47-
using type = T;
48-
static constexpr size_t size = simd_traits<type>::size;
4967
};
5068

51-
template <class T>
52-
constexpr size_t revert_simd_traits<T>::size;
69+
#ifdef XSIMD_ENABLE_XTL_COMPLEX
70+
template <class T, bool i3ec>
71+
struct simd_traits<xtl::xcomplex<T, T, i3ec>>
72+
: detail::simd_traits_impl<std::complex<T>, has_simd_register<T>::value>
73+
{
74+
};
75+
#endif
5376

5477
template <class T>
55-
struct simd_traits<T, true>
78+
struct revert_simd_traits
5679
{
57-
using type = batch<T>;
58-
using bool_type = typename type::batch_bool_type;
59-
static constexpr size_t size = type::size;
80+
using type = T;
81+
static constexpr size_t size = simd_traits<type>::size;
6082
};
6183

6284
template <class T>
63-
constexpr size_t simd_traits<T, true>::size;
85+
constexpr size_t revert_simd_traits<T>::size;
6486

6587
template <class T>
6688
struct revert_simd_traits<batch<T>>

test/test_traits.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ class traits_test : public testing::Test
2727
using batch_bool_type = xsimd::batch_bool<value_type>;
2828
constexpr bool same_bool_type = std::is_same<batch_bool_type, typename traits_type::bool_type>::value;
2929
EXPECT_TRUE(same_bool_type);
30+
31+
using vector_traits_type = xsimd::simd_traits<std::vector<value_type>>;
32+
EXPECT_EQ(vector_traits_type::size, 1);
33+
constexpr bool vec_same_type = std::is_same<typename vector_traits_type::type, std::vector<value_type>>::value;
34+
EXPECT_TRUE(vec_same_type);
3035
}
3136

3237
void test_revert_simd_traits()

0 commit comments

Comments
 (0)