@@ -767,18 +767,65 @@ pub struct IterMut<'a, K: 'a, V: 'a> {
767
767
marker : marker:: PhantomData < ( & ' a K , & ' a mut V ) > ,
768
768
}
769
769
770
+ /// A consuming insertion-order iterator over a `LinkedHashMap`'s entries.
771
+ pub struct IntoIter < K , V > {
772
+ head : * mut LinkedHashMapEntry < K , V > ,
773
+ tail : * mut LinkedHashMapEntry < K , V > ,
774
+ remaining : usize ,
775
+ marker : marker:: PhantomData < ( K , V ) > ,
776
+ }
777
+
770
778
unsafe impl < ' a , K , V > Send for Iter < ' a , K , V > where K : Send , V : Send { }
771
779
772
780
unsafe impl < ' a , K , V > Send for IterMut < ' a , K , V > where K : Send , V : Send { }
773
781
782
+ unsafe impl < K , V > Send for IntoIter < K , V > where K : Send , V : Send { }
783
+
774
784
unsafe impl < ' a , K , V > Sync for Iter < ' a , K , V > where K : Sync , V : Sync { }
775
785
776
786
unsafe impl < ' a , K , V > Sync for IterMut < ' a , K , V > where K : Sync , V : Sync { }
777
787
788
+ unsafe impl < K , V > Sync for IntoIter < K , V > where K : Sync , V : Sync { }
789
+
778
790
impl < ' a , K , V > Clone for Iter < ' a , K , V > {
779
791
fn clone ( & self ) -> Self { Iter { ..* self } }
780
792
}
781
793
794
+ impl < K , V > Clone for IntoIter < K , V > where K : Clone , V : Clone {
795
+ fn clone ( & self ) -> Self {
796
+ if self . remaining == 0 {
797
+ return IntoIter { ..* self }
798
+ }
799
+
800
+ fn clone_entry < K , V > ( e : * mut LinkedHashMapEntry < K , V > ) -> * mut LinkedHashMapEntry < K , V >
801
+ where K : Clone , V : Clone ,
802
+ {
803
+ Box :: into_raw ( Box :: new ( LinkedHashMapEntry :: new (
804
+ unsafe { ( * e) . key . clone ( ) } , unsafe { ( * e) . value . clone ( ) }
805
+ ) ) )
806
+ }
807
+
808
+ let mut cur = self . head ;
809
+ let head = clone_entry ( cur) ;
810
+ let mut tail = head;
811
+ for _ in 1 ..self . remaining {
812
+ unsafe {
813
+ ( * tail) . prev = clone_entry ( ( * cur) . prev ) ;
814
+ ( * ( * tail) . prev ) . next = tail;
815
+ tail = ( * tail) . prev ;
816
+ cur = ( * cur) . prev ;
817
+ }
818
+ }
819
+
820
+ IntoIter {
821
+ head : head,
822
+ tail : tail,
823
+ remaining : self . remaining ,
824
+ marker : marker:: PhantomData ,
825
+ }
826
+ }
827
+ }
828
+
782
829
impl < ' a , K , V > Iterator for Iter < ' a , K , V > {
783
830
type Item = ( & ' a K , & ' a V ) ;
784
831
@@ -821,6 +868,27 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
821
868
}
822
869
}
823
870
871
+ impl < K : Hash + Eq , V > Iterator for IntoIter < K , V > {
872
+ type Item = ( K , V ) ;
873
+
874
+ fn next ( & mut self ) -> Option < ( K , V ) > {
875
+ if self . remaining == 0 {
876
+ return None
877
+ }
878
+ self . remaining -= 1 ;
879
+ unsafe {
880
+ let prev = ( * self . head ) . prev ;
881
+ let e = * Box :: from_raw ( self . head ) ;
882
+ self . head = prev;
883
+ Some ( ( e. key , e. value ) )
884
+ }
885
+ }
886
+
887
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
888
+ ( self . remaining , Some ( self . remaining ) )
889
+ }
890
+ }
891
+
824
892
impl < ' a , K , V > DoubleEndedIterator for Iter < ' a , K , V > {
825
893
fn next_back ( & mut self ) -> Option < ( & ' a K , & ' a V ) > {
826
894
if self . head == self . tail {
@@ -849,6 +917,21 @@ impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
849
917
}
850
918
}
851
919
920
+ impl < K : Hash + Eq , V > DoubleEndedIterator for IntoIter < K , V > {
921
+ fn next_back ( & mut self ) -> Option < ( K , V ) > {
922
+ if self . remaining == 0 {
923
+ return None
924
+ }
925
+ self . remaining -= 1 ;
926
+ unsafe {
927
+ let next = ( * self . tail ) . next ;
928
+ let e = * Box :: from_raw ( self . tail ) ;
929
+ self . tail = next;
930
+ Some ( ( e. key , e. value ) )
931
+ }
932
+ }
933
+ }
934
+
852
935
impl < ' a , K , V > ExactSizeIterator for Iter < ' a , K , V > {
853
936
fn len ( & self ) -> usize { self . remaining }
854
937
}
@@ -857,6 +940,22 @@ impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
857
940
fn len ( & self ) -> usize { self . remaining }
858
941
}
859
942
943
+ impl < K : Hash + Eq , V > ExactSizeIterator for IntoIter < K , V > {
944
+ fn len ( & self ) -> usize { self . remaining }
945
+ }
946
+
947
+ impl < K , V > Drop for IntoIter < K , V > {
948
+ fn drop ( & mut self ) {
949
+ for _ in 0 ..self . remaining {
950
+ unsafe {
951
+ let next = ( * self . tail ) . next ;
952
+ Box :: from_raw ( self . tail ) ;
953
+ self . tail = next;
954
+ }
955
+ }
956
+ }
957
+ }
958
+
860
959
/// An insertion-order iterator over a `LinkedHashMap`'s keys.
861
960
pub struct Keys < ' a , K : ' a , V : ' a > {
862
961
#[ cfg_attr( feature = "clippy" , allow( type_complexity) ) ]
@@ -919,6 +1018,34 @@ impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a mut LinkedHashMap
919
1018
fn into_iter ( self ) -> IterMut < ' a , K , V > { self . iter_mut ( ) }
920
1019
}
921
1020
1021
+ impl < K : Hash + Eq , V , S : BuildHasher > IntoIterator for LinkedHashMap < K , V , S > {
1022
+ type Item = ( K , V ) ;
1023
+ type IntoIter = IntoIter < K , V > ;
1024
+ fn into_iter ( mut self ) -> IntoIter < K , V > {
1025
+ let ( head, tail) = if !self . head . is_null ( ) {
1026
+ unsafe { ( ( * self . head ) . prev , ( * self . head ) . next ) }
1027
+ } else {
1028
+ ( ptr:: null_mut ( ) , ptr:: null_mut ( ) )
1029
+ } ;
1030
+ let len = self . len ( ) ;
1031
+
1032
+ if !self . head . is_null ( ) {
1033
+ unsafe { drop_empty_entry_box ( self . head ) }
1034
+ }
1035
+ self . clear_free_list ( ) ;
1036
+ // drop the HashMap but not the LinkedHashMap
1037
+ self . map = unsafe { mem:: uninitialized ( ) } ;
1038
+ mem:: forget ( self ) ;
1039
+
1040
+ IntoIter {
1041
+ head : head,
1042
+ tail : tail,
1043
+ remaining : len,
1044
+ marker : marker:: PhantomData ,
1045
+ }
1046
+ }
1047
+ }
1048
+
922
1049
#[ cfg( all( feature = "nightly" , test) ) ]
923
1050
mod bench {
924
1051
extern crate test;
0 commit comments