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 });