Merge pull request #624 from dtolnay/clone

Implement Clone for the punctuated iterator types
diff --git a/src/punctuated.rs b/src/punctuated.rs
index 6b29176..e9a47c3 100644
--- a/src/punctuated.rs
+++ b/src/punctuated.rs
@@ -471,6 +471,16 @@
     }
 }
 
+// No Clone bound on T or P.
+impl<'a, T, P> Clone for Pairs<'a, T, P> {
+    fn clone(&self) -> Self {
+        Pairs {
+            inner: self.inner.clone(),
+            last: self.last.clone(),
+        }
+    }
+}
+
 /// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`.
 ///
 /// Refer to the [module documentation] for details about punctuated sequences.
@@ -503,6 +513,7 @@
 /// Refer to the [module documentation] for details about punctuated sequences.
 ///
 /// [module documentation]: index.html
+#[derive(Clone)]
 pub struct IntoPairs<T, P> {
     inner: vec::IntoIter<(T, P)>,
     last: option::IntoIter<T>,
@@ -530,6 +541,7 @@
 /// Refer to the [module documentation] for details about punctuated sequences.
 ///
 /// [module documentation]: index.html
+#[derive(Clone)]
 pub struct IntoIter<T, P> {
     inner: vec::IntoIter<(T, P)>,
     last: option::IntoIter<T>,
@@ -558,7 +570,14 @@
 ///
 /// [module documentation]: index.html
 pub struct Iter<'a, T: 'a> {
-    inner: Box<ExactSizeIterator<Item = &'a T> + 'a>,
+    // The `Item = &'a T` needs to be specified to support rustc 1.31 and older.
+    // On modern compilers we would be able to write just IterTrait<'a, T> where
+    // Item can be inferred unambiguously from the supertrait.
+    inner: Box<IterTrait<'a, T, Item = &'a T> + 'a>,
+}
+
+trait IterTrait<'a, T: 'a>: ExactSizeIterator<Item = &'a T> {
+    fn clone_box(&self) -> Box<IterTrait<'a, T, Item = &'a T> + 'a>;
 }
 
 struct PrivateIter<'a, T: 'a, P: 'a> {
@@ -575,6 +594,15 @@
     }
 }
 
+// No Clone bound on T.
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Self {
+        Iter {
+            inner: self.inner.clone_box(),
+        }
+    }
+}
+
 impl<'a, T> Iterator for Iter<'a, T> {
     type Item = &'a T;
 
@@ -606,6 +634,25 @@
     }
 }
 
+// No Clone bound on T or P.
+impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
+    fn clone(&self) -> Self {
+        PrivateIter {
+            inner: self.inner.clone(),
+            last: self.last.clone(),
+        }
+    }
+}
+
+impl<'a, T: 'a, I: 'a> IterTrait<'a, T> for I
+where
+    I: ExactSizeIterator<Item = &'a T> + Clone,
+{
+    fn clone_box(&self) -> Box<IterTrait<'a, T, Item = &'a T> + 'a> {
+        Box::new(self.clone())
+    }
+}
+
 /// An iterator over mutably borrowed values of type `&mut T`.
 ///
 /// Refer to the [module documentation] for details about punctuated sequences.
@@ -666,6 +713,7 @@
 /// Refer to the [module documentation] for details about punctuated sequences.
 ///
 /// [module documentation]: index.html
+#[cfg_attr(feature = "clone-impls", derive(Clone))]
 pub enum Pair<T, P> {
     Punctuated(T, P),
     End(T),