Compare commits
8 Commits
b1fdbeb3de
...
6b7619da2f
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b7619da2f | |||
| 948ac5f297 | |||
| fbef05fcd1 | |||
| b014dd959c | |||
| 7112987742 | |||
| b8652f6784 | |||
| d5b4490eab | |||
| a91bdbaff4 |
@ -1,8 +1,8 @@
|
||||
[package]
|
||||
name = "sigils"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2024"
|
||||
description = "A mathematics library."
|
||||
description = "High-performance no_std linear algebra for simulations and embedded flight systems."
|
||||
keywords = ["sigils", "math"]
|
||||
repository = "https://workshop.cybermages.tech/CyberMages/sigils"
|
||||
authors = ["Jason Travis Smith <Myrddin@CyberMages.tech>"]
|
||||
@ -10,5 +10,3 @@ readme = "README.md"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
binding = { version = "0.1.0", registry = "cybermages" }
|
||||
pact = { version = "0.1.0", registry = "cybermages" }
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use sigils::quaternion::{Quaternion};
|
||||
|
||||
|
||||
pub fn main()
|
||||
{
|
||||
let quat: Quaternion<f64>;
|
||||
|
||||
quat = Quaternion::<f64>::default();
|
||||
println!("Quaternion: {}", quat);
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use sigils::{Constants, Degree, Radian, Trig};
|
||||
|
||||
|
||||
|
||||
fn main()
|
||||
{
|
||||
let mut val: f64;
|
||||
let mut degrees: Degree<f64>;
|
||||
let mut radians: Radian<f64>;
|
||||
|
||||
val = Constants::QUARTER_PI;
|
||||
val *= 6f64;
|
||||
radians = Radian::new(val);
|
||||
degrees = Trig::acos(Trig::cos(radians));
|
||||
|
||||
println!("{:?}", radians);
|
||||
println!("{:?}", degrees);
|
||||
println!("");
|
||||
|
||||
radians = Radian::new(Constants::QUARTER_PI);
|
||||
radians = Trig::acos(Trig::cos(radians));
|
||||
degrees = Degree::from(radians);
|
||||
|
||||
println!("{:?}", radians);
|
||||
println!("{:?}", degrees);
|
||||
println!("");
|
||||
|
||||
degrees = Degree::new(270.0f64);
|
||||
radians = Trig::acos(Trig::cos(degrees));
|
||||
|
||||
println!("{:?}", degrees);
|
||||
println!("{:?}", radians);
|
||||
println!("");
|
||||
|
||||
degrees = Degree::new(90.0f64);
|
||||
degrees = Trig::acos(Trig::cos(degrees));
|
||||
radians = Radian::from(degrees);
|
||||
|
||||
println!("{:?}", degrees);
|
||||
println!("{:?}", radians);
|
||||
println!("");
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use sigils::vector::{EuclideanVector, Vector2, Vector3, Vector4};
|
||||
|
||||
|
||||
|
||||
pub fn main()
|
||||
{
|
||||
let length: f32;
|
||||
let vec2: Vector2<f64>;
|
||||
let vec3: Vector3<f64>;
|
||||
let vec4: Vector4<f64>;
|
||||
let vector: Vector4<f32>;
|
||||
|
||||
vec2 = Vector2::default();
|
||||
println!("Vector2: {}", vec2);
|
||||
|
||||
vec3 = Vector3::default();
|
||||
println!("Vector3: {}", vec3);
|
||||
|
||||
vec4 = Vector4::default();
|
||||
println!("Vector4: {}", vec4);
|
||||
|
||||
vector = Vector4::new(5.5f32, 5.5f32, 5.5f32, 5.5f32);
|
||||
length = vector.get_length();
|
||||
println!("Vector: {} -- Length: {}", vector, length);
|
||||
assert_eq!(length, 11.0f32);
|
||||
}
|
||||
112
src/bounded.rs
112
src/bounded.rs
@ -1,13 +1,38 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
/// Primitive types that have upper and lower bounds.
|
||||
/// `Bounded` provides the inclusive minimum and maximum range limits
|
||||
/// for a numeric type.
|
||||
///
|
||||
/// Rust types have actual upper and lower representation limits that don't
|
||||
/// follow the mathematical definitions. For example a Natural number goes
|
||||
/// from one to infinity but a u8 can only really represent a number between
|
||||
/// zero and two hundred and fifty five. This let's use set the minimum and
|
||||
/// maximum values a Rust type can represent so we can use them in code easily.
|
||||
pub trait Bounded
|
||||
{
|
||||
/// The minimum value for this type.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use sigils::Bounded;
|
||||
///
|
||||
/// let min = <u8 as Bounded>::MIN;
|
||||
///
|
||||
/// assert_eq!(min, u8::MIN);
|
||||
/// ```
|
||||
const MIN: Self;
|
||||
|
||||
/// The maximum value for this type.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use sigils::Bounded;
|
||||
///
|
||||
/// let max = <f64 as Bounded>::MAX;
|
||||
///
|
||||
/// assert_eq!(max, f64::MAX);
|
||||
/// ```
|
||||
const MAX: Self;
|
||||
}
|
||||
|
||||
@ -17,83 +42,20 @@ pub trait Bounded
|
||||
/// the Bounded trait easier.
|
||||
macro_rules! bounded_trait_impl
|
||||
{
|
||||
($T: ty, $minVal: expr, $maxVal: expr) =>
|
||||
($($T:ty),*) =>
|
||||
{
|
||||
impl Bounded for $T
|
||||
{
|
||||
const MIN: $T = $minVal;
|
||||
|
||||
const MAX: $T = $maxVal;
|
||||
}
|
||||
$(
|
||||
impl Bounded for $T
|
||||
{
|
||||
const MIN: $T = <$T>::MIN;
|
||||
const MAX: $T = <$T>::MAX;
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implement the Bounded for all the primitive types.
|
||||
bounded_trait_impl!(u8, 0u8, !0u8);
|
||||
bounded_trait_impl!(u16, 0u16, !0u16);
|
||||
bounded_trait_impl!(u32, 0u32, !0u32);
|
||||
bounded_trait_impl!(u64, 0u64, !0u64);
|
||||
bounded_trait_impl!(usize, 0usize, !0usize);
|
||||
|
||||
bounded_trait_impl!(i8, (!0i8 ^ (!0u8 >> 1u8) as i8),
|
||||
!(!0i8 ^ (!0u8 >> 1u8) as i8));
|
||||
bounded_trait_impl!(i16, (!0i16 ^ (!0u16 >> 1u16) as i16),
|
||||
!(!0i16 ^ (!0u16 >> 1u16) as i16));
|
||||
bounded_trait_impl!(i32, (!0i32 ^ (!0u32 >> 1u32) as i32),
|
||||
!(!0i32 ^ (!0u32 >> 1u32) as i32));
|
||||
bounded_trait_impl!(i64, (!0i64 ^ (!0u64 >> 1u64) as i64),
|
||||
!(!0i64 ^ (!0u64 >> 1u64) as i64));
|
||||
bounded_trait_impl!(isize, (!0isize ^ (!0usize >> 1usize) as isize),
|
||||
!(!0isize ^ (!0usize >> 1usize) as isize));
|
||||
|
||||
bounded_trait_impl!(f32, -3.40282347e+38f32, 3.40282347e+38f32);
|
||||
bounded_trait_impl!(f64, -1.7976931348623157e+308f64,
|
||||
1.7976931348623157e+308f64);
|
||||
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests
|
||||
{
|
||||
macro_rules! bounds_test
|
||||
{
|
||||
($T: ident, $func_name: ident, $minVal: expr, $maxVal: expr) =>
|
||||
{
|
||||
#[test]
|
||||
fn $func_name()
|
||||
{
|
||||
assert_eq!($T::MIN, $minVal);
|
||||
assert_eq!($T::MAX, $maxVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bounds_test!(u8, min_max_u8, 0u8, !0u8);
|
||||
bounds_test!(u16, min_max_u16, 0u16, !0u16);
|
||||
bounds_test!(u32, min_max_u32, 0u32, !0u32);
|
||||
bounds_test!(u64, min_max_u64, 0u64, !0u64);
|
||||
bounds_test!(usize, min_max_usize, 0usize, !0usize);
|
||||
|
||||
bounds_test!(i8, min_max_i8,
|
||||
-1i8 << (((::std::mem::size_of::<i8>() as i8)*8i8)-1i8),
|
||||
!(-1i8 << (((::std::mem::size_of::<i8>() as i8)*8i8)-1i8)));
|
||||
bounds_test!(i16, min_max_i16,
|
||||
-1i16 << (((::std::mem::size_of::<i16>() as i16)*8i16)-1i16),
|
||||
!(-1i16 << (((::std::mem::size_of::<i16>() as i16)*8i16)-1i16)));
|
||||
bounds_test!(i32, min_max_i32,
|
||||
-1i32 << (((::std::mem::size_of::<i32>() as i32)*8i32)-1i32),
|
||||
!(-1i32 << (((::std::mem::size_of::<i32>() as i32)*8i32)-1i32)));
|
||||
bounds_test!(i64, min_max_i64,
|
||||
-1i64 << (((::std::mem::size_of::<i64>() as i64)*8i64)-1i64),
|
||||
!(-1i64 << (((::std::mem::size_of::<i64>() as i64)*8i64)-1i64)));
|
||||
bounds_test!(isize, min_max_isize,
|
||||
-1isize << (((::std::mem::size_of::<isize>() as isize)*8isize)-1isize),
|
||||
!(-1isize << (((::std::mem::size_of::<isize>() as isize)*8isize)-1isize)));
|
||||
|
||||
bounds_test!(f32, min_max_f32,
|
||||
-3.40282347e+38f32, 3.40282347e+38f32);
|
||||
bounds_test!(f64, min_max_f64,
|
||||
-1.7976931348623157e+308f64,
|
||||
1.7976931348623157e+308f64);
|
||||
}
|
||||
bounded_trait_impl!(u8, u16, u32, u64, u128, usize);
|
||||
bounded_trait_impl!(i8, i16, i32, i64, i128, isize);
|
||||
bounded_trait_impl!(f32, f64);
|
||||
|
||||
40
src/lib.rs
40
src/lib.rs
@ -1,23 +1,38 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
//! A mathematical library.
|
||||
//! License: Proprietary
|
||||
//! # Sigils
|
||||
//!
|
||||
//! A high performance, 'no_std' mathematical library designed for use in
|
||||
//! simulations and flight systems.
|
||||
//!
|
||||
//! Sigils uses Rust's type system to strictly define a mathematical hierarchy
|
||||
//! to ensure type-safe operations.
|
||||
|
||||
#![no_std]
|
||||
extern crate core as std;
|
||||
|
||||
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
mod bounded;
|
||||
|
||||
mod zero;
|
||||
mod one;
|
||||
mod natural;
|
||||
mod number;
|
||||
mod one;
|
||||
mod zero;
|
||||
|
||||
|
||||
|
||||
pub use self::bounded::Bounded;
|
||||
pub use self::natural::Natural;
|
||||
pub use self::number::Number;
|
||||
pub use self::one::One;
|
||||
pub use self::zero::Zero;
|
||||
|
||||
|
||||
|
||||
//#[macro_use]
|
||||
//mod macros;
|
||||
/*
|
||||
|
||||
mod whole;
|
||||
mod integer;
|
||||
mod real;
|
||||
@ -28,11 +43,9 @@ mod trig;
|
||||
pub mod vector;
|
||||
pub mod matrix;
|
||||
pub mod quaternion;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
pub use self::bounded::Bounded;
|
||||
pub use self::zero::Zero;
|
||||
/*
|
||||
pub use self::one::One;
|
||||
pub use self::number::{Number, FromNumber};
|
||||
pub use self::whole::Whole;
|
||||
@ -40,3 +53,4 @@ pub use self::integer::Integer;
|
||||
pub use self::real::Real;
|
||||
pub use self::constants::Constants;
|
||||
pub use self::trig::{Degree, Radian, Trig};
|
||||
*/
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
82
src/natural.rs
Normal file
82
src/natural.rs
Normal file
@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use core::ops::{Add, AddAssign, Mul, MulAssign};
|
||||
|
||||
use crate::number::Number;
|
||||
use crate::one::One;
|
||||
|
||||
|
||||
|
||||
/// A Natural number is a counting number from one to infinity.
|
||||
/// 1, 2, 3, 4, 5, 6, ...
|
||||
///
|
||||
/// Rust types that are in this category are:
|
||||
/// u8, u16, u32, u64, u128, usize
|
||||
pub trait Natural: Number + One +
|
||||
Add<Output=Self> + AddAssign +
|
||||
Mul<Output=Self> + MulAssign +
|
||||
{
|
||||
/// Attempts to subtract a number from itself.
|
||||
///
|
||||
/// Since subtraction isn't closed under this set (1 - 2 = -1) the trait
|
||||
/// doesn't enforce that Sub and SubAssign are implemented. This function,
|
||||
/// however, allows for subtraction and handles the case where the result is
|
||||
/// no longer within the `Natural` numbers domain.
|
||||
///
|
||||
/// # Arguments
|
||||
/// `rhs`: The number to subtract.
|
||||
///
|
||||
/// # Returns
|
||||
/// `None` if the subtraction would fall below 1.
|
||||
/// `Some` if their is a valid result.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use sigils::Natural;
|
||||
///
|
||||
/// let x = 3u8 as Natural;
|
||||
///
|
||||
/// assert_eq!(x.try_sub(2), Some(1));
|
||||
/// assert_eq!(x.try_sub(7), None);
|
||||
/// ```
|
||||
fn try_sub(self, rhs: Self) -> Option<Self>;
|
||||
/*
|
||||
///
|
||||
fn try_div(self, rhs: Self) -> Option<Self>;
|
||||
|
||||
///
|
||||
fn try_rem(self, rhs: Self) -> Option<Self>;
|
||||
|
||||
/// Performs division and returns both the quotient and remainder.
|
||||
#[inline]
|
||||
fn try_div_rem(self, rhs: Self) -> Option<(Self, Self)>
|
||||
{
|
||||
Some((self.try_div(rhs)?, self.try_rem(rhs)?))
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// A macro to make implementing the `Natural` trait easier for all the
|
||||
/// base types in Rust.
|
||||
macro_rules! natural_trait_impl
|
||||
{
|
||||
($($varType:ty),*) =>
|
||||
{
|
||||
$(
|
||||
impl Natural for $varType
|
||||
{
|
||||
#[inline]
|
||||
fn try_sub(self, rhs: Self) -> Option<Self>
|
||||
{
|
||||
self.checked_sub(rhs).filter(|x| *x >= Self::one())
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the Number trait for the types that are Numbers.
|
||||
natural_trait_impl!(u8, u16, u32, u64, u128, usize);
|
||||
962
src/number.rs
962
src/number.rs
@ -1,42 +1,35 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use std::cmp::{PartialEq, PartialOrd};
|
||||
use std::fmt::{Debug, Display};
|
||||
use std::mem::size_of;
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem};
|
||||
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::bounded::Bounded;
|
||||
use crate::zero::Zero;
|
||||
use crate::one::One;
|
||||
use core::cmp::{PartialEq, PartialOrd};
|
||||
use core::fmt::{Debug, Display};
|
||||
|
||||
|
||||
/// A trait that defines what is required to be considered
|
||||
/// a number.
|
||||
pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> +
|
||||
Mul<Output=Self> + Div<Output=Self> + Rem<Output=Self> +
|
||||
AddAssign<Self> + SubAssign<Self> + MulAssign<Self> +
|
||||
DivAssign<Self> + RemAssign<Self> + PartialEq + PartialOrd +
|
||||
Copy + Clone + Debug + Display
|
||||
|
||||
/// `Number` helps bridge the gap between the rust implementation and the pure
|
||||
/// math definitions.
|
||||
///
|
||||
/// `Number` has some basic Rust representation requirements.
|
||||
///
|
||||
/// [`Sized`]: A `Number` has a known size at compile time.
|
||||
/// [`Copy`] & [`Clone`]: A `Number` should be passed by value, not reference.
|
||||
/// [`PartialEq`] & [`PartialOrd`]: Two instances of `Number` should be able to be compared.
|
||||
/// [`Debug`] & [`Display`]: Easier to read output.
|
||||
pub trait Number: Sized + Copy + Clone +
|
||||
PartialEq + PartialOrd +
|
||||
Debug + Display
|
||||
{
|
||||
type StrRadixError;
|
||||
|
||||
|
||||
|
||||
/// The smallest number that can be stored in this type.
|
||||
//const MIN: Self;
|
||||
|
||||
/// The largest number that can be stored in this type.
|
||||
//const MAX: Self;
|
||||
|
||||
|
||||
|
||||
/// Returns the maximum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// use ::sigils::Number;
|
||||
/// # Arguments
|
||||
/// * `other` - Another value, of the same type, to compare.
|
||||
///
|
||||
/// # Returns
|
||||
/// The larger value of the two numbers.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use sigils::Number;
|
||||
///
|
||||
/// let x: f64;
|
||||
/// let y: f64;
|
||||
@ -45,12 +38,23 @@ pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> +
|
||||
/// y = 2.0f64;
|
||||
/// assert_eq!(x.maximum(y), y);
|
||||
/// ```
|
||||
fn maximum(self, other: Self) -> Self;
|
||||
#[inline]
|
||||
fn maximum(self, other: Self) -> Self
|
||||
{
|
||||
if self >= other { self } else { other }
|
||||
}
|
||||
|
||||
/// Returns the minimum of the two numbers.
|
||||
///
|
||||
/// ```
|
||||
/// use ::sigils::Number;
|
||||
/// # Arguments
|
||||
/// * `other` - Another value, of the same type, to compare.
|
||||
///
|
||||
/// # Returns
|
||||
/// The smaller value of the two numbers.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use sigils::Number;
|
||||
///
|
||||
/// let x: i16;
|
||||
/// let y: i16;
|
||||
@ -59,883 +63,29 @@ pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> +
|
||||
/// y = 55i16;
|
||||
/// assert_eq!(x.minimum(y), x);
|
||||
/// ```
|
||||
fn minimum(self, other: Self) -> Self;
|
||||
|
||||
/// Create a number from a given string and base radix.
|
||||
///
|
||||
///```
|
||||
/// // Parse the hex value "FF" into an i32.
|
||||
/// // Hex values have a radix (base) of 16.
|
||||
/// use sigils::Number;
|
||||
///
|
||||
/// let x: i32 = Number::from_str_radix("FF", 16u32).unwrap();
|
||||
/// # assert_eq!(x, 255i32);
|
||||
///```
|
||||
fn from_str_radix(src: &str, radix: u32) ->
|
||||
Result<Self, Self::StrRadixError>;
|
||||
#[inline]
|
||||
fn minimum(self, other: Self) -> Self
|
||||
{
|
||||
if self <= other { self } else { other }
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait that defines converting something to a Number.
|
||||
pub trait ToNumber
|
||||
|
||||
|
||||
|
||||
/// A macro to make implementing the `Number` trait easier for all the
|
||||
/// base types in Rust.
|
||||
macro_rules! number_trait_impl
|
||||
{
|
||||
/// Convert this to an u8.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_u8(&self) -> Option<u8>
|
||||
($($varType:ty),*) =>
|
||||
{
|
||||
let option: Option<u64>;
|
||||
|
||||
option = self.to_u64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_u8()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to a u16.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_u16(&self) -> Option<u16>
|
||||
{
|
||||
let option: Option<u64>;
|
||||
|
||||
option = self.to_u64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_u16()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an u32.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_u32(&self) -> Option<u32>
|
||||
{
|
||||
let option: Option<u64>;
|
||||
|
||||
option = self.to_u64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_u32()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an u64.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_u64(&self) -> Option<u64>;
|
||||
|
||||
/// Convert this to an usize.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_usize(&self) -> Option<usize>
|
||||
{
|
||||
let option: Option<u64>;
|
||||
|
||||
option = self.to_u64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_usize()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Convert this to an i8.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_i8(&self) -> Option<i8>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_i8()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an i16.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_i16(&self) -> Option<i16>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_i16()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an i32.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_i32(&self) -> Option<i32>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_i32()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an i64.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_i64(&self) -> Option<i64>;
|
||||
|
||||
/// Convert this to an isize.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_isize(&self) -> Option<isize>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_isize()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Convert this to an f32.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_f32(&self) -> Option<f32>
|
||||
{
|
||||
let option: Option<f64>;
|
||||
|
||||
option = self.to_f64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_f32()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an f64.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_f64(&self) -> Option<f64>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_f64()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
$(
|
||||
impl Number for $varType {}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait that defines convertung a Number to something else.
|
||||
pub trait FromNumber : Sized
|
||||
{
|
||||
/// Convert an i8 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_i8(number: i8) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
|
||||
/// Convert an i16 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_i16(number: i16) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
|
||||
/// Convert an i32 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_i32(number: i32) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
|
||||
/// Convert an i64 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_i64(number: i64) -> Option<Self>;
|
||||
|
||||
/// Convert an isize to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_isize(number: isize) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
|
||||
|
||||
/// Convert an u8 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_u8(number: u8) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_u64(number as u64)
|
||||
}
|
||||
|
||||
/// Convert an u16 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_u16(number: u16) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_u64(number as u64)
|
||||
}
|
||||
|
||||
/// Convert an u32 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_u32(number: u32) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_u64(number as u64)
|
||||
}
|
||||
|
||||
/// Convert an u64 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_u64(number: u64) -> Option<Self>;
|
||||
|
||||
/// Convert an usize to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_usize(number: usize) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_u64(number as u64)
|
||||
}
|
||||
|
||||
|
||||
/// Convert an f32 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_f32(number: f32) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_f64(number as f64)
|
||||
}
|
||||
|
||||
/// Convert an f64 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_f64(number: f64) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create some macros to ease typing and reading.
|
||||
macro_rules! convert_int_to_int
|
||||
{
|
||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
||||
{
|
||||
{
|
||||
let num: i64;
|
||||
let min_value: $dstType;
|
||||
let max_value: $dstType;
|
||||
|
||||
num = $val as i64;
|
||||
min_value = Bounded::MIN;
|
||||
max_value = Bounded::MAX;
|
||||
|
||||
if (min_value as i64) <= num && num <= (max_value as i64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! convert_int_to_uint
|
||||
{
|
||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
||||
{
|
||||
{
|
||||
let zero: $srcType;
|
||||
let max_value: $dstType;
|
||||
|
||||
zero = Zero::zero();
|
||||
max_value = Bounded::MAX;
|
||||
|
||||
if zero <= $val && ($val as u64) <= (max_value as u64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! convert_uint_to_int
|
||||
{
|
||||
($dstType: ty, $val: expr) =>
|
||||
{
|
||||
{
|
||||
let max_value: $dstType;
|
||||
|
||||
max_value = Bounded::MAX;
|
||||
if ($val as u64) <= (max_value as u64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! convert_uint_to_uint
|
||||
{
|
||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
||||
{
|
||||
if size_of::<$srcType>() <= size_of::<$dstType>()
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
let zero: $srcType;
|
||||
let max_value: $dstType;
|
||||
|
||||
zero = Zero::zero();
|
||||
max_value = Bounded::MAX;
|
||||
|
||||
if zero <= $val && ($val as u64) <= (max_value as u64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! convert_float_to_float
|
||||
{
|
||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
||||
{
|
||||
if size_of::<$srcType>() <= size_of::<$dstType>()
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
let num: f64;
|
||||
let min_value: $srcType;
|
||||
let max_value: $srcType;
|
||||
|
||||
num = $val as f64;
|
||||
min_value = Bounded::MIN;
|
||||
max_value = Bounded::MAX;
|
||||
|
||||
if (min_value as f64) <= num && num <= (max_value as f64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! int_to_number_impl
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
impl $traitName for $varType
|
||||
{
|
||||
fn to_u8(&self) -> Option<u8>
|
||||
{
|
||||
convert_int_to_uint!($varType, u8, *self)
|
||||
}
|
||||
|
||||
fn to_u16(&self) -> Option<u16>
|
||||
{
|
||||
convert_int_to_uint!($varType, u16, *self)
|
||||
}
|
||||
|
||||
fn to_u32(&self) -> Option<u32>
|
||||
{
|
||||
convert_int_to_uint!($varType, u32, *self)
|
||||
}
|
||||
|
||||
fn to_u64(&self) -> Option<u64>
|
||||
{
|
||||
convert_int_to_uint!($varType, u64, *self)
|
||||
}
|
||||
|
||||
fn to_usize(&self) -> Option<usize>
|
||||
{
|
||||
convert_int_to_uint!($varType, usize, *self)
|
||||
}
|
||||
|
||||
|
||||
fn to_i8(&self) -> Option<i8>
|
||||
{
|
||||
convert_int_to_int!($varType, i8, *self)
|
||||
}
|
||||
|
||||
fn to_i16(&self) -> Option<i16>
|
||||
{
|
||||
convert_int_to_int!($varType, i16, *self)
|
||||
}
|
||||
|
||||
fn to_i32(&self) -> Option<i32>
|
||||
{
|
||||
convert_int_to_int!($varType, i32, *self)
|
||||
}
|
||||
|
||||
fn to_i64(&self) -> Option<i64>
|
||||
{
|
||||
convert_int_to_int!($varType, i64, *self)
|
||||
}
|
||||
|
||||
fn to_isize(&self) -> Option<isize>
|
||||
{
|
||||
convert_int_to_int!($varType, isize, *self)
|
||||
}
|
||||
|
||||
|
||||
fn to_f32(&self) -> Option<f32>
|
||||
{
|
||||
Some(*self as f32)
|
||||
}
|
||||
|
||||
fn to_f64(&self) -> Option<f64>
|
||||
{
|
||||
Some(*self as f64)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
macro_rules! uint_to_number_impl
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
impl $traitName for $varType
|
||||
{
|
||||
fn to_u8(&self) -> Option<u8>
|
||||
{
|
||||
convert_uint_to_uint!($varType, u8, *self)
|
||||
}
|
||||
|
||||
fn to_u16(&self) -> Option<u16>
|
||||
{
|
||||
convert_uint_to_uint!($varType, u16, *self)
|
||||
}
|
||||
|
||||
fn to_u32(&self) -> Option<u32>
|
||||
{
|
||||
convert_uint_to_uint!($varType, u32, *self)
|
||||
}
|
||||
|
||||
fn to_u64(&self) -> Option<u64>
|
||||
{
|
||||
convert_uint_to_uint!($varType, u64, *self)
|
||||
}
|
||||
|
||||
fn to_usize(&self) -> Option<usize>
|
||||
{
|
||||
convert_uint_to_uint!($varType, usize, *self)
|
||||
}
|
||||
|
||||
|
||||
fn to_i8(&self) -> Option<i8>
|
||||
{
|
||||
convert_uint_to_int!(i8, *self)
|
||||
}
|
||||
|
||||
fn to_i16(&self) -> Option<i16>
|
||||
{
|
||||
convert_uint_to_int!(i16, *self)
|
||||
}
|
||||
|
||||
fn to_i32(&self) -> Option<i32>
|
||||
{
|
||||
convert_uint_to_int!(i32, *self)
|
||||
}
|
||||
|
||||
fn to_i64(&self) -> Option<i64>
|
||||
{
|
||||
convert_uint_to_int!(i64, *self)
|
||||
}
|
||||
|
||||
fn to_isize(&self) -> Option<isize>
|
||||
{
|
||||
convert_uint_to_int!(isize, *self)
|
||||
}
|
||||
|
||||
|
||||
fn to_f32(&self) -> Option<f32>
|
||||
{
|
||||
Some(*self as f32)
|
||||
}
|
||||
|
||||
fn to_f64(&self) -> Option<f64>
|
||||
{
|
||||
Some(*self as f64)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
macro_rules! float_to_number_impl
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
impl $traitName for $varType
|
||||
{
|
||||
fn to_u8(&self) -> Option<u8>
|
||||
{
|
||||
Some(*self as u8)
|
||||
}
|
||||
|
||||
fn to_u16(&self) -> Option<u16>
|
||||
{
|
||||
Some(*self as u16)
|
||||
}
|
||||
|
||||
fn to_u32(&self) -> Option<u32>
|
||||
{
|
||||
Some(*self as u32)
|
||||
}
|
||||
|
||||
fn to_u64(&self) -> Option<u64>
|
||||
{
|
||||
Some(*self as u64)
|
||||
}
|
||||
|
||||
fn to_usize(&self) -> Option<usize>
|
||||
{
|
||||
Some(*self as usize)
|
||||
}
|
||||
|
||||
|
||||
fn to_i8(&self) -> Option<i8>
|
||||
{
|
||||
Some(*self as i8)
|
||||
}
|
||||
|
||||
fn to_i16(&self) -> Option<i16>
|
||||
{
|
||||
Some(*self as i16)
|
||||
}
|
||||
|
||||
fn to_i32(&self) -> Option<i32>
|
||||
{
|
||||
Some(*self as i32)
|
||||
}
|
||||
|
||||
fn to_i64(&self) -> Option<i64>
|
||||
{
|
||||
Some(*self as i64)
|
||||
}
|
||||
|
||||
fn to_isize(&self) -> Option<isize>
|
||||
{
|
||||
Some(*self as isize)
|
||||
}
|
||||
|
||||
|
||||
fn to_f32(&self) -> Option<f32>
|
||||
{
|
||||
convert_float_to_float!($varType, f32, *self)
|
||||
}
|
||||
|
||||
fn to_f64(&self) -> Option<f64>
|
||||
{
|
||||
convert_float_to_float!($varType, f64, *self)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
macro_rules! from_number_impl
|
||||
{
|
||||
($varType: ty, $toTypeFunc: ident) =>
|
||||
{
|
||||
impl FromNumber for $varType
|
||||
{
|
||||
fn from_u8(number: u8) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_u16(number: u16) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_u32(number: u32) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_u64(number: u64) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
|
||||
fn from_i8(number: i8) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_i16(number: i16) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_i32(number: i32) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_i64(number: i64) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
|
||||
fn from_f32(number: f32) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_f64(number: f64) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro to make implementing the Number trait easier for all the
|
||||
/// base integer types in rust.
|
||||
macro_rules! int_number_trait_impl
|
||||
{
|
||||
($traitName: ident for $varType: ty, $min: expr, $max: expr) =>
|
||||
{
|
||||
impl $traitName for $varType
|
||||
{
|
||||
type StrRadixError = ::std::num::ParseIntError;
|
||||
|
||||
|
||||
|
||||
//const MIN: Self = $min;
|
||||
//const MAX: Self = $max;
|
||||
|
||||
|
||||
|
||||
fn maximum(self, other: Self) -> Self
|
||||
{
|
||||
if self >= other
|
||||
{
|
||||
self
|
||||
}
|
||||
else
|
||||
{
|
||||
other
|
||||
}
|
||||
}
|
||||
|
||||
fn minimum(self, other: Self) -> Self
|
||||
{
|
||||
if self <= other
|
||||
{
|
||||
self
|
||||
}
|
||||
else
|
||||
{
|
||||
other
|
||||
}
|
||||
}
|
||||
|
||||
fn from_str_radix(src: &str, radix: u32) ->
|
||||
Result<Self, ::std::num::ParseIntError>
|
||||
{
|
||||
<$varType>::from_str_radix(src, radix)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro to make implementing the Number trait easier for all the
|
||||
/// base float types in rust.
|
||||
macro_rules! float_number_trait_impl
|
||||
{
|
||||
($traitName: ident for $varType: ty, $min: expr, $max: expr,
|
||||
$minFunc: ident, $maxFunc: ident) =>
|
||||
{
|
||||
impl $traitName for $varType
|
||||
{
|
||||
type StrRadixError = ::std::num::ParseFloatError;
|
||||
|
||||
|
||||
|
||||
//const MIN: Self = $min;
|
||||
//const MAX: Self = $max;
|
||||
|
||||
|
||||
|
||||
fn maximum(self, other: Self) -> Self
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
::pact::math::$maxFunc(self, other) as Self
|
||||
}
|
||||
}
|
||||
|
||||
fn minimum(self, other: Self) -> Self
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
::pact::math::$minFunc(self, other) as Self
|
||||
}
|
||||
}
|
||||
|
||||
fn from_str_radix(src: &str, radix: u32) ->
|
||||
Result<Self, ::std::num::ParseFloatError>
|
||||
{
|
||||
// TODO: Currently this will panic on a non base 10 radix.
|
||||
// This is because the std library deprecated the
|
||||
// from_str_radix function. Until a function can be
|
||||
// written this will use the from_str function and
|
||||
// panic for non base 10 requests.
|
||||
assert!(radix == 10);
|
||||
<$varType>::from_str(src)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implement the Number trait for the types that are Numbers.
|
||||
int_number_trait_impl!(Number for u8, 0u8, 255u8);
|
||||
int_number_trait_impl!(Number for u16, 0u16, 65535u16);
|
||||
int_number_trait_impl!(Number for u32, 0u32, 4294967295u32);
|
||||
int_number_trait_impl!(Number for u64, 0u64, 18446744073709551615u64);
|
||||
int_number_trait_impl!(Number for i8, -128i8, 127i8);
|
||||
int_number_trait_impl!(Number for i16, -32768i16, 32767i16);
|
||||
int_number_trait_impl!(Number for i32, -2147483648i32, 2147483647i32);
|
||||
int_number_trait_impl!(Number for i64, -9223372036854775808i64,
|
||||
9223372036854775807i64);
|
||||
float_number_trait_impl!(Number for f32, -3.40282347e+38f32,
|
||||
3.40282347e+38f32,
|
||||
fminf, fmaxf);
|
||||
float_number_trait_impl!(Number for f64, -1.7976931348623157e+308f64,
|
||||
1.7976931348623157e+308f64,
|
||||
fmin, fmax);
|
||||
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
int_number_trait_impl!(Number for usize, 0usize, 65535usize);
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
int_number_trait_impl!(Number for usize, 0usize, 4294967295usize);
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
int_number_trait_impl!(Number for usize, 0usize, 18446744073709551615usize);
|
||||
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
int_number_trait_impl!(Number for isize, -32768isize, 32767isize);
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
int_number_trait_impl!(Number for isize, -2147483648isize, 2147483647isize);
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
int_number_trait_impl!(Number for isize, -9223372036854775808isize,
|
||||
9223372036854775807isize);
|
||||
|
||||
// Implement the ToNumber and FromNumber traits for
|
||||
// the types that are Numbers. The FromNumber trait needs
|
||||
// to be defined after ToNumber since FromNumber uses
|
||||
// ToNumber definitions.
|
||||
uint_to_number_impl!(ToNumber for u8 u16 u32 u64 usize);
|
||||
int_to_number_impl!(ToNumber for i8 i16 i32 i64 isize);
|
||||
float_to_number_impl!(ToNumber for f32 f64);
|
||||
|
||||
from_number_impl!(u8, to_u8);
|
||||
from_number_impl!(u16, to_u16);
|
||||
from_number_impl!(u32, to_u32);
|
||||
from_number_impl!(u64, to_u64);
|
||||
from_number_impl!(usize, to_usize);
|
||||
|
||||
from_number_impl!(i8, to_i8);
|
||||
from_number_impl!(i16, to_i16);
|
||||
from_number_impl!(i32, to_i32);
|
||||
from_number_impl!(i64, to_i64);
|
||||
from_number_impl!(isize, to_isize);
|
||||
|
||||
from_number_impl!(f32, to_f32);
|
||||
from_number_impl!(f64, to_f64);
|
||||
number_trait_impl!(u8, u16, u32, u64, u128, usize);
|
||||
number_trait_impl!(i8, i16, i32, i64, i128, isize);
|
||||
number_trait_impl!(f32, f64);
|
||||
|
||||
69
src/one.rs
69
src/one.rs
@ -1,10 +1,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use std::ops::Mul;
|
||||
use core::ops::{Mul, MulAssign};
|
||||
|
||||
/// Defines a multiplicative identity element for `Self`.
|
||||
pub trait One: Sized + Mul<Self, Output=Self>
|
||||
|
||||
|
||||
/// Defines a multiplicative identity.
|
||||
pub trait One: Sized + PartialEq +
|
||||
Mul<Self, Output=Self> + MulAssign
|
||||
{
|
||||
/// Returns the multiplicative identity element of `Self`, `1`.
|
||||
///
|
||||
@ -14,44 +17,54 @@ pub trait One: Sized + Mul<Self, Output=Self>
|
||||
/// a * 1 = a ∀ a ∈ Self
|
||||
/// 1 * a = a ∀ a ∈ Self
|
||||
/// ```
|
||||
/// [Multiplicative Identity](https://en.wikipedia.org/wiki/1#In_mathematics)
|
||||
///
|
||||
/// # Purity
|
||||
///
|
||||
/// This function should return the same result at all times regardless of
|
||||
/// external mutable state, for example values stored in TLS or in
|
||||
/// `static mut`s.
|
||||
/// This function must be a pure mathematical constant. It should return
|
||||
/// the same result at all times regardless of external mutable state, for
|
||||
/// example values stored in Thread Local Storage(TLS) or in `static mut`s.
|
||||
fn one() -> Self;
|
||||
|
||||
|
||||
/// Returns `true` if the value is the multiplicative identity.
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use sigils::One;
|
||||
///
|
||||
/// let x = 1u32;
|
||||
/// assert!(x.is_one());
|
||||
///
|
||||
/// let y = 5f64;
|
||||
/// assert!(!y.is_one());
|
||||
/// ```
|
||||
#[inline]
|
||||
fn is_one(&self) -> bool
|
||||
{
|
||||
*self == Self::one()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
macro_rules! one_impl
|
||||
{
|
||||
($varType: ty, $val: expr) =>
|
||||
($($varType: ty),*) =>
|
||||
{
|
||||
impl One for $varType
|
||||
{
|
||||
fn one() -> $varType
|
||||
$(
|
||||
impl One for $varType
|
||||
{
|
||||
$val
|
||||
#[inline]
|
||||
fn one() -> Self
|
||||
{ 1 as $varType }
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
one_impl!(u8, 1u8);
|
||||
one_impl!(u16, 1u16);
|
||||
one_impl!(u32, 1u32);
|
||||
one_impl!(u64, 1u64);
|
||||
one_impl!(usize, 1usize);
|
||||
|
||||
one_impl!(i8, 1i8);
|
||||
one_impl!(i16, 1i16);
|
||||
one_impl!(i32, 1i32);
|
||||
one_impl!(i64, 1i64);
|
||||
one_impl!(isize, 1isize);
|
||||
|
||||
one_impl!(f32, 1.0f32);
|
||||
one_impl!(f64, 1.0f64);
|
||||
// Implement the One trait for the basic rust types.
|
||||
one_impl!(u8, u16, u32, u64, u128, usize);
|
||||
one_impl!(i8, i16, i32, i64, i128, isize);
|
||||
one_impl!(f32, f64);
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
@ -17,7 +17,7 @@ use crate::vector::{EuclideanVector, Vector3};
|
||||
|
||||
|
||||
/// A Quaternion is a combination of a scalar and a vector
|
||||
/// of complex numbers.
|
||||
/// of imaginary units.
|
||||
///
|
||||
/// [S, V] = [S, Xi + Yj + Zk]
|
||||
///
|
||||
@ -28,9 +28,9 @@ use crate::vector::{EuclideanVector, Vector3};
|
||||
///
|
||||
/// | | |
|
||||
/// |:-------:|:-------:|
|
||||
/// | ij = 1 | ik = -1 |
|
||||
/// | jk = 1 | kj = -1 |
|
||||
/// | ki = 1 | ji = -1 |
|
||||
/// | ij = k | ji = -k |
|
||||
/// | jk = i | kj = -i |
|
||||
/// | ki = j | ik = -j |
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Quaternion<T>
|
||||
{
|
||||
@ -274,6 +274,11 @@ impl<T> Quaternion<T> where T: Trig
|
||||
/// conjugate of this Quaternion.
|
||||
pub fn invert(&self) -> Quaternion<T>
|
||||
{
|
||||
// This only works for unit quaternions and the normalize here is doing
|
||||
// the heavy lifting of fixing my drift for my skeleton rotations.
|
||||
//
|
||||
// JTS: To reuse this code for other domains, this needs to become the
|
||||
// conjugate divided by the magnitude squared.
|
||||
self.conjugate().normalize()
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
76
src/zero.rs
76
src/zero.rs
@ -1,10 +1,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use std::ops::Add;
|
||||
use core::ops::{Add, AddAssign};
|
||||
|
||||
/// Defines an additive identity element for `Self`.
|
||||
pub trait Zero: Sized + Add<Self, Output=Self>
|
||||
|
||||
|
||||
/// Defines an additive identity.
|
||||
pub trait Zero: Sized + PartialEq +
|
||||
Add<Self, Output=Self> + AddAssign
|
||||
{
|
||||
/// Returns the additive identity element of `Self`, `0`.
|
||||
///
|
||||
@ -14,44 +17,55 @@ pub trait Zero: Sized + Add<Self, Output=Self>
|
||||
/// a + 0 = a ∀ a ∈ Self
|
||||
/// 0 + a = a ∀ a ∈ Self
|
||||
/// ```
|
||||
/// [Additive Identity](https://en.wikipedia.org/wiki/Additive_identity)
|
||||
///
|
||||
/// # Purity
|
||||
///
|
||||
/// This function should return the same result at all times regardless of
|
||||
/// external mutable state, for example values stored in TLS or in
|
||||
/// `static mut`s.
|
||||
/// This function must be a pure mathematical constant. It should return
|
||||
/// the same result at all times regardless of external mutable state, for
|
||||
/// example values stored in Thread Local Storage(TLS) or in `static mut`s.
|
||||
fn zero() -> Self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
macro_rules! zero_impl
|
||||
{
|
||||
($varType: ty, $val: expr) =>
|
||||
/// Returns `true` if the value is the additive identity.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use sigils::Zero;
|
||||
///
|
||||
/// let x = 0u32;
|
||||
/// assert!(x.is_zero());
|
||||
///
|
||||
/// let y = 5u64;
|
||||
/// assert!(!y.is_zero());
|
||||
/// ```
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool
|
||||
{
|
||||
impl Zero for $varType
|
||||
{
|
||||
fn zero() -> $varType
|
||||
{
|
||||
$val
|
||||
}
|
||||
}
|
||||
*self == Self::zero()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
zero_impl!(u8, 0u8);
|
||||
zero_impl!(u16, 0u16);
|
||||
zero_impl!(u32, 0u32);
|
||||
zero_impl!(u64, 0u64);
|
||||
zero_impl!(usize, 0usize);
|
||||
/// A macro to make implementing the `Zero` trait easier for all the
|
||||
/// base types in Rust.
|
||||
macro_rules! zero_impl
|
||||
{
|
||||
($($varType: ty),*) =>
|
||||
{
|
||||
$(
|
||||
impl Zero for $varType
|
||||
{
|
||||
#[inline]
|
||||
fn zero() -> Self
|
||||
{ 0 as $varType }
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
zero_impl!(i8, 0i8);
|
||||
zero_impl!(i16, 0i16);
|
||||
zero_impl!(i32, 0i32);
|
||||
zero_impl!(i64, 0i64);
|
||||
zero_impl!(isize, 0isize);
|
||||
|
||||
zero_impl!(f32, 0.0f32);
|
||||
zero_impl!(f64, 0.0f64);
|
||||
// Implement the Zero trait for the basic rust types.
|
||||
zero_impl!(u8, u16, u32, u64, u128, usize);
|
||||
zero_impl!(i8, i16, i32, i64, i128, isize);
|
||||
zero_impl!(f32, f64);
|
||||
|
||||
@ -1,98 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use std::{f32, f64};
|
||||
use sigils::Constants;
|
||||
|
||||
|
||||
#[test]
|
||||
fn constant_check_f32()
|
||||
{
|
||||
let val: f32 = Constants::SQRT_2;
|
||||
assert_eq!(val, f32::consts::SQRT_2);
|
||||
let val: f32 = Constants::SQRT_3;
|
||||
assert_eq!(val, 1.73205080756887729352f32);
|
||||
let val: f32 = Constants::INVERSE_SQRT_2;
|
||||
assert_eq!(val, 1.0f32 / f32::consts::SQRT_2);
|
||||
let val: f32 = Constants::INVERSE_SQRT_3;
|
||||
assert_eq!(val, 1.0f32 / 1.73205080756887729352f32);
|
||||
|
||||
let val: f32 = Constants::E;
|
||||
assert_eq!(val, f32::consts::E);
|
||||
|
||||
let val: f32 = Constants::LOG2_E;
|
||||
assert_eq!(val, f32::consts::LOG2_E);
|
||||
let val: f32 = Constants::LOG10_E;
|
||||
assert_eq!(val, f32::consts::LOG10_E);
|
||||
let val: f32 = Constants::LOGE_2;
|
||||
assert_eq!(val, 2f32.ln());
|
||||
let val: f32 = Constants::LOGE_10;
|
||||
assert_eq!(val, 10f32.ln());
|
||||
|
||||
let val: f32 = Constants::TWO_PI;
|
||||
assert_eq!(val, 2f32 * f32::consts::PI);
|
||||
let val: f32 = Constants::PI;
|
||||
assert_eq!(val, f32::consts::PI);
|
||||
let val: f32 = Constants::HALF_PI;
|
||||
assert_eq!(val, f32::consts::PI / 2f32);
|
||||
let val: f32 = Constants::THIRD_PI;
|
||||
assert_eq!(val, f32::consts::PI / 3f32);
|
||||
let val: f32 = Constants::QUARTER_PI;
|
||||
assert_eq!(val, f32::consts::PI / 4f32);
|
||||
let val: f32 = Constants::SIXTH_PI;
|
||||
assert_eq!(val, f32::consts::PI / 6f32);
|
||||
let val: f32 = Constants::EIGHTH_PI;
|
||||
assert_eq!(val, f32::consts::PI / 8f32);
|
||||
let val: f32 = Constants::INVERSE_PI;
|
||||
assert_eq!(val, 1.0f32 / f32::consts::PI);
|
||||
let val: f32 = Constants::TWO_INVERSE_PI;
|
||||
assert_eq!(val, 2.0f32 / f32::consts::PI);
|
||||
let val: f32 = Constants::TWO_INVERSE_SQRT_PI;
|
||||
assert_eq!(val, 2.0f32 / (f32::consts::PI).sqrt());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constant_check_f64()
|
||||
{
|
||||
let val: f64 = Constants::SQRT_2;
|
||||
assert_eq!(val, f64::consts::SQRT_2);
|
||||
let val: f64 = Constants::SQRT_3;
|
||||
assert_eq!(val, 1.73205080756887729352f64);
|
||||
let val: f64 = Constants::INVERSE_SQRT_2;
|
||||
assert_eq!(val, 1.0f64 / f64::consts::SQRT_2);
|
||||
let val: f64 = Constants::INVERSE_SQRT_3;
|
||||
assert_eq!(val, 1.0f64 / 1.73205080756887729352f64);
|
||||
|
||||
let val: f64 = Constants::E;
|
||||
assert_eq!(val, f64::consts::E);
|
||||
|
||||
let val: f64 = Constants::LOG2_E;
|
||||
assert_eq!(val, f64::consts::LOG2_E);
|
||||
let val: f64 = Constants::LOG10_E;
|
||||
assert_eq!(val, f64::consts::LOG10_E);
|
||||
let val: f64 = Constants::LOGE_2;
|
||||
assert_eq!(val, 2f64.ln());
|
||||
let val: f64 = Constants::LOGE_10;
|
||||
assert_eq!(val, 10f64.ln());
|
||||
|
||||
let val: f64 = Constants::TWO_PI;
|
||||
assert_eq!(val, 2f64 * f64::consts::PI);
|
||||
let val: f64 = Constants::PI;
|
||||
assert_eq!(val, f64::consts::PI);
|
||||
let val: f64 = Constants::HALF_PI;
|
||||
assert_eq!(val, f64::consts::PI / 2f64);
|
||||
let val: f64 = Constants::THIRD_PI;
|
||||
assert_eq!(val, f64::consts::PI / 3f64);
|
||||
let val: f64 = Constants::QUARTER_PI;
|
||||
assert_eq!(val, f64::consts::PI / 4f64);
|
||||
let val: f64 = Constants::SIXTH_PI;
|
||||
assert_eq!(val, f64::consts::PI / 6f64);
|
||||
let val: f64 = Constants::EIGHTH_PI;
|
||||
assert_eq!(val, f64::consts::PI / 8f64);
|
||||
let val: f64 = Constants::INVERSE_PI;
|
||||
assert_eq!(val, 1.0f64 / f64::consts::PI);
|
||||
let val: f64 = Constants::TWO_INVERSE_PI;
|
||||
assert_eq!(val, 2.0f64 / f64::consts::PI);
|
||||
let val: f64 = Constants::TWO_INVERSE_SQRT_PI;
|
||||
assert_eq!(val, 2.0f64 / (f64::consts::PI).sqrt());
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
mod constants;
|
||||
mod vector;
|
||||
615
tests/vector.rs
615
tests/vector.rs
@ -1,615 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Sealed with Magistamp.
|
||||
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem};
|
||||
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
||||
use sigils::vector::*;
|
||||
|
||||
|
||||
#[test]
|
||||
fn vector_creation()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(1.0f32);
|
||||
|
||||
assert_eq!(v.x, 1.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_add()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(1.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
||||
let scalar: f32 = 4.0f32;
|
||||
|
||||
let v_three = v.add(&v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v.add(v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_sub()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(9.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
||||
let scalar: f32 = 4.0f32;
|
||||
|
||||
let v_three = v.sub(&v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v.sub(v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_mul()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(3.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
||||
let scalar: f32 = 5.0f32;
|
||||
|
||||
let v_three = v.mul(&v_two);
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v.mul(v_two);
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * &v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * &v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * 5.0f32;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * 5.0f32;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * &scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * &scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_div()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
||||
let scalar: f32 = 5.0f32;
|
||||
|
||||
let v_three = v.div(&v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v.div(v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / 5.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / 5.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_rem()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(6.0f32);
|
||||
let scalar: f32 = 6.0f32;
|
||||
|
||||
let v_three = v.rem(&v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v.rem(v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % 6.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % 6.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_add_assign()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(1.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
||||
let scalar: f32 = 4.0f32;
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.add_assign(&v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.add_assign(v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three += &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three += v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three += 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three += scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three += &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_sub_assign()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(9.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
||||
let scalar: f32 = 4.0f32;
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.sub_assign(&v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.sub_assign(v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three -= &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three -= v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three -= 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three -= scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three -= &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_mul_assign()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(3.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
||||
let scalar: f32 = 5.0f32;
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.mul_assign(&v_two);
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.mul_assign(v_two);
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three *= &v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three *= v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three *= 5.0f32;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three*= scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three *= &scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_div_assign()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
||||
let scalar: f32 = 5.0f32;
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.div_assign(&v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.div_assign(v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three /= &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three /= v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three /= 5.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three /= scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three /= &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_rem_assign()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(6.0f32);
|
||||
let scalar: f32 = 6.0f32;
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.rem_assign(&v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three.rem_assign(v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three %= &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three %= v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three %= 6.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three %= scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let mut v_three = v.clone();
|
||||
v_three %= &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
}
|
||||
Reference in New Issue
Block a user