about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatt Brubeck <mbrubeck@limpet.net>2017-03-10 08:19:42 -0800
committerMatt Brubeck <mbrubeck@limpet.net>2017-04-15 09:01:56 -0700
commitaad2062073f46f28c6d1269463cc6c19df1e0199 (patch)
tree4cc57e0c924feb0018424d13f63aa7be2dca1ac6 /src
parent675475c4d3e3b1ebff5b761570f4a3f9a0ca23df (diff)
downloadrust-aad2062073f46f28c6d1269463cc6c19df1e0199.tar.gz
rust-aad2062073f46f28c6d1269463cc6c19df1e0199.zip
Specialize Vec::from_elem for other numeric types
Diffstat (limited to 'src')
-rw-r--r--src/libcollections/lib.rs2
-rw-r--r--src/libcollections/vec.rs37
2 files changed, 39 insertions, 0 deletions
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 99afd08e811..31af6c2f284 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -35,6 +35,7 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![cfg_attr(not(test), feature(char_escape_debug))]
+#![cfg_attr(not(test), feature(core_float))]
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
@@ -42,6 +43,7 @@
 #![feature(fused)]
 #![feature(generic_param_attrs)]
 #![feature(heap_api)]
+#![feature(i128_type)]
 #![feature(inclusive_range)]
 #![feature(lang_items)]
 #![feature(manually_drop)]
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index f488e36c077..a3c529f3585 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -77,6 +77,8 @@ use core::hash::{self, Hash};
 use core::intrinsics::{arith_offset, assume};
 use core::iter::{FromIterator, FusedIterator, TrustedLen};
 use core::mem;
+#[cfg(not(test))]
+use core::num::Float;
 use core::ops::{InPlace, Index, IndexMut, Place, Placer};
 use core::ops;
 use core::ptr;
@@ -1404,6 +1406,41 @@ impl SpecFromElem for u8 {
     }
 }
 
+macro_rules! impl_spec_from_elem {
+    ($t: ty, $is_zero: expr) => {
+        impl SpecFromElem for $t {
+            #[inline]
+            fn from_elem(elem: $t, n: usize) -> Vec<$t> {
+                if $is_zero(elem) {
+                    return Vec {
+                        buf: RawVec::with_capacity_zeroed(n),
+                        len: n,
+                    }
+                }
+                let mut v = Vec::with_capacity(n);
+                v.extend_with_element(n, elem);
+                v
+            }
+        }
+    };
+}
+
+impl_spec_from_elem!(i8, |x| x == 0);
+impl_spec_from_elem!(i16, |x| x == 0);
+impl_spec_from_elem!(i32, |x| x == 0);
+impl_spec_from_elem!(i64, |x| x == 0);
+impl_spec_from_elem!(i128, |x| x == 0);
+impl_spec_from_elem!(isize, |x| x == 0);
+
+impl_spec_from_elem!(u16, |x| x == 0);
+impl_spec_from_elem!(u32, |x| x == 0);
+impl_spec_from_elem!(u64, |x| x == 0);
+impl_spec_from_elem!(u128, |x| x == 0);
+impl_spec_from_elem!(usize, |x| x == 0);
+
+impl_spec_from_elem!(f32, |x: f32| x == 0. && x.is_sign_positive());
+impl_spec_from_elem!(f64, |x: f64| x == 0. && x.is_sign_positive());
+
 ////////////////////////////////////////////////////////////////////////////////
 // Common trait implementations for Vec
 ////////////////////////////////////////////////////////////////////////////////