Initial import of rayon-1.5.0.

Bug: 155309706
Change-Id: I6ff7de1cb89d093d7938abf78d586ed76da85b0d
diff --git a/src/option.rs b/src/option.rs
new file mode 100644
index 0000000..0f56896
--- /dev/null
+++ b/src/option.rs
@@ -0,0 +1,203 @@
+//! Parallel iterator types for [options][std::option]
+//!
+//! You will rarely need to interact with this module directly unless you need
+//! to name one of the iterator types.
+//!
+//! [std::option]: https://doc.rust-lang.org/stable/std/option/
+
+use crate::iter::plumbing::*;
+use crate::iter::*;
+use std::sync::atomic::{AtomicBool, Ordering};
+
+/// A parallel iterator over the value in [`Some`] variant of an [`Option`].
+///
+/// The iterator yields one value if the [`Option`] is a [`Some`], otherwise none.
+///
+/// This `struct` is created by the [`into_par_iter`] function.
+///
+/// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
+/// [`Some`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some
+/// [`into_par_iter`]: ../iter/trait.IntoParallelIterator.html#tymethod.into_par_iter
+#[derive(Debug, Clone)]
+pub struct IntoIter<T: Send> {
+    opt: Option<T>,
+}
+
+impl<T: Send> IntoParallelIterator for Option<T> {
+    type Item = T;
+    type Iter = IntoIter<T>;
+
+    fn into_par_iter(self) -> Self::Iter {
+        IntoIter { opt: self }
+    }
+}
+
+impl<T: Send> ParallelIterator for IntoIter<T> {
+    type Item = T;
+
+    fn drive_unindexed<C>(self, consumer: C) -> C::Result
+    where
+        C: UnindexedConsumer<Self::Item>,
+    {
+        self.drive(consumer)
+    }
+
+    fn opt_len(&self) -> Option<usize> {
+        Some(self.len())
+    }
+}
+
+impl<T: Send> IndexedParallelIterator for IntoIter<T> {
+    fn drive<C>(self, consumer: C) -> C::Result
+    where
+        C: Consumer<Self::Item>,
+    {
+        let mut folder = consumer.into_folder();
+        if let Some(item) = self.opt {
+            folder = folder.consume(item);
+        }
+        folder.complete()
+    }
+
+    fn len(&self) -> usize {
+        match self.opt {
+            Some(_) => 1,
+            None => 0,
+        }
+    }
+
+    fn with_producer<CB>(self, callback: CB) -> CB::Output
+    where
+        CB: ProducerCallback<Self::Item>,
+    {
+        callback.callback(OptionProducer { opt: self.opt })
+    }
+}
+
+/// A parallel iterator over a reference to the [`Some`] variant of an [`Option`].
+///
+/// The iterator yields one value if the [`Option`] is a [`Some`], otherwise none.
+///
+/// This `struct` is created by the [`par_iter`] function.
+///
+/// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
+/// [`Some`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some
+/// [`par_iter`]: ../iter/trait.IntoParallelRefIterator.html#tymethod.par_iter
+#[derive(Debug)]
+pub struct Iter<'a, T: Sync> {
+    inner: IntoIter<&'a T>,
+}
+
+impl<'a, T: Sync> Clone for Iter<'a, T> {
+    fn clone(&self) -> Self {
+        Iter {
+            inner: self.inner.clone(),
+        }
+    }
+}
+
+impl<'a, T: Sync> IntoParallelIterator for &'a Option<T> {
+    type Item = &'a T;
+    type Iter = Iter<'a, T>;
+
+    fn into_par_iter(self) -> Self::Iter {
+        Iter {
+            inner: self.as_ref().into_par_iter(),
+        }
+    }
+}
+
+delegate_indexed_iterator! {
+    Iter<'a, T> => &'a T,
+    impl<'a, T: Sync + 'a>
+}
+
+/// A parallel iterator over a mutable reference to the [`Some`] variant of an [`Option`].
+///
+/// The iterator yields one value if the [`Option`] is a [`Some`], otherwise none.
+///
+/// This `struct` is created by the [`par_iter_mut`] function.
+///
+/// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
+/// [`Some`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some
+/// [`par_iter_mut`]: ../iter/trait.IntoParallelRefMutIterator.html#tymethod.par_iter_mut
+#[derive(Debug)]
+pub struct IterMut<'a, T: Send> {
+    inner: IntoIter<&'a mut T>,
+}
+
+impl<'a, T: Send> IntoParallelIterator for &'a mut Option<T> {
+    type Item = &'a mut T;
+    type Iter = IterMut<'a, T>;
+
+    fn into_par_iter(self) -> Self::Iter {
+        IterMut {
+            inner: self.as_mut().into_par_iter(),
+        }
+    }
+}
+
+delegate_indexed_iterator! {
+    IterMut<'a, T> => &'a mut T,
+    impl<'a, T: Send + 'a>
+}
+
+/// Private producer for an option
+struct OptionProducer<T: Send> {
+    opt: Option<T>,
+}
+
+impl<T: Send> Producer for OptionProducer<T> {
+    type Item = T;
+    type IntoIter = std::option::IntoIter<T>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.opt.into_iter()
+    }
+
+    fn split_at(self, index: usize) -> (Self, Self) {
+        debug_assert!(index <= 1);
+        let none = OptionProducer { opt: None };
+        if index == 0 {
+            (none, self)
+        } else {
+            (self, none)
+        }
+    }
+}
+
+/// Collect an arbitrary `Option`-wrapped collection.
+///
+/// If any item is `None`, then all previous items collected are discarded,
+/// and it returns only `None`.
+impl<C, T> FromParallelIterator<Option<T>> for Option<C>
+where
+    C: FromParallelIterator<T>,
+    T: Send,
+{
+    fn from_par_iter<I>(par_iter: I) -> Self
+    where
+        I: IntoParallelIterator<Item = Option<T>>,
+    {
+        fn check<T>(found_none: &AtomicBool) -> impl Fn(&Option<T>) + '_ {
+            move |item| {
+                if item.is_none() {
+                    found_none.store(true, Ordering::Relaxed);
+                }
+            }
+        }
+
+        let found_none = AtomicBool::new(false);
+        let collection = par_iter
+            .into_par_iter()
+            .inspect(check(&found_none))
+            .while_some()
+            .collect();
+
+        if found_none.load(Ordering::Relaxed) {
+            None
+        } else {
+            Some(collection)
+        }
+    }
+}