How to implement Clone for array with more than 32 elements?


#1

Hi.

The primitive array type supports Clone only in the case of 32 or less than 32 elements.

I can implement Clone for arrays with more than 32 elements by copying each element,
But I think that it is not efficient. Copying dummy initial value to obtain memory , and copying each element…

I checked std::mem, but there is no memcpy function.

How can I implement efficient Clone for arrays?


#2

It may not be what you meant, but you cannot implement Clone for arrays; only the standard library can do that.

Also, you have to copy each element individually, because:

  • Clone::clone may be arbitrarily complex, so a memcpy will not work.
  • Clone::clone can potentially panic.

You can write a different trait or free function to clone arrays, but it has to be implemented for every size of array individually, and basically consists of cloning each element to a stack variable, then constructing the array in one shot right at the end.


#3

Can you detect at compile time that the data is a POD and use the memcpy in that case?


#4

Well, firstly, POD doesn’t imply trivially copyable, in the sense that you can have a structure that’s POD, but doesn’t implement Copy.

Secondly, you can require a type be Copy, but can’t detect it conditionally; that is, you can’t specify Clone but have a different path for types that are also Copy.


#5

Perhaps a syntax for detecting traits anywhere inside a function can be introduced in Rust (a kind of limited-purpose “static if” to handle it in different paths). This could be useful to lift two Rust limitations.


#6

This is more likely to be addressed by specialisation.


#7

One advantage of “specializing” anywhere inside the body of a function is that you can add common code before and after the specialized part. If you specialize the whole function you risk having some code duplication. And some handy design opportunities are lost.


#8

Sorry for my little understanding.
I should not have mentioned Clone trait, I should have said “clone” method.

My question was, there are any functions like memcpy in the category with replace and swap functions for efficiency?

Or Copy trait for large array may not be efficient in simple case.

I understand your point. Thank you.


#9

Ah. I don’t believe there’s a general, safe memcpy function. The closest would be to write a for loop and hope LLVM lowers it to an actual memcpy call.


#10

What I might want is retep998’s first answer in https://github.com/rust-lang/rust/issues/24288

#[derive(Copy)]
struct Blah {
    array: [i32; LARGE_NUMBER],
    a: SomePrimitive,
    ...
}
impl Clone for Blah { fn clone(&self) -> Blah { *self } }

Amazingly, it works though I don’t know that copying is by memcpy or field by field.