Date: Mon, 18 Dec 2023 12:28:38 +0000
On Sun, Dec 17, 2023, Frederick Virchanza Gotham wrote:
>
> I've written a specialisation of 'std::relocate' for 'std::string':
Although if a container is re-allocating, for example if an
'std::vector' wants to do 'push_back' but hasn't got enough free
space, then it might be more efficient to also have a "relocate_n"
function whose arguments must be correctly aligned, as follows:
https://godbolt.org/z/rPrEcPqb1
And here it is copy-pasted:
template<>
void relocate_n<std::string>(void *const dst, void *const src,
std::size_t n)
{
using T = std::string;
assert( 0u == (reinterpret_cast<std::uintptr_t>(dst) % alignof(T)) );
assert( 0u == (reinterpret_cast<std::uintptr_t>(src) % alignof(T)) );
using std::byte;
// Step 1: Copy all the bytes for the entire array
std::memcpy(dst, src, sizeof(T) * n);
std::ptrdiff_t const delta = static_cast<byte*>(dst) -
static_cast<byte*>(src);
for ( ; n != -1; --n )
{
byte *const addr_of_element = static_cast<byte*>(src)+n*sizeof(T);
// Step 2: Pluck out the pointer (located at offset 0 from 'this')
byte *p = *static_cast<byte**>(static_cast<void*>(addr_of_element));
// Step 3: Check if the pointer points to within the object
if ( (p < addr_of_element) || (p >=
(addr_of_element+__datasizeof(T))) ) continue;
// Step 4: Adjust the pointer at the destination
*static_cast<byte**>(static_cast<void*>(static_cast<T*>(dst)+n))
+= delta;
}
}
>
> I've written a specialisation of 'std::relocate' for 'std::string':
Although if a container is re-allocating, for example if an
'std::vector' wants to do 'push_back' but hasn't got enough free
space, then it might be more efficient to also have a "relocate_n"
function whose arguments must be correctly aligned, as follows:
https://godbolt.org/z/rPrEcPqb1
And here it is copy-pasted:
template<>
void relocate_n<std::string>(void *const dst, void *const src,
std::size_t n)
{
using T = std::string;
assert( 0u == (reinterpret_cast<std::uintptr_t>(dst) % alignof(T)) );
assert( 0u == (reinterpret_cast<std::uintptr_t>(src) % alignof(T)) );
using std::byte;
// Step 1: Copy all the bytes for the entire array
std::memcpy(dst, src, sizeof(T) * n);
std::ptrdiff_t const delta = static_cast<byte*>(dst) -
static_cast<byte*>(src);
for ( ; n != -1; --n )
{
byte *const addr_of_element = static_cast<byte*>(src)+n*sizeof(T);
// Step 2: Pluck out the pointer (located at offset 0 from 'this')
byte *p = *static_cast<byte**>(static_cast<void*>(addr_of_element));
// Step 3: Check if the pointer points to within the object
if ( (p < addr_of_element) || (p >=
(addr_of_element+__datasizeof(T))) ) continue;
// Step 4: Adjust the pointer at the destination
*static_cast<byte**>(static_cast<void*>(static_cast<T*>(dst)+n))
+= delta;
}
}
Received on 2023-12-18 12:28:31