mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 03:50:17 +08:00
[libc++] Replace __resize_default_init with resize_and_overwrite (#157121)
Since `__resize_default_init` is only ever used inside the dylib we can remove the libc++-internal API and switch to the public one. This patch inlines a bunch of functions that aren't required anymore and simplifies the code that way.
This commit is contained in:
@@ -1312,13 +1312,17 @@ public:
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
template <class _Op>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void resize_and_overwrite(size_type __n, _Op __op) {
|
||||
__resize_default_init(__n);
|
||||
__erase_to_end(std::move(__op)(data(), _LIBCPP_AUTO_CAST(__n)));
|
||||
size_type __sz = size();
|
||||
size_type __cap = capacity();
|
||||
if (__n > __cap)
|
||||
__grow_by_without_replace(__cap, __n - __cap, __sz, __sz, 0);
|
||||
__annotate_delete();
|
||||
__set_size(__n);
|
||||
__annotate_new(__n);
|
||||
__erase_to_end(std::move(__op)(data(), auto(__n)));
|
||||
}
|
||||
# endif
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __resize_default_init(size_type __n);
|
||||
|
||||
# if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE)
|
||||
_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve() _NOEXCEPT { shrink_to_fit(); }
|
||||
# endif
|
||||
@@ -1410,8 +1414,6 @@ public:
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s);
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c);
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append_default_init(size_type __n);
|
||||
|
||||
template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
|
||||
append(_InputIterator __first, _InputIterator __last) {
|
||||
@@ -3081,22 +3083,6 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class _CharT, class _Traits, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
|
||||
basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) {
|
||||
if (__n == 0)
|
||||
return;
|
||||
size_type __cap = capacity();
|
||||
size_type __sz = size();
|
||||
if (__cap - __sz < __n)
|
||||
__grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
|
||||
__annotate_increase(__n);
|
||||
pointer __p = __get_pointer();
|
||||
__sz += __n;
|
||||
__set_size(__sz);
|
||||
traits_type::assign(__p[__sz], value_type());
|
||||
}
|
||||
|
||||
template <class _CharT, class _Traits, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) {
|
||||
bool __is_short = !__is_long();
|
||||
@@ -3435,16 +3421,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
|
||||
__erase_to_end(__n);
|
||||
}
|
||||
|
||||
template <class _CharT, class _Traits, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
|
||||
basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) {
|
||||
size_type __sz = size();
|
||||
if (__n > __sz) {
|
||||
__append_default_init(__n - __sz);
|
||||
} else
|
||||
__erase_to_end(__n);
|
||||
}
|
||||
|
||||
template <class _CharT, class _Traits, class _Allocator>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __requested_capacity) {
|
||||
if (__requested_capacity > max_size())
|
||||
|
||||
@@ -34,20 +34,19 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const ch
|
||||
|
||||
va_list apcopy;
|
||||
va_copy(apcopy, ap);
|
||||
int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
|
||||
int size = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
|
||||
va_end(apcopy);
|
||||
|
||||
string result;
|
||||
if (static_cast<size_t>(ret) < buf.size()) {
|
||||
result.assign(buf.data(), static_cast<size_t>(ret));
|
||||
if (static_cast<size_t>(size) < buf.size()) {
|
||||
result.assign(buf.data(), static_cast<size_t>(size));
|
||||
} else {
|
||||
// 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_t 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, ap);
|
||||
_LIBCPP_ASSERT_INTERNAL(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
|
||||
result.resize_and_overwrite(size, [&](char* res, size_t n) { return ::vsnprintf(res, n, msg, ap); });
|
||||
_LIBCPP_ASSERT_INTERNAL(static_cast<size_t>(size) == result.size(),
|
||||
"vsnprintf did not result in the same number of characters as the first attempt?");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
@@ -67,6 +68,21 @@ static void BM_StringCtorDefault(benchmark::State& state) {
|
||||
}
|
||||
BENCHMARK(BM_StringCtorDefault);
|
||||
|
||||
static void BM_StringResizeAndOverwrite(benchmark::State& state) {
|
||||
std::string str;
|
||||
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(str);
|
||||
str.resize_and_overwrite(10, [](char* ptr, size_t n) {
|
||||
std::fill_n(ptr, n, 'a');
|
||||
return n;
|
||||
});
|
||||
benchmark::DoNotOptimize(str);
|
||||
str.clear();
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_StringResizeAndOverwrite);
|
||||
|
||||
enum class Length { Empty, Small, Large, Huge };
|
||||
struct AllLengths : EnumValuesAsTuple<AllLengths, Length, 4> {
|
||||
static constexpr const char* Names[] = {"Empty", "Small", "Large", "Huge"};
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <string>
|
||||
|
||||
// __resize_default_init(size_type)
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
TEST_CONSTEXPR_CXX20 void write_c_str(char* buf, int size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
buf[i] = 'a';
|
||||
}
|
||||
buf[size] = '\0';
|
||||
}
|
||||
|
||||
template <class S>
|
||||
TEST_CONSTEXPR_CXX20 void test_buffer_usage() {
|
||||
{
|
||||
unsigned buff_size = 125;
|
||||
unsigned used_size = buff_size - 16;
|
||||
S s;
|
||||
s.__resize_default_init(buff_size);
|
||||
write_c_str(&s[0], used_size);
|
||||
assert(s.size() == buff_size);
|
||||
assert(std::char_traits<char>().length(s.data()) == used_size);
|
||||
s.__resize_default_init(used_size);
|
||||
assert(s.size() == used_size);
|
||||
assert(s.data()[used_size] == '\0');
|
||||
for (unsigned i = 0; i < used_size; ++i) {
|
||||
assert(s[i] == 'a');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class S>
|
||||
TEST_CONSTEXPR_CXX20 void test_basic() {
|
||||
{
|
||||
S s;
|
||||
s.__resize_default_init(3);
|
||||
assert(s.size() == 3);
|
||||
assert(s.data()[3] == '\0');
|
||||
for (int i = 0; i < 3; ++i)
|
||||
s[i] = 'a' + i;
|
||||
s.__resize_default_init(1);
|
||||
assert(s[0] == 'a');
|
||||
assert(s.data()[1] == '\0');
|
||||
assert(s.size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
template <class S>
|
||||
TEST_CONSTEXPR_CXX20 bool test() {
|
||||
test_basic<S>();
|
||||
test_buffer_usage<S>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<std::string>();
|
||||
#if TEST_STD_VER > 17
|
||||
static_assert(test<std::string>());
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
|
||||
// UNSUPPORTED: availability-filesystem-missing
|
||||
// UNSUPPORTED: no-filesystem
|
||||
// ADDITIONAL_COMPILE_FLAGS: -I %{libcxx-dir}/src
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
|
||||
// UNSUPPORTED: availability-filesystem-missing
|
||||
|
||||
// <filesystem>
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <string>
|
||||
|
||||
// __resize_default_init(size_type)
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
TEST_CONSTEXPR_CXX20 void write_c_str(char* buf, int size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
buf[i] = 'a';
|
||||
}
|
||||
buf[size] = '\0';
|
||||
}
|
||||
|
||||
template <class S>
|
||||
TEST_CONSTEXPR_CXX20 void test_buffer_usage() {
|
||||
{
|
||||
unsigned buff_size = 125;
|
||||
unsigned used_size = buff_size - 16;
|
||||
S s;
|
||||
s.__resize_default_init(buff_size);
|
||||
write_c_str(&s[0], used_size);
|
||||
assert(s.size() == buff_size);
|
||||
assert(std::char_traits<char>().length(s.data()) == used_size);
|
||||
s.__resize_default_init(used_size);
|
||||
assert(s.size() == used_size);
|
||||
assert(s.data()[used_size] == '\0');
|
||||
for (unsigned i = 0; i < used_size; ++i) {
|
||||
assert(s[i] == 'a');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class S>
|
||||
TEST_CONSTEXPR_CXX20 void test_basic() {
|
||||
{
|
||||
S s;
|
||||
s.__resize_default_init(3);
|
||||
assert(s.size() == 3);
|
||||
assert(s.data()[3] == '\0');
|
||||
for (int i = 0; i < 3; ++i)
|
||||
s[i] = 'a' + i;
|
||||
s.__resize_default_init(1);
|
||||
assert(s[0] == 'a');
|
||||
assert(s.data()[1] == '\0');
|
||||
assert(s.size() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
template <class S>
|
||||
TEST_CONSTEXPR_CXX20 bool test() {
|
||||
test_basic<S>();
|
||||
test_buffer_usage<S>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test<std::string>();
|
||||
#if TEST_STD_VER > 17
|
||||
static_assert(test<std::string>());
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user