F
Frederick Gotham
If we want to copy an array of POD's, we can simply do:
SomePODType src[8] = { ... }, dest[8];
memcpy(&dest,&src,sizeof dest);
We can assume that this method is definitely faster than (if not at least
as fast as) the following method:
T *p = dest;
T const *const pover = dest + sizeof dest;
T const *q = src;
do *p++ = *q++;
while (pover != p);
This method won't work for class types, because the constructors and
assignment operators may acquire resources and so forth.
The following is a basic attempt to implement a universal method of copy-
constructing an array:
#include <cstddef>
#include <new>
template<class T,std::size_t len>
void CopyCstr(T const (&src)[len],void *const dest)
{
T *p = (T*)dest;
T const *const pover = p + len;
T const *q = src;
do ::new((void*)p++) T(*q++);
while (pover != p);
}
This looks grand, but what happens if we use it to copy-construct an array
of short ints? It will look like as follows:
void CopyCstr(short const (&src)[8],void *const dest)
{
short *p = (short*)dest;
short const *const pover = p + 8;
short const *q = src;
do ::new((void*)p++) short(*q++);
while (pover != p);
}
The only problem with this is that it may not be as efficient as it could
be. We'd be better off with simply:
void CopyCstr(short const (&src)[8],void *const dest)
{
memcpy(dest,src,sizeof src);
}
So I wonder how we can achieve the best of both worlds with the one sole
template function? If we had a way of knowing that the "normal
initialisation" for a particular type was a no-op, then we could take
advantage of it. Something like
template<class T,std::size_t len>
void CopyCstr(T const (&src)[len],void *const dest)
{
if ( NoOp:new(void*) T) ) memcpy(dest,src,sizeof src);
else
{
T *p = (T*)dest;
T const *const pover = p + len;
T const *q = src;
do ::new((void*)p++) T(*q++);
while (pover != p);
}
Obviously, the "if" conditional would be known at compile-time to be either
true or false, the the opposite command path could be done away with.
Anyway, this was just a thought that went through me head...
SomePODType src[8] = { ... }, dest[8];
memcpy(&dest,&src,sizeof dest);
We can assume that this method is definitely faster than (if not at least
as fast as) the following method:
T *p = dest;
T const *const pover = dest + sizeof dest;
T const *q = src;
do *p++ = *q++;
while (pover != p);
This method won't work for class types, because the constructors and
assignment operators may acquire resources and so forth.
The following is a basic attempt to implement a universal method of copy-
constructing an array:
#include <cstddef>
#include <new>
template<class T,std::size_t len>
void CopyCstr(T const (&src)[len],void *const dest)
{
T *p = (T*)dest;
T const *const pover = p + len;
T const *q = src;
do ::new((void*)p++) T(*q++);
while (pover != p);
}
This looks grand, but what happens if we use it to copy-construct an array
of short ints? It will look like as follows:
void CopyCstr(short const (&src)[8],void *const dest)
{
short *p = (short*)dest;
short const *const pover = p + 8;
short const *q = src;
do ::new((void*)p++) short(*q++);
while (pover != p);
}
The only problem with this is that it may not be as efficient as it could
be. We'd be better off with simply:
void CopyCstr(short const (&src)[8],void *const dest)
{
memcpy(dest,src,sizeof src);
}
So I wonder how we can achieve the best of both worlds with the one sole
template function? If we had a way of knowing that the "normal
initialisation" for a particular type was a no-op, then we could take
advantage of it. Something like
template<class T,std::size_t len>
void CopyCstr(T const (&src)[len],void *const dest)
{
if ( NoOp:new(void*) T) ) memcpy(dest,src,sizeof src);
else
{
T *p = (T*)dest;
T const *const pover = p + len;
T const *q = src;
do ::new((void*)p++) T(*q++);
while (pover != p);
}
Obviously, the "if" conditional would be known at compile-time to be either
true or false, the the opposite command path could be done away with.
Anyway, this was just a thought that went through me head...