Eigen  5.0.1
 
Loading...
Searching...
No Matches
TypeCasting.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2025 Rasmus Munk Larsen
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_TYPE_CASTING_CLANG_H
12#define EIGEN_TYPE_CASTING_CLANG_H
13
14// IWYU pragma: private
15#include "../../InternalHeaderCheck.h"
16
17namespace Eigen {
18namespace internal {
19
20//==============================================================================
21// preinterpret
22//==============================================================================
23template <>
24EIGEN_STRONG_INLINE PacketXf preinterpret<PacketXf, PacketXi>(const PacketXi& a) {
25 return reinterpret_cast<PacketXf>(a);
26}
27template <>
28EIGEN_STRONG_INLINE PacketXi preinterpret<PacketXi, PacketXf>(const PacketXf& a) {
29 return reinterpret_cast<PacketXi>(a);
30}
31
32template <>
33EIGEN_STRONG_INLINE PacketXd preinterpret<PacketXd, PacketXl>(const PacketXl& a) {
34 return reinterpret_cast<PacketXd>(a);
35}
36template <>
37EIGEN_STRONG_INLINE PacketXl preinterpret<PacketXl, PacketXd>(const PacketXd& a) {
38 return reinterpret_cast<PacketXl>(a);
39}
40
41//==============================================================================
42// pcast
43//==============================================================================
44#if EIGEN_HAS_BUILTIN(__builtin_convertvector)
45// Float-to-int conversions: __builtin_convertvector has UB for NaN/inf/
46// out-of-range inputs. Replace NaN with 0 before converting so that
47// pldexp_fast (which may pass NaN exponents) doesn't trigger UB.
48template <>
49EIGEN_STRONG_INLINE PacketXi pcast<PacketXf, PacketXi>(const PacketXf& a) {
50 const PacketXf safe = a == a ? a : PacketXf(0);
51 return __builtin_convertvector(safe, PacketXi);
52}
53template <>
54EIGEN_STRONG_INLINE PacketXf pcast<PacketXi, PacketXf>(const PacketXi& a) {
55 return __builtin_convertvector(a, PacketXf);
56}
57
58template <>
59EIGEN_STRONG_INLINE PacketXl pcast<PacketXd, PacketXl>(const PacketXd& a) {
60 const PacketXd safe = a == a ? a : PacketXd(0);
61 return __builtin_convertvector(safe, PacketXl);
62}
63template <>
64EIGEN_STRONG_INLINE PacketXd pcast<PacketXl, PacketXd>(const PacketXl& a) {
65 return __builtin_convertvector(a, PacketXd);
66}
67
68// Widening and narrowing conversions run on half-width vectors: a widening cast
69// consumes the lower half of its input, and a narrowing cast joins the halves
70// produced from its two inputs.
71template <>
72EIGEN_STRONG_INLINE PacketXd pcast<PacketXf, PacketXd>(const PacketXf& a) {
73 return __builtin_convertvector(detail::lower_half(a), PacketXd);
74}
75
76template <>
77EIGEN_STRONG_INLINE PacketXf pcast<PacketXd, PacketXf>(const PacketXd& a, const PacketXd& b) {
78 using HalfFloat = detail::half_vector_t<PacketXf>;
79 return detail::concat_halves<PacketXf>(__builtin_convertvector(a, HalfFloat), __builtin_convertvector(b, HalfFloat));
80}
81
82template <>
83EIGEN_STRONG_INLINE PacketXl pcast<PacketXi, PacketXl>(const PacketXi& a) {
84 return __builtin_convertvector(detail::lower_half(a), PacketXl);
85}
86
87template <>
88EIGEN_STRONG_INLINE PacketXi pcast<PacketXl, PacketXi>(const PacketXl& a, const PacketXl& b) {
89 using HalfInt = detail::half_vector_t<PacketXi>;
90 return detail::concat_halves<PacketXi>(__builtin_convertvector(a, HalfInt), __builtin_convertvector(b, HalfInt));
91}
92#endif
93
94} // end namespace internal
95} // end namespace Eigen
96
97#endif // EIGEN_TYPE_CASTING_CLANG_H