Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::basic_...nd_overwrite(3) C++ Standard Libarystd::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
       character in the
	      storage.
		 * The equality	is determined as  if  by  checking  this->com-
       pare(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 al-
       locations by,
	  e.g.,	making p equal to the pointer to beginning of storage of char-
       acters 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	refer-
       ences into *this,
	  regardless  whether  reallocation occurs. Implementations may	assume
       that the	contents
	  of the string	are not	aliased	after  the  call  to  resize_and_over-
       write.

		Feature-test	    macro		    Value	   Std
       Feature __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
       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)

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

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::u32string::resize_and_overwrite&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help