table of contents
        
      
      
    - Tumbleweed 2024.07.05-1.3
 - Leap-16.0
 
| std::basic_string::resize_and_overwrite(3) | C++ Standard Libary | std::basic_string::resize_and_overwrite(3) | 
NAME¶
std::basic_string::resize_and_overwrite - std::basic_string::resize_and_overwrite
Synopsis¶
 template< class Operation > (since C++23)
  
   constexpr void resize_and_overwrite( size_type count, Operation op );
  
   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 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 this->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.
  
   2. Evaluates std::move(op)(p, count). Let r be the return value of
    std::move(op)(p,
  
   count).
  
   3. 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].
  
   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.
  
   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)
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 Value Std Feature __cpp_lib_string_resize_and_overwrite
    202110L (C++23) std::basic_string::resize_and_overwrite
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)
| 2024.06.10 | http://cppreference.com |