Trait Wrap

Source
pub trait Wrap<Bound = Self>: Sized {
    // Required methods
    fn wrapped(self, upper: Bound) -> Self;
    fn wrapped_between(self, lower: Bound, upper: Bound) -> Self;
    fn pingpong(self, upper: Bound) -> Self;

    // Provided methods
    fn wrap(val: Self, upper: Bound) -> Self { ... }
    fn wrapped_2pi(self) -> Self
       where Bound: FloatConst + Add<Output = Bound> { ... }
    fn wrap_2pi(val: Self) -> Self
       where Bound: FloatConst + Add<Output = Bound> { ... }
    fn wrap_between(val: Self, lower: Bound, upper: Bound) -> Self
       where Self: Sub<Output = Self> + Add<Output = Self> + From<Bound>,
             Bound: Copy + Sub<Output = Bound> + PartialOrd { ... }
    fn delta_angle(self, target: Self) -> Self
       where Self: From<Bound> + Sub<Output = Self> + PartialOrd,
             Bound: FloatConst + Add<Output = Bound> { ... }
    fn delta_angle_degrees(self, target: Self) -> Self
       where Self: From<Bound> + Sub<Output = Self> + PartialOrd,
             Bound: From<u16> { ... }
}
Expand description

A value that can wrap itself around given bounds.

Required Methods§

Source

fn wrapped(self, upper: Bound) -> Self

Returns this value, wrapped between zero and some upper bound (both inclusive).

The computation is self - (self/upper).floor() * upper.

This might look like the remainder (%) operator, but behaves differently with negative values.

If you’re familiar with Unity, this is the Mathf.Repeat() function.

§Panics

Panics if upper <= 0. Reasons include :

  • Some types may implement it as self.wrapped_between(zero, upper). A negative upper would violate the lower <= upper requirement in this case;
  • On unsigned integers, this just resolves to self % upper, and integer division by zero is forbidden. Testing for i==0 incurs unnecessary overhead.
  • Handling negative upper values would double the number of test cases and increases implementation complexity;
use vek::ops::Wrap;

assert_eq!((-5_i32).wrapped(3), 1);
assert_eq!((-4_i32).wrapped(3), 2);
assert_eq!((-3_i32).wrapped(3), 0);
assert_eq!((-2_i32).wrapped(3), 1);
assert_eq!((-1_i32).wrapped(3), 2);
assert_eq!(0_i32.wrapped(3), 0);
assert_eq!(1_i32.wrapped(3), 1);
assert_eq!(2_i32.wrapped(3), 2);
assert_eq!(3_i32.wrapped(3), 0);
assert_eq!(4_i32.wrapped(3), 1);
assert_eq!(5_i32.wrapped(3), 2);
Source

fn wrapped_between(self, lower: Bound, upper: Bound) -> Self

Returns this value, wrapped between lower (inclusive) and upper (exclusive).

§Panics

Panics if lower >= upper. Swap the values yourself if necessary.

Also panics if lower < 0 or upper <= 0. See wrapped() for a rationale. Forcing lower and upper to be positive allows implementations to be simpler and faster.

use vek::ops::Wrap;

assert_eq!((-4_i32).wrapped_between(2, 5), 2);
assert_eq!((-3_i32).wrapped_between(2, 5), 3);
assert_eq!((-2_i32).wrapped_between(2, 5), 4);
assert_eq!((-1_i32).wrapped_between(2, 5), 2);
assert_eq!(  0_i32 .wrapped_between(2, 5), 3);
assert_eq!(  1_i32 .wrapped_between(2, 5), 4);
assert_eq!(  2_i32 .wrapped_between(2, 5), 2);
assert_eq!(  3_i32 .wrapped_between(2, 5), 3);
assert_eq!(  4_i32 .wrapped_between(2, 5), 4);
assert_eq!(  5_i32 .wrapped_between(2, 5), 2);
assert_eq!(  6_i32 .wrapped_between(2, 5), 3);
Source

fn pingpong(self, upper: Bound) -> Self

Wraps a value such that it goes back and forth from zero to upper (inclusive) as it increases.

§Panics

Panics if upper <= 0. See wrapped() for a rationale.

use vek::ops::Wrap;

assert_eq!((-4_i32).pingpong(3), 2);
assert_eq!((-3_i32).pingpong(3), 3);
assert_eq!((-2_i32).pingpong(3), 2);
assert_eq!((-1_i32).pingpong(3), 1);
assert_eq!(  0_i32 .pingpong(3), 0);
assert_eq!(  1_i32 .pingpong(3), 1);
assert_eq!(  2_i32 .pingpong(3), 2);
assert_eq!(  3_i32 .pingpong(3), 3);
assert_eq!(  4_i32 .pingpong(3), 2);
assert_eq!(  5_i32 .pingpong(3), 1);
assert_eq!(  6_i32 .pingpong(3), 0);
assert_eq!(  7_i32 .pingpong(3), 1);

