A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://doc.rust-lang.org/nightly/core/clone/trait.CloneToUninit.html below:

CloneToUninit in core::clone - Rust

Trait CloneToUninitSource
pub unsafe trait CloneToUninit {
    // Required method
    unsafe fn clone_to_uninit(&self, dest: *mut u8);
}
🔬This is a nightly-only experimental API. (clone_to_uninit #126799) Expand description

A generalization of Clone to dynamically-sized types stored in arbitrary containers.

This trait is implemented for all types implementing Clone, slices of all such types, and other dynamically-sized types in the standard library. You may also implement this trait to enable cloning custom DSTs (structures containing dynamically-sized fields), or use it as a supertrait to enable cloning a trait object.

This trait is normally used via operations on container types which support DSTs, so you should not typically need to call .clone_to_uninit() explicitly except when implementing such a container or otherwise performing explicit management of an allocation, or when implementing CloneToUninit itself.

§Safety

Implementations must ensure that when .clone_to_uninit(dest) returns normally rather than panicking, it always leaves *dest initialized as a valid value of type Self.

§Examples

If you are defining a trait, you can add CloneToUninit as a supertrait to enable cloning of dyn values of your trait:

#![feature(clone_to_uninit)]
use std::rc::Rc;

trait Foo: std::fmt::Debug + std::clone::CloneToUninit {
    fn modify(&mut self);
    fn value(&self) -> i32;
}

impl Foo for i32 {
    fn modify(&mut self) {
        *self *= 10;
    }
    fn value(&self) -> i32 {
        *self
    }
}

let first: Rc<dyn Foo> = Rc::new(1234);

let mut second = first.clone();
Rc::make_mut(&mut second).modify(); assert_eq!(first.value(), 1234);
assert_eq!(second.value(), 12340);

The following is an example of implementing CloneToUninit for a custom DST. (It is essentially a limited form of what derive(CloneToUninit) would do, if such a derive macro existed.)

#![feature(clone_to_uninit)]
use std::clone::CloneToUninit;
use std::mem::offset_of;
use std::rc::Rc;

#[derive(PartialEq)]
struct MyDst<T: ?Sized> {
    label: String,
    contents: T,
}

unsafe impl<T: ?Sized + CloneToUninit> CloneToUninit for MyDst<T> {
    unsafe fn clone_to_uninit(&self, dest: *mut u8) {
        let offset_of_contents = unsafe {
            (&raw const self.contents).byte_offset_from_unsigned(self)
        };

        let label = self.label.clone();

        unsafe {
            self.contents.clone_to_uninit(dest.add(offset_of_contents));

            dest.add(offset_of!(Self, label)).cast::<String>().write(label);
        }
        }
}

fn main() {
    let first: Rc<MyDst<[u8]>> = Rc::new(MyDst {
        label: String::from("hello"),
        contents: [1, 2, 3, 4],
    });

    let mut second = first.clone();
    for elem in Rc::make_mut(&mut second).contents.iter_mut() {
        *elem *= 10;
    }

    assert_eq!(first.contents, [1, 2, 3, 4]);
    assert_eq!(second.contents, [10, 20, 30, 40]);
    assert_eq!(second.label, "hello");
}
§See Also Source 🔬This is a nightly-only experimental API. (clone_to_uninit #126799)

Performs copy-assignment from self to dest.

This is analogous to std::ptr::write(dest.cast(), self.clone()), except that Self may be a dynamically-sized type (!Sized).

Before this function is called, dest may point to uninitialized memory. After this function is called, dest will point to initialized memory; it will be sound to create a &Self reference from the pointer with the pointer metadata from self.

§Safety

Behavior is undefined if any of the following conditions are violated:

§Panics

This function may panic. (For example, it might panic if memory allocation for a clone of a value owned by self fails.) If the call panics, then *dest should be treated as uninitialized memory; it must not be read or dropped, because even if it was previously valid, it may have been partially overwritten.

The caller may wish to take care to deallocate the allocation pointed to by dest, if applicable, to avoid a memory leak (but this is not a requirement).

Implementors should avoid leaking values by, upon unwinding, dropping all component values that might have already been created. (For example, if a [Foo] of length 3 is being cloned, and the second of the three calls to Foo::clone() unwinds, then the first Foo cloned should be dropped.)


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4