Alternative to memcpy in C++?

Started by
25 comments, last by The C modest god 20 years, 2 months ago
quote:Original post by Lord Bart
That is the problem, specialization it can''t!

You are wrong.

quote:std:copy does not have the info needed in order to determine if it can specialize to a memcpy.

Of course it does.

quote:It is a templated function and is made as generic as possible to work with all std container classes and arrary of classes/structures or primitives.

It is precisely through being a function template that it knows enough.

quote:How is it to know it was passed only primitives?

Because it can see the types being used. It can see, for example, that the input range is defined by pointers to primitives and likewise the output range.

quote:
So the only hope it has to work with all things passed to it is to do a loop with assignment on each element.

Be quiet.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/
Advertisement
Hello SabreMan,

I know about template specialization, but then that is a hassel unto it self.
Yes you can go right ahead and create your own specialization of copy for floats/ints (primitives) but then it is not part of the std template copy.
I haven’t every seen a std::copy template specialization for primitives, maybe there is one, but on the systems I seen std::copy on there is none.
It is up to the programmer to do it.

I don''t realy use gcc (at work it is DEC,SUN and MS compilers, though we been trying to push for use of gcc).
If the gcc compiler can correctly make a template specialization to use memcpy for primitives, well that is another reason to ask agian we start to use it.

Now that brings up porting, depending on how your compiler creates templates you might have to do some extra work to make sure your use the specialization and not the std::copy. (DEC compiler is real bad about template instantiations)

So I guess if not using gcc compiler, start to use it , otherwise loop with assignment of each element would be what you get unless your compiler can do what gcc can.
That is why I said be careful of std::copy.
Or create your own specialization copy for that primitive.

Lord Bart
quote:Original post by DrPizza
quote:Original post by Lord Bart
That is the problem, specialization it can't!

You are wrong.

quote:std:copy does not have the info needed in order to determine if it can specialize to a memcpy.

Of course it does.

quote:It is a templated function and is made as generic as possible to work with all std container classes and arrary of classes/structures or primitives.

It is precisely through being a function template that it knows enough.

quote:How is it to know it was passed only primitives?

Because it can see the types being used. It can see, for example, that the input range is defined by pointers to primitives and likewise the output range.

quote:
So the only hope it has to work with all things passed to it is to do a loop with assignment on each element.

Be quiet.



Hello DrPizza,

I never said it could not be specialized, I guess what I should have said is this.
The std::copy in algorithm does not have specialization templates for primatives.

Yes I poorly worded post for your other points and you are correct, and I agree .

I was trying to say is if you just included algorithm and use the copy that is in it you would only get the std:copy that does loop and assignments. Unless your using gcc, which looks like it can create the specialization usinf memcpy automatically.

So unless your compiler is real good(gcc seems to be) or you create your own specialization template for the primitive you want, you should get the loop and assignment std::copy if you include algorithm, right?

Lord Bart


[edited by - lord bart on February 16, 2004 1:07:31 PM]
It''s not up to the compiler; it''s up to the library implementation.

g++''s implementation uses memmove() if it can, though it is actually wrong to do this. std::copy() is allowed to clobber things in overlapping ranges; there''s std::copy_backward() to deal with overlapping ranges -- that should use memmove().
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/
quote:Original post by SabreMan
The compiler has the information, and the Standard Library implementer can use that information to create specialisations of memcpy.
I wonder...

That works alright for primitives, but what about PODs? AFAIK, there is no way for a regular programmer to determine at compile-time if a class has a non-trivial copy-constructor, but the compiler can make this kind of deduction. Is a Standard Library implementation allowed to make use of internal info given by the compiler to transform a std::copy(some_pod) into a mem_cpy?

Or perhaps, are there compilers smart enough to recognize a for loop that copies every member of every object one by one (if the copy constructor is inlined in the std::copy), and turn that into a mem_cpy?

Cédric
quote:Or perhaps, are there compilers smart enough to recognize a for loop that copies every member of every object one by one (if the copy constructor is inlined in the std::copy), and turn that into a mem_cpy?


Yes.

quote:I haven’t every seen a std::copy template specialization for primitives, maybe there is one, but on the systems I seen std::copy on there is none.
It is up to the programmer to do it.


Users are denied the privilidge of adding to namespace std. You would have to add the specilization to the standard header itself, and that is not a very good idea.

You shouldn''t be ditching memcpy though - it does still have it''s uses. I use it quite a bit in the typeless world of binary datafiles.
quote:That works alright for primitives, but what about PODs? AFAIK, there is no way for a regular programmer to determine at compile-time if a class has a non-trivial copy-constructor, but the compiler can make this kind of deduction. Is a Standard Library implementation allowed to make use of internal info given by the compiler to transform a std::copy(some_pod) into a mem_cpy?

I believe so -- if a compiler offered, for example, some traits extension that allowed one to determine the PODness of a class it would be fair game to use it. I think the standard library could be implemented entirely in terms of magic, if a vendor so chose.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/

This topic is closed to new replies.

Advertisement