diff options
| author | Michał Krasnoborski <mkrdln@gmail.com> | 2017-01-27 04:51:24 +0100 |
|---|---|---|
| committer | Michał Krasnoborski <mkrdln@gmail.com> | 2017-01-28 01:50:05 +0100 |
| commit | e74b55b9da5a163e02bbcbf97e7ea24d48742943 (patch) | |
| tree | 3119620b3d5a58f8c433f697452ddf86798c7609 /src/libcore/fmt | |
| parent | 8430042a49bbd49bbb4fbc54f457feb5fb614f56 (diff) | |
use `String::with_capacity` in `format!`
Diffstat (limited to 'src/libcore/fmt')
| -rw-r--r-- | src/libcore/fmt/mod.rs | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 2ba7d6e8bd1..ed9c5d3337f 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -265,6 +265,34 @@ impl<'a> Arguments<'a> { args: args } } + + /// Estimates the length of the formatted text. + /// + /// This is intended to be used for setting initial `String` capacity + /// when using `format!`. Note: this is neither the lower nor upper bound. + #[doc(hidden)] #[inline] + #[unstable(feature = "fmt_internals", reason = "internal to format_args!", + issue = "0")] + pub fn estimated_capacity(&self) -> usize { + // Using wrapping arithmetics in this function, because + // wrong result is highly unlikely and doesn't cause unsafety. + use ::num::Wrapping as W; + + let pieces_length: W<usize> = self.pieces.iter() + .map(|x| W(x.len())).sum(); + + // If they are any arguments to format, the string will most likely + // double in size. So we're pre-doubling it here. + let multiplier = if self.args.is_empty() { W(1) } else { W(2) }; + + let capacity = multiplier * pieces_length; + if multiplier == W(2) && (W(1)..W(8)).contains(capacity) { + // Allocations smaller than 8 don't really make sense for String. + 8 + } else { + capacity.0 + } + } } /// This structure represents a safely precompiled version of a format string |