Provided Methods§

Source

fn wrap(val: Self, upper: Bound) -> Self

Alias to wrapped() which doesn’t take self.

§Panics

Panics if upper <= 0. See wrapped() for a rationale.

Source

fn wrapped_2pi(self) -> Self
where Bound: FloatConst + Add<Output = Bound>,

Returns this value, wrapped between zero and two times 𝛑 (inclusive).

This ought to be named wrapped_tau, but I assume people are more familiar with 𝛑, and 2pi is therefore more evocative.

Source

fn wrap_2pi(val: Self) -> Self
where Bound: FloatConst + Add<Output = Bound>,

Alias to wrapped_2pi which doesn’t take self.

This ought to be named wrap_tau, but I assume people are more familiar with 𝛑, and 2pi is therefore more evocative.

Source

fn wrap_between(val: Self, lower: Bound, upper: Bound) -> Self
where Self: Sub<Output = Self> + Add<Output = Self> + From<Bound>, Bound: Copy + Sub<Output = Bound> + PartialOrd,

Alias to wrapped_between which doesn’t take self.

§Panics

Panics if lower is greater than upper. Swap the values yourself if necessary.

Source

fn delta_angle(self, target: Self) -> Self
where Self: From<Bound> + Sub<Output = Self> + PartialOrd, Bound: FloatConst + Add<Output = Bound>,

Calculates the shortest difference between two given angles, in radians.

Source

fn delta_angle_degrees(self, target: Self) -> Self
where Self: From<Bound> + Sub<Output = Self> + PartialOrd, Bound: From<u16>,

Calculates the shortest difference between two given angles, in degrees.

This exists because it’s enough for Bound to implement From<u16>.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl Wrap for f32

Source§

fn wrapped(self, upper: f32) -> f32

Source§

fn wrapped_between(self, lower: f32, upper: f32) -> f32

Source§

fn pingpong(self, upper: f32) -> f32

Source§

impl Wrap for f64

Source§

fn wrapped(self, upper: f64) -> f64

Source§

fn wrapped_between(self, lower: f64, upper: f64) -> f64

Source§

fn pingpong(self, upper: f64) -> f64

Source§

impl Wrap for i8

Source§

fn wrapped_between(self, lower: i8, upper: i8) -> i8

Source§

fn wrapped(self, upper: i8) -> i8

Source§

fn pingpong(self, upper: i8) -> i8

Source§

impl Wrap for i16

Source§

fn wrapped_between(self, lower: i16, upper: i16) -> i16

Source§

fn wrapped(self, upper: i16) -> i16

Source§

fn pingpong(self, upper: i16) -> i16

Source§

impl Wrap for i32

Source§

fn wrapped_between(self, lower: i32, upper: i32) -> i32

Source§

fn wrapped(self, upper: i32) -> i32

Source§

fn pingpong(self, upper: i32) -> i32

Source§

impl Wrap for i64

Source§

fn wrapped_between(self, lower: i64, upper: i64) -> i64

Source§

fn wrapped(self, upper: i64) -> i64

Source§

fn pingpong(self, upper: i64) -> i64

Source§

impl Wrap for isize

Source§

fn wrapped_between(self, lower: isize, upper: isize) -> isize

Source§

fn wrapped(self, upper: isize) -> isize

Source§

fn pingpong(self, upper: isize) -> isize

Source§

impl Wrap for u8

Source§

fn wrapped_between(self, lower: u8, upper: u8) -> u8

Source§

fn wrapped(self, upper: u8) -> u8

Source§

fn pingpong(self, upper: u8) -> u8

Source§

impl Wrap for u16

Source§

fn wrapped_between(self, lower: u16, upper: u16) -> u16

Source§

fn wrapped(self, upper: u16) -> u16

Source§

fn pingpong(self, upper: u16) -> u16

Source§

impl Wrap for u32

Source§

fn wrapped_between(self, lower: u32, upper: u32) -> u32

Source§

fn wrapped(self, upper: u32) -> u32

Source§

fn pingpong(self, upper: u32) -> u32

Source§

impl Wrap for u64

Source§

fn wrapped_between(self, lower: u64, upper: u64) -> u64

Source§

fn wrapped(self, upper: u64) -> u64

Source§

fn pingpong(self, upper: u64) -> u64

Source§

