home | help
std::basic_...nd_overwrite(3)  C++ Standard Libary std::basic_...nd_overwrite(3)

NAME
     std::basic_string::resize_and_overwrite	   -	  std::basic_string::re-
     size_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 charac-
     ter 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 alloca-
     tions by,
	e.g., making p equal to the pointer to beginning of storage  of  charac-
     ters 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		    Fea-
     ture   __cpp_lib_string_resize_and_overwrite   202110L   (C++23)	std::ba-
     sic_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 in-
     creased.
	  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 in-
     voked.
	  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 co-
     conut"

See also
	resize changes the number of characters stored
	       (public member function)

http://cppreference.com 	   2024.06.10	   std::basic_...nd_overwrite(3)

home | help