about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlbin Hedman <albin9604@gmail.com>2020-11-26 23:22:36 +0100
committerAlbin Hedman <albin9604@gmail.com>2020-11-26 23:22:36 +0100
commit3b8617b9b6718f04d412ffae52337053e79c3c6b (patch)
tree58c61e6ba7244c5b3ac16c188b436f97dc4de1bf
parent72da5a9d85a522b11e80d0fdd1fd95247d442604 (diff)
downloadrust-3b8617b9b6718f04d412ffae52337053e79c3c6b.tar.gz
rust-3b8617b9b6718f04d412ffae52337053e79c3c6b.zip
Added [T; N]::zip()
-rw-r--r--library/core/src/array/mod.rs28
-rw-r--r--library/core/tests/array.rs8
-rw-r--r--library/core/tests/lib.rs1
3 files changed, 37 insertions, 0 deletions
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index a7cb1023229..02b771863e9 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -463,6 +463,34 @@ impl<T, const N: usize> [T; N] {
         unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) }
     }
 
+    /// 'Zips up' two arrays into a single array of pairs.
+    /// `zip()` returns a new array where every element is a tuple where the first element comes from the first array, and the second element comes from the second array.
+    /// In other words, it zips two arrays together, into a single one.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(array_zip)]
+    /// let x = [1, 2, 3];
+    /// let y = [4, 5, 6];
+    /// let z = x.zip(y);
+    /// assert_eq!(z, [(1, 4), (2, 5), (3, 6)]);
+    /// ```
+    #[unstable(feature = "array_zip", issue = "none")]
+    pub fn zip<U>(self, rhs: [U; N]) -> [(T, U); N] {
+        use crate::mem::MaybeUninit;
+
+        let mut dst = MaybeUninit::uninit_array::<N>();
+        for ((lhs, rhs), dst) in IntoIter::new(self).zip(IntoIter::new(rhs)).zip(&mut dst) {
+            dst.write((lhs, rhs));
+        }
+        // FIXME: Convert to crate::mem::transmute once it works with generics.
+        // unsafe { crate::mem::transmute::<[MaybeUninit<U>; N], [U; N]>(dst) }
+        // SAFETY: At this point we've properly initialized the whole array
+        // and we just need to cast it to the correct type.
+        unsafe { crate::mem::transmute_copy::<_, [(T, U); N]>(&dst) }
+    }
+
     /// Returns a slice containing the entire array. Equivalent to `&s[..]`.
     #[unstable(feature = "array_methods", issue = "76118")]
     pub fn as_slice(&self) -> &[T] {
diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs
index 89c2a969c28..9005e3d8f43 100644
--- a/library/core/tests/array.rs
+++ b/library/core/tests/array.rs
@@ -317,6 +317,14 @@ fn array_map() {
     assert_eq!(b, [1, 2, 3]);
 }
 
+#[test]
+fn array_zip() {
+    let a = [1, 2, 3];
+    let b = [4, 5, 6];
+    let c = a.zip(b);
+    assert_eq!(c, [(1, 4), (2, 5), (3, 6)]);
+}
+
 // See note on above test for why `should_panic` is used.
 #[test]
 #[should_panic(expected = "test succeeded")]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 1efb3b74118..2daf2650b58 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -3,6 +3,7 @@
 #![feature(array_from_ref)]
 #![feature(array_methods)]
 #![feature(array_map)]
+#![feature(array_zip)]
 #![feature(array_windows)]
 #![feature(bool_to_option)]
 #![feature(bound_cloned)]