I have two values v1 and v2 of types T1 and T2 respectively, with sizeof(T1)>sizeof(T2). Both types are plain-old-data. Now, I want to replace the k'th, k+1'th, ... k+sizeof(T2)-1'th bytes of v1 with the bytes of v2.
C++ doesn't offer this functionality inherently in the language, nor to my knowledge in the standard library (at least, not directly). What would be the best approach to implementing this generically? i.e. implementing:
template<typename T1, typename T2>
void replace_bytes(T1& v1, T2 v2, std::size_t k)
or at least
template<typename T1, typename T2, std::size_t k>
void replace_bytes(T1& v1, T2 v2)
?
My thoughts have been:
- Reinterpret cast into arrays of bytes
- Reinterpret cast into std::array of bytes
- Use spans
- Pointer arithmetic with the address of v1
- For not-so-large types - reinterpret as unsigned integers and use bit operations: AND with a mask, shift, OR to combine the existing and replacement bits.
Notes:
- Of course if
k
is too high there will be UB here (or we could check it isn't too high). - You may assume for the sake of simplicity that memory layout is little-endian.
- If alignment is an issue, be explicit about your choices regarding it.
- Efficiency/speed is of course a key issue.
- If your suggestion requires a newer C++ language standard, that's fine, but do mention it.
- It is important for the code be well-optimized during compilation.
Clean version of code (no comments):
The following works for T1 sizes upto 8 bytes, and seems to get optimized well enough on GCC, clang and MSVC - at least when inlining:
but I feel it's better to avoid out-parameters - and indeed, doing so allows the function implementation to be strictly in-registers: