3 prim::{PrimSInt, PrimUInt},
4 traits::{Bool, Compare, Context, ConvertFrom, Float, Int, Make, SInt, Select, UInt},
7 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
8 Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
11 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
14 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
16 pub struct Value<T>(pub T);
18 macro_rules! impl_convert_from {
19 ($first:ident $(, $ty:ident)*) => {
21 impl ConvertFrom<Value<$first>> for Value<$ty> {
22 fn cvt_from(v: Value<$first>) -> Self {
23 Value(ConvertFrom::cvt_from(v.0))
26 impl ConvertFrom<Value<$ty>> for Value<$first> {
27 fn cvt_from(v: Value<$ty>) -> Self {
28 Value(ConvertFrom::cvt_from(v.0))
32 impl_convert_from![$($ty),*];
38 impl_convert_from![u8, i8, u16, i16, F16, u32, i32, u64, i64, f32, f64];
40 macro_rules! impl_bit_ops {
42 impl BitAnd for Value<$ty> {
45 fn bitand(self, rhs: Self) -> Self {
50 impl BitOr for Value<$ty> {
53 fn bitor(self, rhs: Self) -> Self {
58 impl BitXor for Value<$ty> {
61 fn bitxor(self, rhs: Self) -> Self {
66 impl Not for Value<$ty> {
69 fn not(self) -> Self {
74 impl BitAndAssign for Value<$ty> {
75 fn bitand_assign(&mut self, rhs: Self) {
80 impl BitOrAssign for Value<$ty> {
81 fn bitor_assign(&mut self, rhs: Self) {
86 impl BitXorAssign for Value<$ty> {
87 fn bitxor_assign(&mut self, rhs: Self) {
94 macro_rules! impl_wrapping_int_ops {
96 impl Add for Value<$ty> {
99 fn add(self, rhs: Self) -> Self {
100 Value(self.0.wrapping_add(rhs.0))
104 impl Sub for Value<$ty> {
107 fn sub(self, rhs: Self) -> Self {
108 Value(self.0.wrapping_sub(rhs.0))
112 impl Mul for Value<$ty> {
115 fn mul(self, rhs: Self) -> Self {
116 Value(self.0.wrapping_mul(rhs.0))
120 impl Div for Value<$ty> {
123 fn div(self, rhs: Self) -> Self {
124 Value(self.0.wrapping_div(rhs.0))
128 impl Rem for Value<$ty> {
131 fn rem(self, rhs: Self) -> Self {
132 Value(self.0.wrapping_rem(rhs.0))
136 impl Shl for Value<$ty> {
139 fn shl(self, rhs: Self) -> Self {
140 Value(self.0.wrapping_shl(rhs.0 as u32))
144 impl Shr for Value<$ty> {
147 fn shr(self, rhs: Self) -> Self {
148 Value(self.0.wrapping_shr(rhs.0 as u32))
152 impl Neg for Value<$ty> {
155 fn neg(self) -> Self {
156 Value(self.0.wrapping_neg())
160 impl AddAssign for Value<$ty> {
161 fn add_assign(&mut self, rhs: Self) {
162 *self = self.add(rhs);
166 impl SubAssign for Value<$ty> {
167 fn sub_assign(&mut self, rhs: Self) {
168 *self = self.sub(rhs);
172 impl MulAssign for Value<$ty> {
173 fn mul_assign(&mut self, rhs: Self) {
174 *self = self.mul(rhs);
178 impl DivAssign for Value<$ty> {
179 fn div_assign(&mut self, rhs: Self) {
180 *self = self.div(rhs);
184 impl RemAssign for Value<$ty> {
185 fn rem_assign(&mut self, rhs: Self) {
186 *self = self.rem(rhs);
190 impl ShlAssign for Value<$ty> {
191 fn shl_assign(&mut self, rhs: Self) {
192 *self = self.shl(rhs);
196 impl ShrAssign for Value<$ty> {
197 fn shr_assign(&mut self, rhs: Self) {
198 *self = self.shr(rhs);
203 macro_rules! impl_int {
206 impl_wrapping_int_ops!($ty);
207 impl Int for Value<$ty> {
208 fn leading_zeros(self) -> Self {
209 Value(self.0.leading_zeros() as $ty)
211 fn leading_ones(self) -> Self {
212 Value(self.0.leading_ones() as $ty)
214 fn trailing_zeros(self) -> Self {
215 Value(self.0.trailing_zeros() as $ty)
217 fn trailing_ones(self) -> Self {
218 Value(self.0.trailing_ones() as $ty)
220 fn count_zeros(self) -> Self {
221 Value(self.0.count_zeros() as $ty)
223 fn count_ones(self) -> Self {
224 Value(self.0.count_ones() as $ty)
230 macro_rules! impl_uint {
231 ($($ty:ident),*) => {
234 impl UInt for Value<$ty> {
236 type SignedType = Value<<$ty as PrimUInt>::SignedType>;
242 impl_uint![u8, u16, u32, u64];
244 macro_rules! impl_sint {
245 ($($ty:ident),*) => {
248 impl SInt for Value<$ty> {
250 type UnsignedType = Value<<$ty as PrimSInt>::UnsignedType>;
256 impl_sint![i8, i16, i32, i64];
258 macro_rules! impl_float_ops {
260 impl Add for Value<$ty> {
263 fn add(self, rhs: Self) -> Self {
264 Value(self.0.add(rhs.0))
268 impl Sub for Value<$ty> {
271 fn sub(self, rhs: Self) -> Self {
272 Value(self.0.sub(rhs.0))
276 impl Mul for Value<$ty> {
279 fn mul(self, rhs: Self) -> Self {
280 Value(self.0.mul(rhs.0))
284 impl Div for Value<$ty> {
287 fn div(self, rhs: Self) -> Self {
288 Value(self.0.div(rhs.0))
292 impl Rem for Value<$ty> {
295 fn rem(self, rhs: Self) -> Self {
296 Value(self.0.rem(rhs.0))
300 impl Neg for Value<$ty> {
303 fn neg(self) -> Self {
308 impl AddAssign for Value<$ty> {
309 fn add_assign(&mut self, rhs: Self) {
310 *self = self.add(rhs);
314 impl SubAssign for Value<$ty> {
315 fn sub_assign(&mut self, rhs: Self) {
316 *self = self.sub(rhs);
320 impl MulAssign for Value<$ty> {
321 fn mul_assign(&mut self, rhs: Self) {
322 *self = self.mul(rhs);
326 impl DivAssign for Value<$ty> {
327 fn div_assign(&mut self, rhs: Self) {
328 *self = self.div(rhs);
332 impl RemAssign for Value<$ty> {
333 fn rem_assign(&mut self, rhs: Self) {
334 *self = self.rem(rhs);
340 impl_float_ops!(F16);
342 macro_rules! impl_float {
343 ($ty:ident, $bits:ty, $signed_bits:ty) => {
344 impl_float_ops!($ty);
345 impl Float for Value<$ty> {
346 type PrimFloat = $ty;
347 type BitsType = Value<$bits>;
348 type SignedBitsType = Value<$signed_bits>;
349 fn abs(self) -> Self {
350 #[cfg(feature = "std")]
351 return Value(self.0.abs());
352 #[cfg(not(feature = "std"))]
353 return crate::algorithms::base::abs(Scalar, self);
355 fn copy_sign(self, sign: Self) -> Self {
356 #[cfg(feature = "std")]
357 return Value(self.0.copysign(sign.0));
358 #[cfg(not(feature = "std"))]
359 return crate::algorithms::base::copy_sign(Scalar, self, sign);
361 fn trunc(self) -> Self {
362 #[cfg(feature = "std")]
363 return Value(self.0.trunc());
364 #[cfg(not(feature = "std"))]
365 return crate::algorithms::base::trunc(Scalar, self);
367 fn ceil(self) -> Self {
368 #[cfg(feature = "std")]
369 return Value(self.0.ceil());
370 #[cfg(not(feature = "std"))]
371 return crate::algorithms::base::ceil(Scalar, self);
373 fn floor(self) -> Self {
374 #[cfg(feature = "std")]
375 return Value(self.0.floor());
376 #[cfg(not(feature = "std"))]
377 return crate::algorithms::base::floor(Scalar, self);
379 fn round(self) -> Self {
380 #[cfg(feature = "std")]
381 return Value(self.0.round());
382 #[cfg(not(feature = "std"))]
383 return crate::algorithms::base::round_to_nearest_ties_to_even(Scalar, self);
385 #[cfg(feature = "fma")]
386 fn fma(self, a: Self, b: Self) -> Self {
387 Value(self.0.mul_add(a.0, b.0))
389 fn is_nan(self) -> Self::Bool {
390 Value(self.0.is_nan())
392 fn is_infinite(self) -> Self::Bool {
393 Value(self.0.is_infinite())
395 fn is_finite(self) -> Self::Bool {
396 Value(self.0.is_finite())
398 fn from_bits(v: Self::BitsType) -> Self {
399 Value(<$ty>::from_bits(v.0))
401 fn to_bits(self) -> Self::BitsType {
402 Value(self.0.to_bits())
408 impl_float!(f32, u32, i32);
409 impl_float!(f64, u64, i64);
411 macro_rules! impl_compare_using_partial_cmp {
414 impl Compare for Value<$ty> {
415 type Bool = Value<bool>;
416 fn eq(self, rhs: Self) -> Self::Bool {
419 fn ne(self, rhs: Self) -> Self::Bool {
422 fn lt(self, rhs: Self) -> Self::Bool {
425 fn gt(self, rhs: Self) -> Self::Bool {
428 fn le(self, rhs: Self) -> Self::Bool {
431 fn ge(self, rhs: Self) -> Self::Bool {
439 impl_compare_using_partial_cmp![bool, u8, i8, u16, i16, F16, u32, i32, f32, u64, i64, f64];
441 impl Bool for Value<bool> {}
445 impl<T> Select<Value<T>> for Value<bool> {
446 fn select(self, true_v: Value<T>, false_v: Value<T>) -> Value<T> {
455 macro_rules! impl_from {
456 ($src:ident => [$($dest:ident),*]) => {
458 impl From<Value<$src>> for Value<$dest> {
459 fn from(v: Value<$src>) -> Self {
467 impl_from!(u8 => [u16, i16, F16, u32, i32, f32, u64, i64, f64]);
468 impl_from!(u16 => [u32, i32, f32, u64, i64, f64]);
469 impl_from!(u32 => [u64, i64, f64]);
470 impl_from!(i8 => [i16, F16, i32, f32, i64, f64]);
471 impl_from!(i16 => [i32, f32, i64, f64]);
472 impl_from!(i32 => [i64, f64]);
473 impl_from!(F16 => [f32, f64]);
474 impl_from!(f32 => [f64]);
476 macro_rules! impl_context {
478 impl Context for Scalar {
479 $(type $name:ident = Value<$ty:ident>;)*
481 $(type $vec_name:ident = Value<$vec_ty:ident>;)*
484 impl Context for Scalar {
485 $(type $name = Value<$ty>;)*
486 $(type $vec_name = Value<$vec_ty>;)*
490 impl Make for Value<$ty> {
492 type Context = Scalar;
493 fn ctx(self) -> Self::Context {
496 fn make(_ctx: Self::Context, v: Self::Prim) -> Self {
505 impl Context for Scalar {
506 type Bool = Value<bool>;
509 type U16 = Value<u16>;
510 type I16 = Value<i16>;
511 type F16 = Value<F16>;
512 type U32 = Value<u32>;
513 type I32 = Value<i32>;
514 type F32 = Value<f32>;
515 type U64 = Value<u64>;
516 type I64 = Value<i64>;
517 type F64 = Value<f64>;
519 type VecBool8 = Value<bool>;
520 type VecU8 = Value<u8>;
521 type VecI8 = Value<i8>;
522 type VecBool16 = Value<bool>;
523 type VecU16 = Value<u16>;
524 type VecI16 = Value<i16>;
525 type VecF16 = Value<F16>;
526 type VecBool32 = Value<bool>;
527 type VecU32 = Value<u32>;
528 type VecI32 = Value<i32>;
529 type VecF32 = Value<f32>;
530 type VecBool64 = Value<bool>;
531 type VecU64 = Value<u64>;
532 type VecI64 = Value<i64>;
533 type VecF64 = Value<f64>;