@@ -207,6 +207,60 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
207207 clone_subtree ( self . root . as_ref ( ) )
208208 }
209209 }
210+
211+ fn clone_from ( & mut self , other : & Self ) {
212+ BTreeClone :: clone_from ( self , other) ;
213+ }
214+ }
215+
216+ trait BTreeClone {
217+ fn clone_from ( & mut self , other : & Self ) ;
218+ }
219+
220+ impl < K : Clone , V : Clone > BTreeClone for BTreeMap < K , V > {
221+ default fn clone_from ( & mut self , other : & Self ) {
222+ * self = other. clone ( ) ;
223+ }
224+ }
225+
226+ impl < K : Clone + Ord , V : Clone > BTreeClone for BTreeMap < K , V > {
227+ fn clone_from ( & mut self , other : & Self ) {
228+ // This truncates `self` to `other.len()` by calling `split_off` on
229+ // the first key after `other.len()` elements if it exists
230+ if let Some ( key) = {
231+ if self . len ( ) > other. len ( ) {
232+ let diff = self . len ( ) - other. len ( ) ;
233+ if diff <= other. len ( ) {
234+ self . iter ( ) . nth_back ( diff - 1 ) . map ( |pair| ( * pair. 0 ) . clone ( ) )
235+ } else {
236+ self . iter ( ) . nth ( other. len ( ) ) . map ( |pair| ( * pair. 0 ) . clone ( ) )
237+ }
238+ } else {
239+ None
240+ }
241+ } {
242+ self . split_off ( & key) ;
243+ }
244+ let mut siter = self . range_mut ( ..) ;
245+ let mut oiter = other. iter ( ) ;
246+ // After truncation, `self` is at most as long as `other` so this loop
247+ // replaces every key-value pair in `self`. Since `oiter` is in sorted
248+ // order and the structure of the `BTreeMap` stays the same,
249+ // the BTree invariants are maintained at the end of the loop
250+ while siter. front != siter. back {
251+ if let Some ( ( ok, ov) ) = oiter. next ( ) {
252+ // This is safe because the `siter.front != siter.back` check
253+ // ensures that `siter` is nonempty
254+ let ( sk, sv) = unsafe { siter. next_unchecked ( ) } ;
255+ sk. clone_from ( ok) ;
256+ sv. clone_from ( ov) ;
257+ } else {
258+ break ;
259+ }
260+ }
261+ // If `other` is longer than `self`, the remaining elements are inserted
262+ self . extend ( oiter. map ( |( k, v) | ( ( * k) . clone ( ) , ( * v) . clone ( ) ) ) ) ;
263+ }
210264}
211265
212266impl < K , Q : ?Sized > super :: Recover < Q > for BTreeMap < K , ( ) >
0 commit comments