impl Wrap for usize

Source§

fn wrapped_between(self, lower: usize, upper: usize) -> usize

Source§

fn wrapped(self, upper: usize) -> usize

Source§

fn pingpong(self, upper: usize) -> usize

Source§

impl Wrap for Wrapping<i8>

Source§

fn wrapped_between( self, lower: Wrapping<i8>, upper: Wrapping<i8>, ) -> Wrapping<i8>

Source§

fn wrapped(self, upper: Wrapping<i8>) -> Wrapping<i8>

Source§

fn pingpong(self, upper: Wrapping<i8>) -> Wrapping<i8>

Source§

impl Wrap for Wrapping<i16>

Source§

fn wrapped_between( self, lower: Wrapping<i16>, upper: Wrapping<i16>, ) -> Wrapping<i16>

Source§

fn wrapped(self, upper: Wrapping<i16>) -> Wrapping<i16>

Source§

fn pingpong(self, upper: Wrapping<i16>) -> Wrapping<i16>

Source§

impl Wrap for Wrapping<i32>

Source§

fn wrapped_between( self, lower: Wrapping<i32>, upper: Wrapping<i32>, ) -> Wrapping<i32>

Source§

fn wrapped(self, upper: Wrapping<i32>) -> Wrapping<i32>

Source§

fn pingpong(self, upper: Wrapping<i32>) -> Wrapping<i32>

Source§

impl Wrap for Wrapping<i64>

Source§

fn wrapped_between( self, lower: Wrapping<i64>, upper: Wrapping<i64>, ) -> Wrapping<i64>

Source§

fn wrapped(self, upper: Wrapping<i64>) -> Wrapping<i64>

Source§

fn pingpong(self, upper: Wrapping<i64>) -> Wrapping<i64>

Source§

impl Wrap for Wrapping<isize>

Source§

impl Wrap for Wrapping<u8>

Source§

fn wrapped_between( self, lower: Wrapping<u8>, upper: Wrapping<u8>, ) -> Wrapping<u8>

Source§

fn wrapped(self, upper: Wrapping<u8>) -> Wrapping<u8>

Source§

fn pingpong(self, upper: Wrapping<u8>) -> Wrapping<u8>

Source§

impl Wrap for Wrapping<u16>

Source§

fn wrapped_between( self, lower: Wrapping<u16>, upper: Wrapping<u16>, ) -> Wrapping<u16>

Source§

fn wrapped(self, upper: Wrapping<u16>) -> Wrapping<u16>

Source§

fn pingpong(self, upper: Wrapping<u16>) -> Wrapping<u16>

Source§

impl Wrap for Wrapping<u32>

Source§

fn wrapped_between( self, lower: Wrapping<u32>, upper: Wrapping<u32>, ) -> Wrapping<u32>

Source§

fn wrapped(self, upper: Wrapping<u32>) -> Wrapping<u32>

Source§

fn pingpong(self, upper: Wrapping<u32>) -> Wrapping<u32>

Source§

impl Wrap for Wrapping<u64>

Source§

fn wrapped_between( self, lower: Wrapping<u64>, upper: Wrapping<u64>, ) -> Wrapping<u64>

Source§

fn wrapped(self, upper: Wrapping<u64>) -> Wrapping<u64>

Source§

fn pingpong(self, upper: Wrapping<u64>) -> Wrapping<u64>

Source§

impl Wrap for Wrapping<usize>

Implementors§

Source§

impl<T> Wrap for Extent2<T>
where T: Wrap,

Source§

impl<T> Wrap for Extent3<T>
where T: Wrap,

Source§

impl<T> Wrap for Rgb<T>
where T: Wrap,

Source§

impl<T> Wrap for Rgba<T>
where T: Wrap,

Source§

impl<T> Wrap for Vec2<T>
where T: Wrap,

Source§

impl<T> Wrap for Vec3<T>
where T: Wrap,

Source§

impl<T> Wrap for Vec4<T>
where T: Wrap,

Source§

impl<T> Wrap<T> for Extent2<T>
where T: Wrap + Copy,

Source§

impl<T> Wrap<T> for Extent3<T>
where T: Wrap + Copy,

Source§

impl<T> Wrap<T> for Rgb<T>
where T: Wrap + Copy,

Source§

impl<T> Wrap<T> for Rgba<T>
where T: Wrap + Copy,

Source§

impl<T> Wrap<T> for Vec2<T>
where T: Wrap + Copy,

Source§

impl<T> Wrap<T> for Vec3<T>
where T: Wrap + Copy,

Source§

impl<T> Wrap<T> for Vec4<T>
where T: Wrap + Copy,