Namespaces
Variants
Actions

std::basic_string<CharT,Traits,Allocator>::resize_and_overwrite

From cppreference.com
< cpp‎ | string‎ | basic string
 
 
 
std::basic_string
 
template<class Operation >
constexprvoid resize_and_overwrite( size_type count, Operation op );
(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:

  1. 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 + kp + count] may have indeterminate values.
  2. Evaluates std::move(op)(p, count), let r be the return value.
  3. Replaces the contents of *this with [pp + r) (which sets the length of *this to r). Invalidates all pointers and references to the range [pp + 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 [0count].
  • Any character in range [pp + 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().

Contents

[edit]Parameters

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

[edit]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.

[edit]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_overwrite202110L(C++23)std::basic_string::resize_and_overwrite

[edit]Example

Link to test the example: compiler explorer.

#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_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{constauto 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{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::string food{"Food:"};constauto 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;conststd::string_view fruit : fruits){char* last = first + fruit.size()+1;if(last > end)break;*first++=' '; std::ranges::copy(fruit, first); first = last;}   constauto 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"

[edit]See also

changes the number of characters stored
(public member function)[edit]
close