cvmath/
bools.rs

1/*!
2Boolean vectors.
3
4## Comparison masks
5
6Comparison masks are boolean vectors to be consumed by `select`.
7
8`is_finite(self)`: Creates a mask for finite components.
9
10`is_infinite(self)`: Creates a mask for infinite components.
11
12`eq(self, rhs)`: Creates a mask for equal components.
13
14`ne(self, rhs)`: Creates a mask for unequal components.
15
16`lt(self, rhs)`: Creates a mask for left-hand side components are less than the right-hand side.
17
18`le(self, rhs)`: Creates a mask for left-hand side components are less than or equal the right-hand side.
19
20`gt(self, rhs)`: Creates a mask for left-hand side components are greater than the right-hand side.
21
22`ge(self, rhs)`: Creates a mask for left-hand side components are greater than or equal the right-hand side.
23
24`is_close(self, rhs)`: Creates a mask for approximately equal components.
25
26`all_close(self, rhs)`: Equivalent to `self.is_close(rhs).all()`.
27
28### Examples
29
30```
31use cvmath::{Vec2, Bool2};
32
33assert_eq!(Bool2 { x: true, y: false }, Vec2(1, 2).eq(Vec2(1, -2)));
34```
35
36## Comparison operators
37
38`any(self)`: Returns `true` if any of the components are `true`.
39
40`all(self)`: Returns `true` if all the components are `true`.
41
42`none(self)`: Returns `true` if none of the components are `true`.
43
44`select(self, lhs, rhs)`: Combines two vectors based on the bools, selecting components from the left-hand side if `true` and right-hand side if `false`.
45
46### Examples
47
48```
49use cvmath::{Bool2};
50
51assert!(Bool2 { x: true, y: false }.any());
52assert!(Bool2 { x: true, y: true }.all());
53assert!(Bool2 { x: false, y: false }.none());
54```
55
56*/
57
58use super::*;
59
60/// Bool2 mask.
61pub type Bool2 = Vec2<bool>;
62/// Bool3 mask.
63pub type Bool3 = Vec3<bool>;
64/// Bool4 mask.
65pub type Bool4 = Vec4<bool>;
66
67macro_rules! bools {
68	($bools:ident $vec:ident { $($field:ident),+ }) => {
69
70		#[doc = stringify!($bools)]
71		#[doc = " constructor."]
72		#[allow(non_snake_case)]
73		#[inline]
74		pub const fn $bools($($field: bool),+) -> $bools {
75			$bools { $($field),+ }
76		}
77
78		//----------------------------------------------------------------
79		// Comparison masks
80
81		impl<T> $vec<T> {
82			/// Creates a mask for finite components.
83			#[inline]
84			pub fn is_finite(self) -> $bools where T: Float {
85				$vec { $($field: self.$field.is_finite()),+ }
86			}
87			/// Creates a mask for infinite components.
88			#[inline]
89			pub fn is_infinite(self) -> $bools where T: Float {
90				$vec { $($field: self.$field.is_infinite()),+ }
91			}
92			/// Creates a mask for equal components.
93			#[inline]
94			pub fn eq(self, rhs: $vec<T>) -> $bools where T: PartialEq {
95				$vec { $($field: self.$field == rhs.$field),+ }
96			}
97			/// Creates a mask for inequal components.
98			#[inline]
99			pub fn ne(self, rhs: $vec<T>) -> $bools where T: PartialEq {
100				$vec { $($field: self.$field != rhs.$field),+ }
101			}
102			/// Creates a mask for left-hand side components are less than the right-hand side.
103			#[inline]
104			pub fn lt(self, rhs: $vec<T>) -> $bools where T: PartialOrd {
105				$vec { $($field: self.$field < rhs.$field),+ }
106			}
107			/// Creates a mask for left-hand side components are less than or equal the right-hand side.
108			#[inline]
109			pub fn le(self, rhs: $vec<T>) -> $bools where T: PartialOrd {
110				$vec { $($field: self.$field <= rhs.$field),+ }
111			}
112			/// Creates a mask for left-hand side components are greater than the right-hand side.
113			#[inline]
114			pub fn gt(self, rhs: $vec<T>) -> $bools where T: PartialOrd {
115				$vec { $($field: self.$field > rhs.$field),+ }
116			}
117			/// Creates a mask for left-hand side components are greater than or equal the right-hand side.
118			#[inline]
119			pub fn ge(self, rhs: $vec<T>) -> $bools where T: PartialOrd {
120				$vec { $($field: self.$field >= rhs.$field),+ }
121			}
122		}
123
124		impl<T> $vec<T> {
125			/// Creates a mask for approximately equal components.
126			#[inline]
127			pub fn is_close(self, rhs: $vec<T>) -> $bools where T: Float {
128				$vec { $($field: self.$field.is_close(rhs.$field)),+ }
129			}
130			/// Returns true if the values are approximately equal.
131			#[inline]
132			pub fn all_close(self, rhs: $vec<T>) -> bool where T: Float {
133				self.is_close(rhs).all()
134			}
135		}
136
137		//----------------------------------------------------------------
138		// Comparison operators
139
140		impl $bools {
141			/// Returns `true` if any of the components are `true`.
142			#[inline]
143			pub const fn any(self) -> bool {
144				infix!(| $(self.$field),+)
145			}
146			/// Returns `true` if all the components are `true`.
147			#[inline]
148			pub const fn all(self) -> bool {
149				infix!(& $(self.$field),+)
150			}
151			/// Returns `true` if none of the components are `true`.
152			#[inline]
153			pub const fn none(self) -> bool {
154				!self.any()
155			}
156			/// Combines two vectors based on the bools, selecting components from the left-hand side if `true` and right-hand side if `false`.
157			#[inline]
158			pub fn select<T>(self, lhs: $vec<T>, rhs: $vec<T>) -> $vec<T> {
159				$vec { $($field: if self.$field { lhs.$field } else { rhs.$field }),+ }
160			}
161		}
162
163		//----------------------------------------------------------------
164		// Bitwise operators
165
166		impl<U, T: ops::BitAnd<U>> ops::BitAnd<$vec<U>> for $vec<T> {
167			type Output = $vec<T::Output>;
168			#[inline]
169			fn bitand(self, rhs: $vec<U>) -> $vec<T::Output> {
170				$vec { $($field: self.$field & rhs.$field),+ }
171			}
172		}
173		impl<U, T: ops::BitOr<U>> ops::BitOr<$vec<U>> for $vec<T> {
174			type Output = $vec<T::Output>;
175			#[inline]
176			fn bitor(self, rhs: $vec<U>) -> $vec<T::Output> {
177				$vec { $($field: self.$field | rhs.$field),+ }
178			}
179		}
180		impl<U, T: ops::BitXor<U>> ops::BitXor<$vec<U>> for $vec<T> {
181			type Output = $vec<T::Output>;
182			#[inline]
183			fn bitxor(self, rhs: $vec<U>) -> $vec<T::Output> {
184				$vec { $($field: self.$field ^ rhs.$field),+ }
185			}
186		}
187		impl<T: ops::Not> ops::Not for $vec<T> {
188			type Output = $vec<T::Output>;
189			#[inline]
190			fn not(self) -> $vec<T::Output> {
191				$vec { $($field: !self.$field),+ }
192			}
193		}
194	};
195}
196
197bools!(Bool2 Vec2 { x, y });
198bools!(Bool3 Vec3 { x, y, z });
199bools!(Bool4 Vec4 { x, y, z, w });