Skip to content

Commit e4fc044

Browse files
authored
Improve string allocation
* Remove unnecessary std::max in shrink_to_fit * Remove unnecessary condition in __recommend * Fix allocation for string with small_size required less bytes (24 instead of 26, 12 instead of 11, etc) ``` #include <cstddef> #include <cstdint> using size_type = size_t; template <typename long_type> struct __long { long_type x; long_type y; long_type z; }; template <typename value_type, typename long_type> static constexpr size_type min_cap = (sizeof(__long<long_type>) - 1) / sizeof(value_type) > 2 ? (sizeof(__long<long_type>) - 1) / sizeof(value_type) : 2; template <typename long_type> static constexpr size_type alignment = sizeof(long_type); template <size_type __a> static constexpr size_type __align_it(size_type __s) noexcept { return (__s + (__a - 1)) & ~(__a - 1); } template <typename value_type, typename long_type, size_type __endian_factor> static constexpr size_type __recommend(size_type __s) noexcept { constexpr auto __min_cap = min_cap<value_type, long_type>; constexpr auto __alignment = alignment<long_type>; if (__s < __min_cap) { return static_cast<size_type>(__min_cap) - 1; } const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor; size_type __guess = __align_it<__boundary>(__s + 1) - 1; //if (__guess == __min_cap) __guess += __endian_factor; return __guess; } template <typename value_type, typename long_type, size_type __endian_factor> static constexpr auto to_alloc(size_type s) { return __recommend<value_type, long_type, __endian_factor>(s) + 1; } int main() { static constexpr auto char8_64 = min_cap<char, long>; static_assert(char8_64 == 23); static constexpr auto char16_64 = min_cap<char16_t, long>; static_assert(char16_64 == 11); static constexpr auto char32_64 = min_cap<char32_t, long>; static_assert(char32_64 == 5); static constexpr auto char64_64 = min_cap<long, long>; static_assert(char64_64 == 2); static constexpr auto char8_32 = min_cap<char, int>; static_assert(char8_32 == 11); static constexpr auto char16_32 = min_cap<char16_t, int>; static_assert(char16_32 == 5); static constexpr auto char32_32 = min_cap<char32_t, int>; static_assert(char32_32 == 2); static constexpr auto char64_32 = min_cap<long, int>; static_assert(char64_32 == 2); // 64 bit system, __endian_factor = 1 static_assert(to_alloc<char, long, 1>(0) == char8_64); static_assert(to_alloc<char16_t, long, 1>(0) == char16_64); static_assert(to_alloc<char32_t, long, 1>(0) == char32_64); static_assert(to_alloc<long, long, 1>(0) == char64_64); static_assert(to_alloc<char, long, 1>(char8_64) == char8_64 + 1); static_assert(to_alloc<char16_t, long, 1>(char16_64) == char16_64 + 1); static_assert(to_alloc<char32_t, long, 1>(char32_64) == char32_64 + 1); static_assert(to_alloc<long, long, 1>(char64_64) == char64_64 + 1); static_assert(to_alloc<char, long, 1>(char8_64 + 1) == 32); static_assert(to_alloc<char16_t, long, 1>(char16_64 + 1) == 16); static_assert(to_alloc<char32_t, long, 1>(char32_64 + 1) == 8); static_assert(to_alloc<long, long, 1>(char64_64 + 1) == 4); // 64 bit system, __endian_factor = 2 static_assert(to_alloc<char, long, 2>(0) == char8_64); static_assert(to_alloc<char16_t, long, 2>(0) == char16_64); static_assert(to_alloc<char32_t, long, 2>(0) == char32_64); static_assert(to_alloc<long, long, 2>(0) == char64_64); static_assert(to_alloc<char, long, 2>(char8_64) == char8_64 + 1); static_assert(to_alloc<char16_t, long, 2>(char16_64) == char16_64 + 1); static_assert(to_alloc<char32_t, long, 2>(char32_64) == char32_64 + 1); static_assert(to_alloc<long, long, 2>(char64_64) == char64_64 + 2); static_assert(to_alloc<char, long, 2>(char8_64 + 1) == 32); static_assert(to_alloc<char16_t, long, 2>(char16_64 + 1) == 16); static_assert(to_alloc<char32_t, long, 2>(char32_64 + 1) == 8); static_assert(to_alloc<long, long, 2>(char64_64 + 1) == 4); // 32 bit system, __endian_factor = 1 static_assert(to_alloc<char, int, 1>(0) == char8_32); static_assert(to_alloc<char16_t, int, 1>(0) == char16_32); static_assert(to_alloc<char32_t, int, 1>(0) == char32_32); static_assert(to_alloc<long, int, 1>(0) == char64_32); static_assert(to_alloc<char, int, 1>(char8_32) == char8_32 + 1); static_assert(to_alloc<char16_t, int, 1>(char16_32) == char16_32 + 1); static_assert(to_alloc<char32_t, int, 1>(char32_32) == char32_32 + 1); static_assert(to_alloc<long, int, 1>(char64_32) == char64_32 + 1); static_assert(to_alloc<char, int, 1>(char8_32 + 1) == 16); static_assert(to_alloc<char16_t, int, 1>(char16_32 + 1) == 8); static_assert(to_alloc<char32_t, int, 1>(char32_32 + 1) == 4); static_assert(to_alloc<long, int, 1>(char64_32 + 1) == 4); // 32 bit system, __endian_factor = 2 static_assert(to_alloc<char, int, 2>(0) == char8_32); static_assert(to_alloc<char16_t, int, 2>(0) == char16_32); static_assert(to_alloc<char32_t, int, 2>(0) == char32_32); static_assert(to_alloc<long, int, 2>(0) == char64_32); static_assert(to_alloc<char, int, 2>(char8_32) == char8_32 + 1); static_assert(to_alloc<char16_t, int, 2>(char16_32) == char16_32 + 1); static_assert(to_alloc<char32_t, int, 2>(char32_32) == 4); static_assert(to_alloc<long, int, 2>(char64_32) == 4); static_assert(to_alloc<char, int, 2>(char8_32 + 1) == 16); static_assert(to_alloc<char16_t, int, 2>(char16_32 + 1) == 8); static_assert(to_alloc<char32_t, int, 2>(char32_32 + 1) == 4); static_assert(to_alloc<long, int, 2>(char64_32 + 1) == 4); } ```
1 parent e90126e commit e4fc044

File tree

1 file changed

+1
-7
lines changed

1 file changed

+1
-7
lines changed

libcxx/include/string

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,13 +1984,8 @@ private:
19841984
}
19851985
enum { __alignment = 8 };
19861986
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __s) _NOEXCEPT {
1987-
if (__s < __min_cap) {
1988-
return static_cast<size_type>(__min_cap) - 1;
1989-
}
19901987
const size_type __boundary = sizeof(value_type) < __alignment ? __alignment / sizeof(value_type) : __endian_factor;
19911988
size_type __guess = __align_it<__boundary>(__s + 1) - 1;
1992-
if (__guess == __min_cap)
1993-
__guess += __endian_factor;
19941989
return __guess;
19951990
}
19961991

@@ -3249,8 +3244,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::re
32493244
if (__requested_capacity <= capacity())
32503245
return;
32513246

3252-
size_type __target_capacity = std::max(__requested_capacity, size());
3253-
__target_capacity = __recommend(__target_capacity);
3247+
__target_capacity = __recommend(__target_capacity);
32543248
if (__target_capacity == capacity())
32553249
return;
32563250

0 commit comments

Comments
 (0)