@@ -704,7 +704,7 @@ impl<T, const CAP: usize> std::convert::TryFrom<&[T]> for ArrayVec<T, CAP>
704
704
Err ( CapacityError :: new ( ( ) ) )
705
705
} else {
706
706
let mut array = Self :: new ( ) ;
707
- array. extend ( slice. iter ( ) . cloned ( ) ) ;
707
+ array. extend_from_slice ( slice) ;
708
708
Ok ( array)
709
709
}
710
710
}
@@ -931,39 +931,75 @@ impl<T, Data, F> Drop for ScopeExitGuard<T, Data, F>
931
931
932
932
/// Extend the `ArrayVec` with an iterator.
933
933
///
934
- /// Does not extract more items than there is space for. No error
935
- /// occurs if there are more iterator elements.
934
+ /// ***Panics*** if extending the vector exceeds its capacity.
936
935
impl < T , const CAP : usize > Extend < T > for ArrayVec < T , CAP > {
936
+ /// Extend the `ArrayVec` with an iterator.
937
+ ///
938
+ /// ***Panics*** if extending the vector exceeds its capacity.
937
939
fn extend < I : IntoIterator < Item =T > > ( & mut self , iter : I ) {
938
- let take = self . capacity ( ) - self . len ( ) ;
939
940
unsafe {
940
- let len = self . len ( ) ;
941
- let mut ptr = raw_ptr_add ( self . as_mut_ptr ( ) , len) ;
942
- let end_ptr = raw_ptr_add ( ptr, take) ;
943
- // Keep the length in a separate variable, write it back on scope
944
- // exit. To help the compiler with alias analysis and stuff.
945
- // We update the length to handle panic in the iteration of the
946
- // user's iterator, without dropping any elements on the floor.
947
- let mut guard = ScopeExitGuard {
948
- value : & mut self . len ,
949
- data : len,
950
- f : move |& len, self_len| {
951
- * * self_len = len;
952
- }
953
- } ;
954
- let mut iter = iter. into_iter ( ) ;
955
- loop {
956
- if ptr == end_ptr { break ; }
957
- if let Some ( elt) = iter. next ( ) {
958
- raw_ptr_write ( ptr, elt) ;
959
- ptr = raw_ptr_add ( ptr, 1 ) ;
960
- guard. data += 1 ;
961
- } else {
962
- break ;
963
- }
941
+ self . extend_from_iter :: < _ , true > ( iter)
942
+ }
943
+ }
944
+ }
945
+
946
+ #[ inline( never) ]
947
+ #[ cold]
948
+ fn extend_panic ( ) {
949
+ panic ! ( "ArrayVec: capacity exceeded in extend/from_iter" ) ;
950
+ }
951
+
952
+ impl < T , const CAP : usize > ArrayVec < T , CAP > {
953
+ /// Extend the arrayvec from the iterable.
954
+ ///
955
+ /// ## Safety
956
+ ///
957
+ /// Unsafe because if CHECK is false, the length of the input is not checked.
958
+ /// The caller must ensure the length of the input fits in the capacity.
959
+ pub ( crate ) unsafe fn extend_from_iter < I , const CHECK : bool > ( & mut self , iterable : I )
960
+ where I : IntoIterator < Item = T >
961
+ {
962
+ let take = self . capacity ( ) - self . len ( ) ;
963
+ let len = self . len ( ) ;
964
+ let mut ptr = raw_ptr_add ( self . as_mut_ptr ( ) , len) ;
965
+ let end_ptr = raw_ptr_add ( ptr, take) ;
966
+ // Keep the length in a separate variable, write it back on scope
967
+ // exit. To help the compiler with alias analysis and stuff.
968
+ // We update the length to handle panic in the iteration of the
969
+ // user's iterator, without dropping any elements on the floor.
970
+ let mut guard = ScopeExitGuard {
971
+ value : & mut self . len ,
972
+ data : len,
973
+ f : move |& len, self_len| {
974
+ * * self_len = len;
975
+ }
976
+ } ;
977
+ let mut iter = iterable. into_iter ( ) ;
978
+ loop {
979
+ if let Some ( elt) = iter. next ( ) {
980
+ if ptr == end_ptr && CHECK { extend_panic ( ) ; }
981
+ debug_assert_ne ! ( ptr, end_ptr) ;
982
+ ptr. write ( elt) ;
983
+ ptr = raw_ptr_add ( ptr, 1 ) ;
984
+ guard. data += 1 ;
985
+ } else {
986
+ return ; // success
964
987
}
965
988
}
966
989
}
990
+
991
+ /// Extend the ArrayVec with clones of elements from the slice;
992
+ /// the length of the slice must be <= the remaining capacity in the arrayvec.
993
+ pub ( crate ) fn extend_from_slice ( & mut self , slice : & [ T ] )
994
+ where T : Clone
995
+ {
996
+ let take = self . capacity ( ) - self . len ( ) ;
997
+ debug_assert ! ( slice. len( ) <= take) ;
998
+ unsafe {
999
+ let slice = if take < slice. len ( ) { & slice[ ..take] } else { slice } ;
1000
+ self . extend_from_iter :: < _ , false > ( slice. iter ( ) . cloned ( ) ) ;
1001
+ }
1002
+ }
967
1003
}
968
1004
969
1005
/// Rawptr add but uses arithmetic distance for ZST
@@ -976,19 +1012,13 @@ unsafe fn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T {
976
1012
}
977
1013
}
978
1014
979
- unsafe fn raw_ptr_write < T > ( ptr : * mut T , value : T ) {
980
- if mem:: size_of :: < T > ( ) == 0 {
981
- /* nothing */
982
- } else {
983
- ptr:: write ( ptr, value)
984
- }
985
- }
986
-
987
1015
/// Create an `ArrayVec` from an iterator.
988
1016
///
989
- /// Does not extract more items than there is space for. No error
990
- /// occurs if there are more iterator elements.
1017
+ /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity.
991
1018
impl < T , const CAP : usize > iter:: FromIterator < T > for ArrayVec < T , CAP > {
1019
+ /// Create an `ArrayVec` from an iterator.
1020
+ ///
1021
+ /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity.
992
1022
fn from_iter < I : IntoIterator < Item =T > > ( iter : I ) -> Self {
993
1023
let mut array = ArrayVec :: new ( ) ;
994
1024
array. extend ( iter) ;
@@ -1014,8 +1044,8 @@ impl<T, const CAP: usize> Clone for ArrayVec<T, CAP>
1014
1044
self . pop ( ) ;
1015
1045
}
1016
1046
} else {
1017
- let rhs_elems = rhs[ self . len ( ) ..] . iter ( ) . cloned ( ) ;
1018
- self . extend ( rhs_elems) ;
1047
+ let rhs_elems = & rhs[ self . len ( ) ..] ;
1048
+ self . extend_from_slice ( rhs_elems) ;
1019
1049
}
1020
1050
}
1021
1051
}
0 commit comments