title: Type-Safe C++ wrapper for memcpy?
body: <p>Given that <a href="http://en.cppreference.com/w/cpp/algorithm/copy" rel="nofollow noreferrer"><code>std::copy</code></a> (for Trivial Types obviously) can only be implemented as a wrapper around <a href="http://en.cppreference.com/w/cpp/string/byte/memmove" rel="nofollow noreferrer">memmove</a>(*), I'm wondering:</p>
  
  <ul>
  <li>Is there a Standard C++ type-safe wrapper for the times you need <code>memcpy</code>? (I can't count the number of times I forgot to multiply by <code>sizeof</code>.)</li>
  <li>If there's nothing in the standard, have there been any proposals for this? If not, why not?</li>
  <li>Are there any specific obstacles in providing a <code>memcpy</code> wrapper that does the <code>sizeof</code> multiplication automatically?</li>
  </ul>
  
  <hr>
  
  <p>(*): C++ Standard Library implementations (from back MSVC 2005(!) up to modern MSVC2015, libc++ etc.) decay <code>std::copy</code> TriviallyCopyable types to <code>memmove</code>. Bot <strong>not</strong> to <code>memcpy</code>. Because:</p>
  
  <ul>
  <li><p><code>std::copy(src_first, src_last, destination_first)</code> defines that:</p>
  
  <blockquote>
    <p>The behavior is undefined if <code>d_first</code> is within the range <code>[first, last)</code>.</p>
  </blockquote>
  
  <ul>
  <li>Only the <em>beginning</em> of the destination range MUST NOT be within the source range. The destination range <em>is allowed</em> to extend into the source range. That is, <code>d_first</code> can be "to the left" of the source range, and the destination range can extend into the source range.</li>
  </ul></li>
  <li><p>For <code>std::memcpy</code> the definition is that</p>
  
  <blockquote>
    <p>If the objects overlap, the behavior is undefined.</p>
  </blockquote>
  
  <ul>
  <li>That is, the full ranges must not overlap: This is what allows memcpy to be the fastest variant, because it can just assume that the memory of source and destination is completely disjoint.</li>
  </ul></li>
  <li><p>For <code>std::memmove</code>, the definition is:</p>
  
  <blockquote>
    <p>The objects may overlap: copying takes place as if the characters were copied to a temporary character array and then the characters were copied from the array to dest.</p>
  </blockquote>
  
  <ul>
  <li>That is, the source and destination range may arbitrarily overlap, there is no restriction.</li>
  </ul></li>
  </ul>
  
  <p>Given this, it is clear that you can use <code>std::memove</code> to implement <code>std::copy</code> for TrivialllyCopyable types, because memmove doesn't impose any restrictions and the dispatch to the correct implementation can be done at compile time via type traits --</p>
  
  <p>but it's hard to implement <code>std::copy</code> in terms of <code>memcpy</code> because (a) the check whether the pointer ranges overlap would have to be done <em>at run time</em>, and (b) even implementing the runtime check for unrelated memory ranges <a href="https://stackoverflow.com/q/4657976/321013">could be quite a mess</a>.</p>
  
  <p>So, this leaves us with </p>
  
  <pre><code>void* memcpy( void* dest, const void* src, std::size_t count );
  </code></pre>
  
  <p>a function with a less than stellar interface, where you constantly need to multiply the input count of non-char objects with their <code>sizeof</code> and that is totally untyped.</p>
  
  <p>But memcpy is fastest (and by quite a margin, measure it yourself), and when you need fast copies of TriviallyCopyable types, you reach for memcpy. Which <em>superficially</em> should be easy to wrap in a type safe wrapper like:</p>
  
  <pre><code>template&lt;typename T&gt;
  T* trivial_copy(T* dest, T* src, std::size_t n) {
      return static_cast&lt;T*&gt;(std::memcpy(dest, src, sizeof(T) * n));
  }
  </code></pre>
  
  <p>but then, it's unclear wether you should do compile time checks via <code>std::is_trival</code> or somesuch and of course there may be some discussion whether to go with the exact <code>memcpy</code> signature order, yadda yadda.</p>
  
  <p>So do I really have to reinvent this wheel myself? Was it discussed for the standard? Etc.</p>
  
  <hr>