mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Modify scalar pzero, ptrue, pselect, and p<binary> operations to avoid memset.
The `memset` function and bitwise manipulation only apply to POD types
that do not require initialization, otherwise resulting in UB. We currently
violate this in `ptrue` and `pzero`, we assume bitmasks for `pselect`, and
bitwise operations are applied byte-by-byte in the generic implementations.
This is causing issues for scalar types that do require initialization
or that contain non-POD info such as pointers (#2201). We either break
them, or force specializations of these functions for custom scalars,
even if they are not vectorized.
Here we modify these functions for scalars only - instead using only
scalar operations:
- `pzero`: `Scalar(0)` for all scalars.
- `ptrue`: `Scalar(1)` for non-trivial scalars, bitset to one bits for trivial scalars.
- `pselect`: ternary select comparing mask to `Scalar(0)` for all scalars
- `pand`, `por`, `pxor`, `pnot`: use operators `&`, `|`, `^`, `~` for all integer or non-trivial scalars, otherwise apply bytewise.
For non-scalar types, the original implementations are used to maintain
compatibility and minimize the number of changes.
Fixes #2201.
(cherry picked from commit 3d98a6ef5c)
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
3dc42eeaec
commit
237c59a2aa
@@ -126,7 +126,7 @@ template<>
|
||||
struct NumTraits<AnnoyingScalar> : NumTraits<float>
|
||||
{
|
||||
enum {
|
||||
RequireInitialization = true
|
||||
RequireInitialization = 1,
|
||||
};
|
||||
typedef AnnoyingScalar Real;
|
||||
typedef AnnoyingScalar Nested;
|
||||
@@ -145,10 +145,6 @@ bool (isfinite)(const AnnoyingScalar& x) {
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template<> EIGEN_STRONG_INLINE AnnoyingScalar pcmp_eq(const AnnoyingScalar& a, const AnnoyingScalar& b)
|
||||
{ return AnnoyingScalar(pcmp_eq(*a.v, *b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE AnnoyingScalar pselect(const AnnoyingScalar& mask, const AnnoyingScalar& a, const AnnoyingScalar& b)
|
||||
{ return numext::equal_strict(*mask.v, 0.f) ? b : a; }
|
||||
template<> EIGEN_STRONG_INLINE double cast(const AnnoyingScalar& x) { return double(*x.v); }
|
||||
template<> EIGEN_STRONG_INLINE float cast(const AnnoyingScalar& x) { return *x.v; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user