Repository: bitshifter/glam-rs
Pull request #482 (2024-03-03 10:08:59)

Add from array for boolean vectors.


Patch:
diff --git a/codegen/templates/vec_mask.rs.tera b/codegen/templates/vec_mask.rs.tera
index 4cc8575..2f2970e 100644
--- a/codegen/templates/vec_mask.rs.tera
+++ b/codegen/templates/vec_mask.rs.tera
@@ -130,7 +130,7 @@ impl {{ self_t }} {
         {% endif %}
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
@@ -141,6 +141,17 @@ impl {{ self_t }} {
         )
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; {{ dim }}]) -> Self {
+        Self::new(
+            {% for c in components %}
+                a[{{ loop.index0 }}],
+            {%- endfor %}
+        )
+    }
+
     /// Returns a bitmask with the lowest {{ dim }} bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -499,6 +510,13 @@ impl fmt::Display for {{ self_t }} {
     }
 }
 
+impl From<[bool; {{ dim }}]> for {{ self_t }} {
+    #[inline]
+    fn from(a: [bool; {{ dim }}]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<{{ self_t }}> for [bool; {{ dim }}] {
     #[inline]
     fn from(mask: {{ self_t }}) -> Self {
diff --git a/src/bool/bvec2.rs b/src/bool/bvec2.rs
index e4fe0c0..3fc13b1 100644
--- a/src/bool/bvec2.rs
+++ b/src/bool/bvec2.rs
@@ -28,13 +28,20 @@ impl BVec2 {
         Self { x, y }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 2]) -> Self {
+        Self::new(a[0], a[1])
+    }
+
     /// Returns a bitmask with the lowest 2 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -185,6 +192,13 @@ impl fmt::Display for BVec2 {
     }
 }
 
+impl From<[bool; 2]> for BVec2 {
+    #[inline]
+    fn from(a: [bool; 2]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec2> for [bool; 2] {
     #[inline]
     fn from(mask: BVec2) -> Self {
diff --git a/src/bool/bvec3.rs b/src/bool/bvec3.rs
index 983cd3f..2f33cd1 100644
--- a/src/bool/bvec3.rs
+++ b/src/bool/bvec3.rs
@@ -29,13 +29,20 @@ impl BVec3 {
         Self { x, y, z }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 3]) -> Self {
+        Self::new(a[0], a[1], a[2])
+    }
+
     /// Returns a bitmask with the lowest 3 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -203,6 +210,13 @@ impl fmt::Display for BVec3 {
     }
 }
 
+impl From<[bool; 3]> for BVec3 {
+    #[inline]
+    fn from(a: [bool; 3]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec3> for [bool; 3] {
     #[inline]
     fn from(mask: BVec3) -> Self {
diff --git a/src/bool/bvec4.rs b/src/bool/bvec4.rs
index b1e9144..2300a4a 100644
--- a/src/bool/bvec4.rs
+++ b/src/bool/bvec4.rs
@@ -30,13 +30,20 @@ impl BVec4 {
         Self { x, y, z, w }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 4]) -> Self {
+        Self::new(a[0], a[1], a[2], a[3])
+    }
+
     /// Returns a bitmask with the lowest 4 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -212,6 +219,13 @@ impl fmt::Display for BVec4 {
     }
 }
 
+impl From<[bool; 4]> for BVec4 {
+    #[inline]
+    fn from(a: [bool; 4]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec4> for [bool; 4] {
     #[inline]
     fn from(mask: BVec4) -> Self {
diff --git a/src/bool/coresimd/bvec3a.rs b/src/bool/coresimd/bvec3a.rs
index 5167672..080f3bd 100644
--- a/src/bool/coresimd/bvec3a.rs
+++ b/src/bool/coresimd/bvec3a.rs
@@ -40,13 +40,20 @@ impl BVec3A {
         }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 3]) -> Self {
+        Self::new(a[0], a[1], a[2])
+    }
+
     /// Returns a bitmask with the lowest 3 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -213,6 +220,13 @@ impl fmt::Display for BVec3A {
     }
 }
 
+impl From<[bool; 3]> for BVec3A {
+    #[inline]
+    fn from(a: [bool; 3]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec3A> for [bool; 3] {
     #[inline]
     fn from(mask: BVec3A) -> Self {
diff --git a/src/bool/coresimd/bvec4a.rs b/src/bool/coresimd/bvec4a.rs
index 123a003..a1213b0 100644
--- a/src/bool/coresimd/bvec4a.rs
+++ b/src/bool/coresimd/bvec4a.rs
@@ -45,13 +45,20 @@ impl BVec4A {
         }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 4]) -> Self {
+        Self::new(a[0], a[1], a[2], a[3])
+    }
+
     /// Returns a bitmask with the lowest 4 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -225,6 +232,13 @@ impl fmt::Display for BVec4A {
     }
 }
 
+impl From<[bool; 4]> for BVec4A {
+    #[inline]
+    fn from(a: [bool; 4]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec4A> for [bool; 4] {
     #[inline]
     fn from(mask: BVec4A) -> Self {
diff --git a/src/bool/scalar/bvec3a.rs b/src/bool/scalar/bvec3a.rs
index f2dc95f..28c9f45 100644
--- a/src/bool/scalar/bvec3a.rs
+++ b/src/bool/scalar/bvec3a.rs
@@ -33,13 +33,20 @@ impl BVec3A {
         }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 3]) -> Self {
+        Self::new(a[0], a[1], a[2])
+    }
+
     /// Returns a bitmask with the lowest 3 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -207,6 +214,13 @@ impl fmt::Display for BVec3A {
     }
 }
 
+impl From<[bool; 3]> for BVec3A {
+    #[inline]
+    fn from(a: [bool; 3]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec3A> for [bool; 3] {
     #[inline]
     fn from(mask: BVec3A) -> Self {
diff --git a/src/bool/scalar/bvec4a.rs b/src/bool/scalar/bvec4a.rs
index bdf8884..eaf6572 100644
--- a/src/bool/scalar/bvec4a.rs
+++ b/src/bool/scalar/bvec4a.rs
@@ -35,13 +35,20 @@ impl BVec4A {
         }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 4]) -> Self {
+        Self::new(a[0], a[1], a[2], a[3])
+    }
+
     /// Returns a bitmask with the lowest 4 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -217,6 +224,13 @@ impl fmt::Display for BVec4A {
     }
 }
 
+impl From<[bool; 4]> for BVec4A {
+    #[inline]
+    fn from(a: [bool; 4]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec4A> for [bool; 4] {
     #[inline]
     fn from(mask: BVec4A) -> Self {
diff --git a/src/bool/sse2/bvec3a.rs b/src/bool/sse2/bvec3a.rs
index 0ac65a5..6ef1aa3 100644
--- a/src/bool/sse2/bvec3a.rs
+++ b/src/bool/sse2/bvec3a.rs
@@ -43,13 +43,20 @@ impl BVec3A {
         }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 3]) -> Self {
+        Self::new(a[0], a[1], a[2])
+    }
+
     /// Returns a bitmask with the lowest 3 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -224,6 +231,13 @@ impl fmt::Display for BVec3A {
     }
 }
 
+impl From<[bool; 3]> for BVec3A {
+    #[inline]
+    fn from(a: [bool; 3]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec3A> for [bool; 3] {
     #[inline]
     fn from(mask: BVec3A) -> Self {
diff --git a/src/bool/sse2/bvec4a.rs b/src/bool/sse2/bvec4a.rs
index 18f8a03..e9fe1ce 100644
--- a/src/bool/sse2/bvec4a.rs
+++ b/src/bool/sse2/bvec4a.rs
@@ -48,13 +48,20 @@ impl BVec4A {
         }
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 4]) -> Self {
+        Self::new(a[0], a[1], a[2], a[3])
+    }
+
     /// Returns a bitmask with the lowest 4 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -237,6 +244,13 @@ impl fmt::Display for BVec4A {
     }
 }
 
+impl From<[bool; 4]> for BVec4A {
+    #[inline]
+    fn from(a: [bool; 4]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec4A> for [bool; 4] {
     #[inline]
     fn from(mask: BVec4A) -> Self {
diff --git a/src/bool/wasm32/bvec3a.rs b/src/bool/wasm32/bvec3a.rs
index a634670..4a4bb2c 100644
--- a/src/bool/wasm32/bvec3a.rs
+++ b/src/bool/wasm32/bvec3a.rs
@@ -34,13 +34,20 @@ impl BVec3A {
         ))
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 3]) -> Self {
+        Self::new(a[0], a[1], a[2])
+    }
+
     /// Returns a bitmask with the lowest 3 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -215,6 +222,13 @@ impl fmt::Display for BVec3A {
     }
 }
 
+impl From<[bool; 3]> for BVec3A {
+    #[inline]
+    fn from(a: [bool; 3]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec3A> for [bool; 3] {
     #[inline]
     fn from(mask: BVec3A) -> Self {
diff --git a/src/bool/wasm32/bvec4a.rs b/src/bool/wasm32/bvec4a.rs
index 3813354..115e8e9 100644
--- a/src/bool/wasm32/bvec4a.rs
+++ b/src/bool/wasm32/bvec4a.rs
@@ -34,13 +34,20 @@ impl BVec4A {
         ))
     }
 
-    /// Creates a vector with all elements set to `v`.
+    /// Creates a vector mask with all elements set to `v`.
     #[inline]
     #[must_use]
     pub const fn splat(v: bool) -> Self {
         Self::new(v, v, v, v)
     }
 
+    /// Creates a new vector mask from a bool array.
+    #[inline]
+    #[must_use]
+    pub const fn from_array(a: [bool; 4]) -> Self {
+        Self::new(a[0], a[1], a[2], a[3])
+    }
+
     /// Returns a bitmask with the lowest 4 bits set from the elements of `self`.
     ///
     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
@@ -223,6 +230,13 @@ impl fmt::Display for BVec4A {
     }
 }
 
+impl From<[bool; 4]> for BVec4A {
+    #[inline]
+    fn from(a: [bool; 4]) -> Self {
+        Self::from_array(a)
+    }
+}
+
 impl From<BVec4A> for [bool; 4] {
     #[inline]
     fn from(mask: BVec4A) -> Self {


Test patch:
diff --git a/tests/vec2.rs b/tests/vec2.rs
index 2ad1cd4..fd176c9 100644
--- a/tests/vec2.rs
+++ b/tests/vec2.rs
@@ -261,6 +261,13 @@ macro_rules! impl_vec2_tests {
             assert!(b.cmpeq($vec2::splat(1 as $t)).all());
         });
 
+        glam_test!(test_mask_from_array_bool, {
+            assert_eq!($mask::new(false, false), $mask::from([false, false]));
+            assert_eq!($mask::new(true, false), $mask::from([true, false]));
+            assert_eq!($mask::new(false, true), $mask::from([false, true]));
+            assert_eq!($mask::new(true, true), $mask::from([true, true]));
+        });
+
         glam_test!(test_mask_into_array_u32, {
             assert_eq!(Into::<[u32; 2]>::into($mask::new(false, false)), [0, 0]);
             assert_eq!(Into::<[u32; 2]>::into($mask::new(true, false)), [!0, 0]);
diff --git a/tests/vec3.rs b/tests/vec3.rs
index 3b4c2a4..89e4f22 100644
--- a/tests/vec3.rs
+++ b/tests/vec3.rs
@@ -279,6 +279,33 @@ macro_rules! impl_vec3_tests {
             assert!(a.cmpeq($vec3::ONE).all());
         });
 
+        glam_test!(test_mask_from_array_bool, {
+            assert_eq!(
+                $mask::new(false, false, false),
+                $mask::from([false, false, false])
+            );
+            assert_eq!(
+                $mask::new(true, false, false),
+                $mask::from([true, false, false])
+            );
+            assert_eq!(
+                $mask::new(false, true, true),
+                $mask::from([false, true, true])
+            );
+            assert_eq!(
+                $mask::new(false, true, false),
+                $mask::from([false, true, false])
+            );
+            assert_eq!(
+                $mask::new(true, false, true),
+                $mask::from([true, false, true])
+            );
+            assert_eq!(
+                $mask::new(true, true, true),
+                $mask::from([true, true, true])
+            );
+        });
+
         glam_test!(test_mask_into_array_u32, {
             assert_eq!(
                 Into::<[u32; 3]>::into($mask::new(false, false, false)),
@@ -328,8 +355,8 @@ macro_rules! impl_vec3_tests {
                 [true, false, true]
             );
             assert_eq!(
-                Into::<[u32; 3]>::into($mask::new(true, true, true)),
-                [!0, !0, !0]
+                Into::<[bool; 3]>::into($mask::new(true, true, true)),
+                [true, true, true]
             );
         });
 
diff --git a/tests/vec4.rs b/tests/vec4.rs
index 05fd72f..917eb4b 100644
--- a/tests/vec4.rs
+++ b/tests/vec4.rs
@@ -356,6 +356,32 @@ macro_rules! impl_vec4_tests {
             should_panic!({ $vec4::from_slice(&[0 as $t; 3]) });
         });
 
+        glam_test!(test_mask_from_array_bool, {
+            assert_eq!(
+                $mask::new(false, false, false, false),
+                $mask::from([false, false, false, false])
+            );
+            assert_eq!(
+                $mask::new(false, false, true, true),
+                $mask::from([false, false, true, true])
+            );
+            assert_eq!(
+                $mask::new(true, true, false, false),
+                $mask::from([true, true, false, false])
+            );
+            assert_eq!(
+                $mask::new(false, true, false, true),
+                $mask::from([false, true, false, true])
+            );
+            assert_eq!(
+                $mask::new(true, false, true, false),
+                $mask::from([true, false, true, false])
+            );
+            assert_eq!(
+                $mask::new(true, true, true, true),
+                $mask::from([true, true, true, true])
+            );
+        });
         glam_test!(test_mask_into_array_u32, {
             assert_eq!(
                 Into::<[u32; 4]>::into($mask::new(false, false, false, false)),