std::basic_string<CharT,Traits,Allocator>::resize_and_overwrite - cppreference.com

From cppreference.com

template<classOperation>constexprvoidresize_and_overwrite(size_typecount,Operationop);(since C++23)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. This 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 the following steps:

Obtains contiguous storage that contains count+1 characters, and makes its first k characters equal to the first k characters of *this, where k is the smaller of count and the result of size() before the call to resize_and_overwrite. Let p denote 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.

Evaluates std::move(op)(p,count), let r be the return value.

Replaces the contents of *this with [p, p+r) (which sets the length of *this to r). Invalidates all pointers and references to the range [p, p+count].

If r is not of an

integer-like type

, the program is ill-formed.

If any of the following conditions is satisfied, the behavior is undefined:

std::move(op)(p,count) throws an exception.

std::move(op)(p,count) modifies p or count.

r is not in the range [0, count].

Any character in range [p, p+r) has an indeterminate value.

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 capacity().

Parameters

count - the maximal possible new size of the string op - the function object used for setting the new contents of the string Exceptions

std::length_error

if count>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

macroValueStdFeature

__cpp_lib_string_resize_and_overwrite

202110L

(C++23)std::basic_string::resize_and_overwriteExample

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);constexprstd::string_viewfruits[]{"apple","banana","coconut","date","elderberry"};intmain(){// A simple case, append only fruits[0]. The string size will be increased.std::strings{"Food: "};s.resize_and_overwrite(16,[sz=s.size()](char*buf,std::size_tbuf_size)noexcept{constautoto_copy=std::min(buf_size-sz,fruits[0].size());std::memcpy(buf+sz,fruits[0].data(),to_copy);returnsz+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,intn)noexcept{returnstd::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::stringfood{"Food:"};constautoresize_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_tn)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*constend=p+n;conststd::string_viewfruit:fruits){char*last=first+fruit.size()+1;if(last>end)break;*first++=' ';std::ranges::copy(fruit,first);first=last;}constautofinal_size{static_cast<std::size_t>(first-p)};// Debug print:std::cout<<"In Operation(); final_size: "<<final_size<<'\n';assert(final_size<=n);returnfinal_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

changes the number of characters stored
(public member function)

[edit]