summaryrefslogtreecommitdiffstats
path: root/libcxx/src/filesystem/filesystem_common.h
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2018-11-26 20:15:38 +0000
committerEric Fiselier <eric@efcs.ca>2018-11-26 20:15:38 +0000
commit01a87ef88b77034ab6a9ea7bc9da24fb380e91e8 (patch)
tree102226ac8c60dd336894950f571b5f4e48357c9b /libcxx/src/filesystem/filesystem_common.h
parente8e8c5cf4dfb2cd8a2505db9d8d103661a153458 (diff)
downloadbcm5719-llvm-01a87ef88b77034ab6a9ea7bc9da24fb380e91e8.tar.gz
bcm5719-llvm-01a87ef88b77034ab6a9ea7bc9da24fb380e91e8.zip
Add basic_string::__resize_default_init (from P1072)
This patch adds an implementation of __resize_default_init as described in P1072R2. Additionally, it uses it in filesystem to demonstrate its intended utility. Once P1072 lands, or if it changes it's interface, I will adjust the internal libc++ implementation to match. llvm-svn: 347589
Diffstat (limited to 'libcxx/src/filesystem/filesystem_common.h')
-rw-r--r--libcxx/src/filesystem/filesystem_common.h31
1 files changed, 19 insertions, 12 deletions
diff --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h
index ed92877c425..40419ee35e6 100644
--- a/libcxx/src/filesystem/filesystem_common.h
+++ b/libcxx/src/filesystem/filesystem_common.h
@@ -67,24 +67,31 @@ static string format_string_imp(const char* msg, ...) {
va_copy(args_cp, args);
GuardVAList args_copy_guard(args_cp);
+ std::string result;
+
array<char, 256> local_buff;
- size_t size = local_buff.size();
- auto ret = ::vsnprintf(local_buff.data(), size, msg, args_cp);
+ size_t size_with_null = local_buff.size();
+ auto ret = ::vsnprintf(local_buff.data(), size_with_null, msg, args_cp);
args_copy_guard.clear();
// handle empty expansion
if (ret == 0)
- return string{};
- if (static_cast<size_t>(ret) < size)
- return string(local_buff.data());
-
- // we did not provide a long enough buffer on our first attempt.
- // add 1 to size to account for null-byte in size cast to prevent overflow
- size = static_cast<size_t>(ret) + 1;
- auto buff_ptr = unique_ptr<char[]>(new char[size]);
- ret = ::vsnprintf(buff_ptr.get(), size, msg, args);
- return string(buff_ptr.get());
+ return result;
+ if (static_cast<size_t>(ret) < size_with_null) {
+ result.assign(local_buff.data(), static_cast<size_t>(ret));
+ return result;
+ }
+
+ // we did not provide a long enough buffer on our first attempt. The
+ // return value is the number of bytes (excluding the null byte) that are
+ // needed for formatting.
+ size_with_null = static_cast<size_t>(ret) + 1;
+ result.__resize_default_init(size_with_null - 1);
+ ret = ::vsnprintf(&result[0], size_with_null, msg, args);
+ _LIBCPP_ASSERT(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
+
+ return result;
}
const char* unwrap(string const& s) { return s.c_str(); }
OpenPOWER on IntegriCloud