mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Don't use SmallVec<[T; 1]> for computed values with an empty default
This commit is contained in:
parent
da9d2001db
commit
813883e1bd
2 changed files with 48 additions and 35 deletions
|
@ -83,6 +83,7 @@
|
||||||
delegate_animate=False, separator='Comma', **kwargs)">
|
delegate_animate=False, separator='Comma', **kwargs)">
|
||||||
<%call expr="longhand(name, vector=True, **kwargs)">
|
<%call expr="longhand(name, vector=True, **kwargs)">
|
||||||
% if not gecko_only:
|
% if not gecko_only:
|
||||||
|
#[allow(unused_imports)]
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
@ -113,13 +114,23 @@
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
pub use super::single_value::computed_value as single_value;
|
pub use super::single_value::computed_value as single_value;
|
||||||
pub use self::single_value::T as SingleComputedValue;
|
pub use self::single_value::T as SingleComputedValue;
|
||||||
|
% if allow_empty and allow_empty != "NotInitial":
|
||||||
|
use std::vec::IntoIter;
|
||||||
|
% else:
|
||||||
use smallvec::{IntoIter, SmallVec};
|
use smallvec::{IntoIter, SmallVec};
|
||||||
|
% endif
|
||||||
use values::computed::ComputedVecIter;
|
use values::computed::ComputedVecIter;
|
||||||
|
|
||||||
/// The computed value, effectively a list of single values.
|
/// The computed value, effectively a list of single values.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct T(pub SmallVec<[single_value::T; 1]>);
|
pub struct T(
|
||||||
|
% if allow_empty and allow_empty != "NotInitial":
|
||||||
|
pub Vec<single_value::T>,
|
||||||
|
% else:
|
||||||
|
pub SmallVec<[single_value::T; 1]>,
|
||||||
|
% endif
|
||||||
|
);
|
||||||
|
|
||||||
% if delegate_animate:
|
% if delegate_animate:
|
||||||
use properties::animated_properties::Animatable;
|
use properties::animated_properties::Animatable;
|
||||||
|
@ -149,7 +160,11 @@
|
||||||
|
|
||||||
impl IntoIterator for T {
|
impl IntoIterator for T {
|
||||||
type Item = single_value::T;
|
type Item = single_value::T;
|
||||||
|
% if allow_empty and allow_empty != "NotInitial":
|
||||||
|
type IntoIter = IntoIter<single_value::T>;
|
||||||
|
% else:
|
||||||
type IntoIter = IntoIter<[single_value::T; 1]>;
|
type IntoIter = IntoIter<[single_value::T; 1]>;
|
||||||
|
% endif
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
self.0.into_iter()
|
self.0.into_iter()
|
||||||
}
|
}
|
||||||
|
@ -207,7 +222,7 @@
|
||||||
|
|
||||||
pub fn get_initial_value() -> computed_value::T {
|
pub fn get_initial_value() -> computed_value::T {
|
||||||
% if allow_empty and allow_empty != "NotInitial":
|
% if allow_empty and allow_empty != "NotInitial":
|
||||||
computed_value::T(SmallVec::new())
|
computed_value::T(vec![])
|
||||||
% else:
|
% else:
|
||||||
let mut v = SmallVec::new();
|
let mut v = SmallVec::new();
|
||||||
v.push(single_value::get_initial_value());
|
v.push(single_value::get_initial_value());
|
||||||
|
|
|
@ -808,31 +808,37 @@ pub trait RepeatableListAnimatable: Animatable {}
|
||||||
impl RepeatableListAnimatable for LengthOrPercentage {}
|
impl RepeatableListAnimatable for LengthOrPercentage {}
|
||||||
impl RepeatableListAnimatable for Either<f32, LengthOrPercentage> {}
|
impl RepeatableListAnimatable for Either<f32, LengthOrPercentage> {}
|
||||||
|
|
||||||
impl<T: RepeatableListAnimatable> Animatable for SmallVec<[T; 1]> {
|
macro_rules! repeated_vec_impl {
|
||||||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64)
|
($($ty:ty),*) => {
|
||||||
-> Result<Self, ()> {
|
$(impl<T: RepeatableListAnimatable> Animatable for $ty {
|
||||||
use num_integer::lcm;
|
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64)
|
||||||
let len = lcm(self.len(), other.len());
|
-> Result<Self, ()> {
|
||||||
self.iter().cycle().zip(other.iter().cycle()).take(len).map(|(me, you)| {
|
use num_integer::lcm;
|
||||||
me.add_weighted(you, self_portion, other_portion)
|
let len = lcm(self.len(), other.len());
|
||||||
}).collect()
|
self.iter().cycle().zip(other.iter().cycle()).take(len).map(|(me, you)| {
|
||||||
}
|
me.add_weighted(you, self_portion, other_portion)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||||
use num_integer::lcm;
|
use num_integer::lcm;
|
||||||
let len = lcm(self.len(), other.len());
|
let len = lcm(self.len(), other.len());
|
||||||
self.iter().cycle().zip(other.iter().cycle()).take(len).map(|(me, you)| {
|
self.iter().cycle().zip(other.iter().cycle()).take(len).map(|(me, you)| {
|
||||||
me.compute_squared_distance(you)
|
me.compute_squared_distance(you)
|
||||||
}).collect::<Result<Vec<_>, _>>().map(|d| d.iter().sum())
|
}).sum()
|
||||||
}
|
}
|
||||||
|
})*
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repeated_vec_impl!(SmallVec<[T; 1]>, Vec<T>);
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
||||||
impl Animatable for Au {
|
impl Animatable for Au {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -3053,9 +3059,9 @@ pub struct IntermediateShadow {
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
/// Intermediate type for box-shadow list and text-shadow list.
|
/// Intermediate type for box-shadow list and text-shadow list.
|
||||||
pub struct IntermediateShadowList(pub SmallVec<[IntermediateShadow; 1]>);
|
pub struct IntermediateShadowList(pub Vec<IntermediateShadow>);
|
||||||
|
|
||||||
type ShadowList = SmallVec<[Shadow; 1]>;
|
type ShadowList = Vec<Shadow>;
|
||||||
|
|
||||||
impl From<IntermediateShadowList> for ShadowList {
|
impl From<IntermediateShadowList> for ShadowList {
|
||||||
fn from(shadow_list: IntermediateShadowList) -> Self {
|
fn from(shadow_list: IntermediateShadowList) -> Self {
|
||||||
|
@ -3172,11 +3178,7 @@ impl Animatable for IntermediateShadowList {
|
||||||
|
|
||||||
let max_len = cmp::max(self.0.len(), other.0.len());
|
let max_len = cmp::max(self.0.len(), other.0.len());
|
||||||
|
|
||||||
let mut result = if max_len > 1 {
|
let mut result = Vec::with_capacity(max_len);
|
||||||
SmallVec::from_vec(Vec::with_capacity(max_len))
|
|
||||||
} else {
|
|
||||||
SmallVec::new()
|
|
||||||
};
|
|
||||||
|
|
||||||
for i in 0..max_len {
|
for i in 0..max_len {
|
||||||
let shadow = match (self.0.get(i), other.0.get(i)) {
|
let shadow = match (self.0.get(i), other.0.get(i)) {
|
||||||
|
@ -3202,11 +3204,7 @@ impl Animatable for IntermediateShadowList {
|
||||||
fn add(&self, other: &Self) -> Result<Self, ()> {
|
fn add(&self, other: &Self) -> Result<Self, ()> {
|
||||||
let len = self.0.len() + other.0.len();
|
let len = self.0.len() + other.0.len();
|
||||||
|
|
||||||
let mut result = if len > 1 {
|
let mut result = Vec::with_capacity(len);
|
||||||
SmallVec::from_vec(Vec::with_capacity(len))
|
|
||||||
} else {
|
|
||||||
SmallVec::new()
|
|
||||||
};
|
|
||||||
|
|
||||||
result.extend(self.0.iter().cloned());
|
result.extend(self.0.iter().cloned());
|
||||||
result.extend(other.0.iter().cloned());
|
result.extend(other.0.iter().cloned());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue