string: upgrade sprintf to write directly into std::string buffer
This removes extra memory allocation. Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
1685cd3283
commit
293da738b9
@ -2367,17 +2367,17 @@ namespace stdex
|
|||||||
switch (errno) {
|
switch (errno) {
|
||||||
case 0:
|
case 0:
|
||||||
count = vsnprintf(NULL, 0, format, locale, arg);
|
count = vsnprintf(NULL, 0, format, locale, arg);
|
||||||
|
_Assume_(count >= 0);
|
||||||
break;
|
break;
|
||||||
case EINVAL: throw std::invalid_argument("invalid vsnprintf arguments");
|
case EINVAL: throw std::invalid_argument("invalid vsnprintf arguments");
|
||||||
case EILSEQ: throw std::runtime_error("encoding error");
|
case EILSEQ: throw std::runtime_error("encoding error");
|
||||||
default: throw std::runtime_error("failed to format string");
|
default: throw std::runtime_error("failed to format string");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto buf_dyn = std::make_unique<T[]>(count + 1);
|
size_t offset = str.size();
|
||||||
count = vsnprintf(buf_dyn.get(), count + 1, format, locale, arg);
|
str.resize(offset + count);
|
||||||
if (count < 0) _Unlikely_
|
if (vsnprintf(&str[offset], count + 1, format, locale, arg) != count) _Unlikely_
|
||||||
throw std::runtime_error("failed to format string");
|
throw std::runtime_error("failed to format string");
|
||||||
str.append(buf_dyn.get(), count);
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2504,16 +2504,16 @@ namespace stdex
|
|||||||
if (count) {
|
if (count) {
|
||||||
// Copy from stack.
|
// Copy from stack.
|
||||||
str.append(buf, count);
|
str.append(buf, count);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
size_t offset = str.size();
|
||||||
for (size_t capacity = 2 * 1024 / sizeof(T);; capacity *= 2) {
|
for (size_t capacity = 2 * 1024 / sizeof(T);; capacity *= 2) {
|
||||||
// Allocate on heap and retry.
|
// Allocate on heap and retry.
|
||||||
auto buf_dyn = std::make_unique<T[]>(capacity);
|
str.resize(offset + capacity);
|
||||||
count = strftime(buf_dyn.get(), capacity, format, time, locale);
|
count = strftime(&str[offset], capacity + 1, format, time, locale);
|
||||||
if (count) {
|
if (count) {
|
||||||
str.append(buf_dyn.get(), count);
|
str.resize(offset + count);
|
||||||
break;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user