Skip to content

Commit 5dd3ff0

Browse files
committed
Factor integer traits
1 parent 924ef86 commit 5dd3ff0

File tree

13 files changed

+174
-238
lines changed

13 files changed

+174
-238
lines changed

docs/Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ INPUT = ../include/xsimd/types/xsimd_api.hpp \
88
../include/xsimd/memory/xsimd_alignment.hpp \
99
../include/xsimd/memory/xsimd_aligned_allocator.hpp \
1010
../include/xsimd/types/xsimd_common_arch.hpp \
11-
../include/xsimd/types/xsimd_traits.hpp \
11+
../include/xsimd/types/simd_traits.hpp \
1212
../include/xsimd/types/xsimd_vsx_register.hpp \
1313
../include/xsimd/types/xsimd_avx2_register.hpp \
1414
../include/xsimd/types/xsimd_avx512bw_register.hpp \

include/xsimd/arch/common/xsimd_common_cast.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
#ifndef XSIMD_COMMON_CAST_HPP
1313
#define XSIMD_COMMON_CAST_HPP
1414

15-
#include "../../types/xsimd_traits.hpp"
15+
#include <array>
16+
17+
#include "../../config/xsimd_macros.hpp"
18+
#include "../../type_traits.hpp"
1619

1720
namespace xsimd
1821
{

include/xsimd/arch/utils/shifts.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "../../config/xsimd_macros.hpp"
1717
#include "../../types/xsimd_batch.hpp"
1818
#include "../../types/xsimd_batch_constant.hpp"
19-
#include "../../types/xsimd_traits.hpp"
19+
#include "../../types/simd_traits.hpp"
2020

2121
namespace xsimd
2222
{

include/xsimd/arch/xsimd_neon.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <tuple>
2020
#include <type_traits>
2121

22+
#include "../type_traits.hpp"
2223
#include "../types/xsimd_neon_register.hpp"
2324
#include "../types/xsimd_utils.hpp"
2425
#include "./common/xsimd_common_bit.hpp"

include/xsimd/arch/xsimd_rvv.hpp

Lines changed: 6 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <type_traits>
1515

1616
#include "../config/xsimd_macros.hpp"
17+
#include "../type_traits.hpp"
1718
#include "../types/xsimd_batch_constant.hpp"
1819
#include "../types/xsimd_rvv_register.hpp"
1920
#include "./xsimd_constants.hpp"
@@ -95,8 +96,8 @@
9596
static constexpr size_t width = XSIMD_RVV_BITS; \
9697
static constexpr size_t vl = width / (sizeof(T) * 8); \
9798
using vec = rvv_reg_t<T, width>; \
98-
using uvec = rvv_reg_t<as_unsigned_relaxed_t<T>, width>; \
99-
using svec = rvv_reg_t<as_signed_relaxed_t<T>, width>; \
99+
using uvec = rvv_reg_t<xsimd::sized_uint_t<T>, width>; \
100+
using svec = rvv_reg_t<xsimd::sized_int_t<T>, width>; \
100101
using fvec = rvv_reg_t<as_float_relaxed_t<T>, width>; \
101102
using bvec = rvv_bool_t<T, width>; \
102103
using scalar_vec = rvv_reg_t<T, types::detail::rvv_width_m1>; \
@@ -294,57 +295,12 @@ namespace xsimd
294295
template <class T, size_t Width = XSIMD_RVV_BITS>
295296
using rvv_bool_t = types::detail::rvv_bool_t<T, Width>;
296297

297-
template <size_t>
298-
struct as_signed_relaxed;
299-
template <>
300-
struct as_signed_relaxed<1>
301-
{
302-
using type = int8_t;
303-
};
304-
template <>
305-
struct as_signed_relaxed<2>
306-
{
307-
using type = int16_t;
308-
};
309-
template <>
310-
struct as_signed_relaxed<4>
311-
{
312-
using type = int32_t;
313-
};
314-
template <>
315-
struct as_signed_relaxed<8>
316-
{
317-
using type = int64_t;
318-
};
319-
template <class T>
320-
using as_signed_relaxed_t = typename as_signed_relaxed<sizeof(T)>::type;
321-
template <size_t>
322-
struct as_unsigned_relaxed;
323-
template <>
324-
struct as_unsigned_relaxed<1>
298+
template <std::size_t S>
299+
struct as_float_relaxed
325300
{
326-
using type = uint8_t;
301+
using type = xsimd::sized_fp_t<S>;
327302
};
328303
template <>
329-
struct as_unsigned_relaxed<2>
330-
{
331-
using type = uint16_t;
332-
};
333-
template <>
334-
struct as_unsigned_relaxed<4>
335-
{
336-
using type = uint32_t;
337-
};
338-
template <>
339-
struct as_unsigned_relaxed<8>
340-
{
341-
using type = uint64_t;
342-
};
343-
template <class T>
344-
using as_unsigned_relaxed_t = typename as_unsigned_relaxed<sizeof(T)>::type;
345-
template <size_t>
346-
struct as_float_relaxed;
347-
template <>
348304
struct as_float_relaxed<1>
349305
{
350306
using type = int8_t;
@@ -354,16 +310,6 @@ namespace xsimd
354310
{
355311
using type = int16_t;
356312
};
357-
template <>
358-
struct as_float_relaxed<4>
359-
{
360-
using type = float;
361-
};
362-
template <>
363-
struct as_float_relaxed<8>
364-
{
365-
using type = double;
366-
};
367313
template <class T>
368314
using as_float_relaxed_t = typename as_float_relaxed<sizeof(T)>::type;
369315

include/xsimd/arch/xsimd_sve.hpp

Lines changed: 22 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <type_traits>
1818

1919
#include "../config/xsimd_macros.hpp"
20+
#include "../type_traits.hpp"
2021
#include "../types/xsimd_sve_register.hpp"
2122

2223
// Define a inline namespace with the explicit SVE vector size to avoid ODR violation
@@ -88,103 +89,36 @@ namespace xsimd
8889
template <class T>
8990
using sve_enable_all_t = std::enable_if_t<std::is_arithmetic<T>::value, int>;
9091

91-
// Trait describing the SVE types that correspond to a scalar,
92-
// parameterised by (byte size, signedness, floating-point-ness).
93-
//
94-
// `scalar` is the matching fixed-width scalar (int8_t, ..., float,
95-
// double). SVE load/store intrinsics are overloaded on these
96-
// pointer types, so remapping integers through `scalar` avoids
97-
// platform quirks such as darwin arm64's `long` vs `long long`
98-
// distinction and rejects `char` as an element type.
99-
//
100-
// `sizeless` is the matching sizeless SVE type. xsimd stores SVE
101-
// vectors as fixed-size attributed types (arm_sve_vector_bits),
102-
// which clang treats as implicitly convertible to every sizeless
103-
// SVE type — including multi-vector tuples — making the overloaded
104-
// svreinterpret_*/svsel/etc. intrinsics ambiguous. Static-casting
105-
// to `sizeless` first collapses the overload set to the single
92+
// Sizeless SVE type for T.
93+
// xsimd stores SVE vectors as fixed-size attributed types (arm_sve_vector_bits),
94+
// which clang treats as implicitly convertible to every sizeless SVE
95+
// type — including multi-vector tuples — making the overloaded
96+
// svreinterpret_*/svsel/etc. // intrinsics ambiguous.
97+
// Static-casting to `sizeless` first collapses the overload set to the single
10698
// 1-vector candidate.
107-
template <size_t N, bool Signed, bool FP>
108-
struct sve_type;
109-
template <>
110-
struct sve_type<1, true, false>
111-
{
112-
using scalar = int8_t;
113-
using sizeless = svint8_t;
114-
};
115-
template <>
116-
struct sve_type<1, false, false>
117-
{
118-
using scalar = uint8_t;
119-
using sizeless = svuint8_t;
120-
};
121-
template <>
122-
struct sve_type<2, true, false>
123-
{
124-
using scalar = int16_t;
125-
using sizeless = svint16_t;
126-
};
127-
template <>
128-
struct sve_type<2, false, false>
129-
{
130-
using scalar = uint16_t;
131-
using sizeless = svuint16_t;
132-
};
133-
template <>
134-
struct sve_type<4, true, false>
135-
{
136-
using scalar = int32_t;
137-
using sizeless = svint32_t;
138-
};
139-
template <>
140-
struct sve_type<4, false, false>
141-
{
142-
using scalar = uint32_t;
143-
using sizeless = svuint32_t;
144-
};
145-
template <>
146-
struct sve_type<8, true, false>
147-
{
148-
using scalar = int64_t;
149-
using sizeless = svint64_t;
150-
};
151-
template <>
152-
struct sve_type<8, false, false>
153-
{
154-
using scalar = uint64_t;
155-
using sizeless = svuint64_t;
156-
};
157-
template <>
158-
struct sve_type<4, true, true>
159-
{
160-
using scalar = float;
161-
using sizeless = svfloat32_t;
162-
};
163-
template <>
164-
struct sve_type<8, true, true>
165-
{
166-
using scalar = double;
167-
using sizeless = svfloat64_t;
168-
};
169-
17099
template <class T>
171-
using sve_type_for = sve_type<sizeof(T), std::is_signed<T>::value, std::is_floating_point<T>::value>;
100+
using sve_sizeless_t = xsimd::types::detail::sve_vector_type<T>;
172101

173-
template <class T>
174-
using sve_sizeless_t = typename sve_type_for<T>::sizeless;
175-
176-
// Remap integer Ts to their matching fixed-width counterpart (via
177-
// sve_type::scalar) so svld1/svst1 see the pointer type their
178-
// overload set expects; pass non-integer Ts through unchanged.
179-
template <class T, bool IsInt = std::is_integral<std::decay_t<T>>::value>
102+
// Remap integer Ts to their matching fixed-width counterpart so
103+
// svld1/svst1 see the pointer type their overload set expects;
104+
// pass non-integer Ts through unchanged. Uses sized_int_t /
105+
// sized_uint_t / sized_fp_t which already enumerate scalar types.
106+
template <class T, int = 0>
180107
struct sve_fix_integer_impl
181108
{
182109
using type = T;
183110
};
111+
112+
template <class T>
113+
struct sve_fix_integer_impl<T, sve_enable_signed_int_t<std::decay_t<T>> {}>
114+
{
115+
using type = xsimd::sized_int_t<sizeof(std::decay_t<T>)>;
116+
};
117+
184118
template <class T>
185-
struct sve_fix_integer_impl<T, true>
119+
struct sve_fix_integer_impl<T, sve_enable_unsigned_int_t<std::decay_t<T>> {}>
186120
{
187-
using type = typename sve_type_for<std::decay_t<T>>::scalar;
121+
using type = xsimd::sized_uint_t<sizeof(std::decay_t<T>)>;
188122
};
189123

190124
template <class T>

include/xsimd/type_traits.hpp

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/***************************************************************************
2+
* Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
3+
* Martin Renou *
4+
* Copyright (c) QuantStack *
5+
* Copyright (c) Serge Guelton *
6+
* *
7+
* Distributed under the terms of the BSD 3-Clause License. *
8+
* *
9+
* The full license is in the file LICENSE, distributed with this software. *
10+
****************************************************************************/
11+
12+
#ifndef XSIMD_TYPE_TRAITS_HPP
13+
#define XSIMD_TYPE_TRAITS_HPP
14+
15+
#include <cstddef>
16+
#include <cstdint>
17+
#include <type_traits>
18+
19+
namespace xsimd
20+
{
21+
namespace detail
22+
{
23+
template <std::size_t S>
24+
struct sized_num_types;
25+
26+
template <>
27+
struct sized_num_types<1>
28+
{
29+
using signed_type = std::int8_t;
30+
using unsigned_type = std::uint8_t;
31+
using floating_point_type = void;
32+
};
33+
34+
template <>
35+
struct sized_num_types<2>
36+
{
37+
using signed_type = std::int16_t;
38+
using unsigned_type = std::uint16_t;
39+
using floating_point_type = void;
40+
};
41+
42+
template <>
43+
struct sized_num_types<4>
44+
{
45+
using signed_type = std::int32_t;
46+
using unsigned_type = std::uint32_t;
47+
using floating_point_type = float;
48+
};
49+
50+
template <>
51+
struct sized_num_types<8>
52+
{
53+
using signed_type = std::int64_t;
54+
using unsigned_type = std::uint64_t;
55+
using floating_point_type = double;
56+
};
57+
}
58+
59+
/**
60+
* @ingroup batch_traits
61+
*
62+
* Signed integer type with exactly @c S bytes (1, 2, 4, or 8).
63+
*
64+
* @tparam S size in bytes.
65+
*/
66+
template <std::size_t S>
67+
using sized_int_t = typename detail::sized_num_types<S>::signed_type;
68+
69+
/**
70+
* @ingroup batch_traits
71+
*
72+
* Unsigned integer type with exactly @c S bytes (1, 2, 4, or 8).
73+
*
74+
* @tparam S size in bytes.
75+
*/
76+
template <std::size_t S>
77+
using sized_uint_t = typename detail::sized_num_types<S>::unsigned_type;
78+
79+
/**
80+
* @ingroup batch_traits
81+
*
82+
* Floating-point type with exactly @c S bytes (4 for @c float, 8 for @c double).
83+
* Yields @c void for sizes without a standard floating-point type (1, 2).
84+
*
85+
* @tparam S size in bytes.
86+
*/
87+
template <std::size_t S>
88+
using sized_fp_t = typename detail::sized_num_types<S>::floating_point_type;
89+
90+
namespace detail
91+
{
92+
template <typename T, typename = void>
93+
struct widen;
94+
95+
template <typename T>
96+
struct widen<T, std::enable_if_t<std::is_floating_point<T>::value>>
97+
{
98+
using type = xsimd::sized_fp_t<sizeof(T) * 2>;
99+
};
100+
101+
template <typename T>
102+
struct widen<T, std::enable_if_t<!std::is_floating_point<T>::value && std::is_signed<T>::value>>
103+
{
104+
using type = xsimd::sized_int_t<sizeof(T) * 2>;
105+
};
106+
107+
template <typename T>
108+
struct widen<T, std::enable_if_t<!std::is_floating_point<T>::value && !std::is_signed<T>::value>>
109+
{
110+
using type = xsimd::sized_uint_t<sizeof(T) * 2>;
111+
};
112+
}
113+
114+
/**
115+
* @ingroup batch_traits
116+
*
117+
* The next-wider arithmetic type for @c T: doubles the size while preserving
118+
* signedness for integers and yielding @c double for @c float.
119+
* Supported input types: @c [u]int{8,16,32}_t and @c float.
120+
*
121+
* @tparam T arithmetic type to widen.
122+
*/
123+
template <typename T>
124+
using widen_t = typename detail::widen<T>::type;
125+
}
126+
127+
#endif

0 commit comments

Comments
 (0)