Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old November 15th, 2006, 11:25 AM
Frederick Gotham
Guest
 
Posts: n/a
Default Array CopyConstruct as efficiently as possible


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...

--

Frederick Gotham
  #2  
Old November 15th, 2006, 11:55 AM
Pete Becker
Guest
 
Posts: n/a
Default Re: Array CopyConstruct as efficiently as possible

Frederick Gotham wrote:
Quote:
>
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.
>
std::tr1::has_trivial_copy gives you that information.

// sketch, untested:

template <class Ty, bool>
struct copier
{ /* element by element copy */
static void init(Ty *tgt,
const Ty *src, unsigned count);
};

template <class Ty>
struct copier<Ty, true>
{ /* byte copy */
static void init(Ty *tgt, const Ty *src, unsigned count);
};

void init(Ty *tgt, const Ty *src, unsigned count)
{
copier<Ty, has_trivial_copy<Ty>::value::
init(tgt, src, count);
}

For a complete example (using assignment, not construction), see listing
8 in the section "Type Traits" in my article at
http://www.ddj.com/dept/cpp/184401964 (limited access, unfortunately).

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles