about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorEmerentius <emerentius@arcor.de>2018-05-23 07:20:37 +0200
committerEmerentius <emerentius@arcor.de>2018-06-01 17:13:25 +0200
commitd0d0885c3fa85fd05946d69599a3ddd886c9671f (patch)
treec6e7dc6144c440692cc4fe34ec2a606d6d5c15d3 /src/liballoc
parentb2fd7da0cf0b835a540d333b4b72426b4735c586 (diff)
downloadrust-d0d0885c3fa85fd05946d69599a3ddd886c9671f.tar.gz
rust-d0d0885c3fa85fd05946d69599a3ddd886c9671f.zip
compacts join code
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/str.rs44
1 files changed, 14 insertions, 30 deletions
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 45daabf86ab..4db6d5d715c 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -104,7 +104,6 @@ macro_rules! spezialize_for_lengths {
     ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => {
         let mut target = $target;
         let iter = $iter;
-        let sep_len = $separator.len();
         let sep_bytes = $separator;
         match $separator.len() {
             $(
@@ -112,46 +111,31 @@ macro_rules! spezialize_for_lengths {
                 // specialize the cases with small separator lengths
                 $num => {
                     for s in iter {
-                        target.get_unchecked_mut(..$num)
-                            .copy_from_slice(sep_bytes);
-
-                        let s_bytes = s.borrow().as_ref();
-                        let offset = s_bytes.len();
-                        target = {target}.get_unchecked_mut($num..);
-                        target.get_unchecked_mut(..offset)
-                            .copy_from_slice(s_bytes);
-                        target = {target}.get_unchecked_mut(offset..);
+                        copy_slice_and_advance!(target, sep_bytes);
+                        copy_slice_and_advance!(target, s.borrow().as_ref());
                     }
                 },
             )*
-            0 => {
-                // concat, same principle without the separator
-                for s in iter {
-                    let s_bytes = s.borrow().as_ref();
-                    let offset = s_bytes.len();
-                    target.get_unchecked_mut(..offset)
-                        .copy_from_slice(s_bytes);
-                    target = {target}.get_unchecked_mut(offset..);
-                }
-            },
             _ => {
                 // arbitrary non-zero size fallback
                 for s in iter {
-                    target.get_unchecked_mut(..sep_len)
-                        .copy_from_slice(sep_bytes);
-
-                    let s_bytes = s.borrow().as_ref();
-                    let offset = s_bytes.len();
-                    target = {target}.get_unchecked_mut(sep_len..);
-                    target.get_unchecked_mut(..offset)
-                        .copy_from_slice(s_bytes);
-                    target = {target}.get_unchecked_mut(offset..);
+                    copy_slice_and_advance!(target, sep_bytes);
+                    copy_slice_and_advance!(target, s.borrow().as_ref());
                 }
             }
         }
     };
 }
 
+macro_rules! copy_slice_and_advance {
+    ($target:expr, $bytes:expr) => {
+        let len = $bytes.len();
+        $target.get_unchecked_mut(..len)
+            .copy_from_slice($bytes);
+        $target = {$target}.get_unchecked_mut(len..);
+    }
+}
+
 // Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
 // Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
 // For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
@@ -192,7 +176,7 @@ where
                 // copy separator and strs over without bounds checks
                 // generate loops with hardcoded offsets for small separators
                 // massive improvements possible (~ x2)
-                spezialize_for_lengths!(sep, target, iter; 1, 2, 3, 4);
+                spezialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4);
             }
             result.set_len(len);
         }