std::basic_...nd_overwrite(3)
π std::basic_...nd_overwrite(3) β C++ Standard Libary realness π
bestie, we are literally on the std::basic_...nd_overwrite(3) page from the C++ Standard Libary, and it's all about std::basic_string::resize_and_overwrite. Yes, the title is giving "my name is my name" energy, and we're keeping it. π
πΈ NAME πΈ
std::basic_string::resize_and_overwrite β also literally std::basic_string::resize_and_overwrite. no cap, the original says it twice, so we're saying it twice too. π
β¨ Synopsis β¨
template< class Operation >
(since C++23)
constexpr void resize_and_overwrite( size_type count, Operation op );
π«Ά Description π«Ά
okay so this one is actually kind of iconic. It resizes the string to contain at most count characters, using the user-provided operation op to modify the possibly indeterminate contents and set the length. The whole point is that it avoids the cost of initializing a suitably-sized std::string when it is intended to be used as a char array to be populated by, e.g., a C API call. β¨
This function performs following steps:
- Obtains contiguous storage that contains
count + 1characters, and makes its firstkcharacters equal to the firstkcharacters of*this, wherekis the smaller ofcountand the result ofthis->size()before the call toresize_and_overwrite. Letpdenote the pointer to the first character in the storage.- The equality is determined as if by checking
this->compare(0, k, p, k) == 0. - The characters in
[p + k, p + count]may have indeterminate values.
- The equality is determined as if by checking
- Evaluates
std::move(op)(p, count). Letrbe the return value ofstd::move(op)(p, count). - Replaces the contents of
*thiswith[p, p + r)(which sets the length of*thistor). Invalidates all pointers and references to the range[p, p + count].
The program is ill-formed if r does not have an integer-like type. The behavior is undefined if std::move(op)(p, count) throws an exception or modifies p or count, r is not in the range [0, count], or any character in range [p, p + r) has an indeterminate value. π
bestie, that "behavior is undefined" part is not a vibe. do not mess withporcount, do not letopthrow, and keeprinside[0, count]. fr fr. π
Implementations are recommended to avoid unnecessary copies and allocations by, e.g., making p equal to the pointer to beginning of storage of characters allocated for *this after the call, which can be identical to the existing storage of *this if count is less than or equal to this->capacity(). π§
π Parameters π
countβ the maximal possible new size of the string.opβ the function object used for setting the new contents of the string.
π«Ά Return value π«Ά
(none) β it's giving "I do the work, I don't return the tea." π
π Exceptions π
std::length_error if count > this->max_size(). Any exceptions thrown by corresponding Allocator.
If an exception is thrown from std::move(op)(p, count), the behavior is undefined. Otherwise, if an exception is thrown, this function has no effect.
π Notes π
resize_and_overwrite invalidates all iterators, pointers, and references into *this, regardless whether reallocation occurs. Implementations may assume that the contents of the string are not aliased after the call to resize_and_overwrite. π
Feature-test macro check, bestie: the macro is __cpp_lib_string_resize_and_overwrite, its value is 202110L, the Std is (C++23), and it's for std::basic_string::resize_and_overwrite. slay. β
π Example π
Link to test the example: compiler explorer. π§ͺ
// Run this code
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <string>
#include <string_view>
static_assert(__cpp_lib_string_resize_and_overwrite);
constexpr std::string_view fruits[]{"apple", "banana", "coconut", "date", "elderberry"};
int main()
{
// A simple case, append only fruits[0]. The string size will be increased.
std::string s{"Food: "};
s.resize_and_overwrite(16, [sz = s.size()](char* buf, std::size_t buf_size) noexcept
{
const auto to_copy = std::min(buf_size - sz, fruits[0].size());
std::memcpy(buf + sz, fruits[0].data(), to_copy);
return sz + to_copy;
});
std::cout << "1. " << std::quoted(s) << '\n';
// The size shrinking case. Note, that the user's lambda is always invoked.
s.resize_and_overwrite(10, [](char* buf, int n) noexcept
{
return std::find(buf, buf + n, ':') - buf;
});
std::cout << "2. " << std::quoted(s) << '\n';
std::cout << "3. Copy data until the buffer is full. Print data and sizes.\n";
std::string food{"Food:"};
const auto resize_to{27};
std::cout << "Initially, food.size: " << food.size()
<< ", food.capacity: " << food.capacity()
<< ", resize_to: " << resize_to
<< ", food: " << std::quoted(food) << '\n';
food.resize_and_overwrite(
resize_to,
[food_size = food.size()](char* p, std::size_t n) noexcept -> std::size_t
{
// p[0]..p[n] is the assignable range
// p[0]..p[min(n, food_size) - 1] is the readable range
// (contents initially equal to the original string)
// Debug print:
std::cout << "In Operation(); n: " << n << '\n';
// Copy fruits to the buffer p while there is enough space.
char* first = p + food_size;
for (char* const end = p + n; const std::string_view fruit : fruits)
{
char* last = first + fruit.size() + 1;
if (last > end)
break;
*first++ = ' ';
std::ranges::copy(fruit, first);
first = last;
}
const auto final_size{static_cast<std::size_t>(first - p)};
// Debug print:
std::cout << "In Operation(); final_size: " << final_size << '\n';
assert(final_size <= n);
return final_size; // Return value is the actual new length
// of the string, must be in range 0..n
});
std::cout << "Finally, food.size: " << food.size()
<< ", food.capacity: " << food.capacity()
<< ", food: " << std::quoted(food) << '\n';
}
π₯ Possible output π₯
1. "Food: apple"
2. "Food"
3. Copy data until the buffer is full. Print data and sizes.
Initially, food.size: 5, food.capacity: 15, resize_to: 27, food: "Food:"
In Operation(); n: 27
In Operation(); final_size: 26
Finally, food.size: 26, food.capacity: 30, food: "Food: apple banana coconut"
π¦ See also π¦
resizeβ changes the number of characters stored (public member function).
and that's the whole page, bestie π«Άπ. This little masterpiece is from http://cppreference.com, dated 2024.06.10, and yes it's the std::basic_...nd_overwrite(3) page. slay, go resize something responsibly. π
β¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms