smart_ptr/
lib.rs

1//!Smart pointers for Rust
2//!
3//!## Features
4//!
5//!- `alloc` Enables usage of `alloc` crate
6
7#![no_std]
8#![warn(missing_docs)]
9#![cfg_attr(feature = "cargo-clippy", allow(clippy::style))]
10
11#[cfg(feature = "alloc")]
12extern crate alloc;
13
14///Describes how to de-allocate pointer.
15pub trait Deleter {
16    ///This function is called on `Drop`
17    unsafe fn delete<T: ?Sized>(ptr: *mut T);
18}
19
20impl Deleter for () {
21    #[inline(always)]
22    unsafe fn delete<T: ?Sized>(_: *mut T) {}
23}
24
25#[cfg(feature = "alloc")]
26///Default Rust deleter.
27///
28///Invokes destructor and de-allocates memory using global allocator, using Box.
29///
30///It can be useful when one would want to allow type erasure,
31///but it is UB to specify invalid `T`
32///
33///```rust
34///use smart_ptr::Unique;
35///
36///let var = Box::new("test".to_string());
37///unsafe {
38///    smart_ptr::boxed_deleter::<String>(Box::leak(var) as *mut String);
39///}
40///```
41///
42///## Warning
43///
44///Remember that things can get complicated when you cast from fat ptrs(with vtable)
45pub unsafe fn boxed_deleter<T: ?Sized>(ptr: *mut T) {
46    debug_assert!(!ptr.is_null());
47
48    let _  = alloc::boxed::Box::from_raw(ptr);
49}
50
51#[derive(Default)]
52///Deleter which uses global allocator via `Box`.
53///
54///It uses type information, provided as type parameter of `Deleter::delete` to re-create `Box` and
55///destruct it
56///
57///Therefore user must guarantee that pointer was created with the same type information
58pub struct GlobalDeleter;
59
60#[cfg(feature = "alloc")]
61impl Deleter for GlobalDeleter {
62    #[inline]
63    unsafe fn delete<T: ?Sized>(ptr: *mut T) {
64        boxed_deleter::<T>(ptr)
65    }
66}
67
68pub mod unique;
69pub use unique::Unique;