unique_ptr/
lib.rs

1use std::mem;
2
3pub struct DefaultDelete<T> {
4    _marker: std::marker::PhantomData<T>,
5}
6
7impl<T> DefaultDelete<T> {
8    pub fn new() -> Self {
9        DefaultDelete { _marker: std::marker::PhantomData }
10    }
11}
12
13impl<T> Default for DefaultDelete<T> {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19pub struct UniquePtr<T, Deleter = DefaultDelete<T>> {
20    pub ptr: *mut T,
21    pub deleter: Deleter,
22}
23
24impl<T> UniquePtr<T> {
25    pub fn new() -> Self {
26        UniquePtr { ptr: std::ptr::null_mut(), deleter: DefaultDelete::new() }
27    }
28
29    pub fn with_ptr(ptr: *mut T) -> Self {
30        UniquePtr { ptr, deleter: DefaultDelete::new() }
31    }
32}
33
34impl<T, Deleter> Drop for UniquePtr<T, Deleter> {
35    fn drop(&mut self) {
36        unsafe {
37            Box::from_raw(self.ptr);
38        }
39    }
40}
41
42impl<T, Deleter> Clone for UniquePtr<T, Deleter> where Deleter: Clone,
43{
44    fn clone(&self) -> Self {
45        Self::with_ptr_and_deleter(self.ptr, self.deleter.clone())
46    }
47}
48
49impl<T, Deleter> UniquePtr<T, Deleter> {
50    pub fn reset(&mut self, ptr: *mut T) {
51        unsafe {
52            Box::from_raw(self.ptr);
53        }
54        self.ptr = ptr;
55    }
56
57    pub fn release(&mut self) -> *mut T {
58        let old_ptr = self.ptr;
59        self.ptr = std::ptr::null_mut();
60        old_ptr
61    }
62
63    pub fn swap(&mut self, other: &mut Self) {
64        mem::swap(&mut self.ptr, &mut other.ptr);
65        mem::swap(&mut self.deleter, &mut other.deleter);
66    }
67
68    pub fn get(&self) -> *mut T {
69        self.ptr
70    }
71
72    pub fn with_ptr_and_deleter(ptr: *mut T, deleter: Deleter) -> Self {
73        UniquePtr { ptr, deleter }
74    }
75}
76
77impl<T, Deleter> std::ops::Deref for UniquePtr<T, Deleter> {
78    type Target = T;
79
80    fn deref(&self) -> &Self::Target {
81        unsafe { &*self.ptr }
82    }
83}
84
85impl<T, Deleter> std::ops::DerefMut for UniquePtr<T, Deleter> {
86    fn deref_mut(&mut self) -> &mut Self::Target {
87        unsafe { &mut *self.ptr }
88    }
89}
90
91impl<T, Deleter> UniquePtr<T, Deleter> {
92    pub fn get_deleter(&self) -> &Deleter {
93        &self.deleter
94    }
95}
96
97impl<T, Deleter> From<UniquePtr<T, Deleter>> for Option<Box<T>> {
98    fn from(ptr: UniquePtr<T, Deleter>) -> Self {
99        if ptr.ptr.is_null() {
100            None
101        } else {
102            Some(unsafe { Box::from_raw(ptr.ptr) })
103        }
104    }
105}
106
107impl<T> UniquePtr<T, DefaultDelete<T>> {
108    pub fn into_raw(self) -> *mut T {
109        let ptr = self.ptr;
110        mem::forget(self);
111        ptr
112    }
113
114    pub fn from_raw(ptr: *mut T) -> Self {
115        UniquePtr::with_ptr(ptr)
116    }
117}
118
119#[cfg(test)]
120mod tests {
121    use super::*;
122
123    #[test]
124    fn test_unique_ptr_creation() {
125        let ptr = Box::into_raw(Box::new(42));
126        let unique_ptr = UniquePtr::with_ptr(ptr);
127
128        assert_eq!(unsafe { *unique_ptr.ptr }, 42);
129    }
130
131    #[test]
132    fn test_unique_ptr_reset() {
133        let ptr1 = Box::into_raw(Box::new(42));
134        let mut unique_ptr = UniquePtr::with_ptr(ptr1);
135
136        let ptr2 = Box::into_raw(Box::new(99));
137        unique_ptr.reset(ptr2);
138
139        assert_eq!(unsafe { *unique_ptr.ptr }, 99);
140    }
141
142    #[test]
143    fn test_unique_ptr_release() {
144        let ptr = Box::into_raw(Box::new(42));
145        let mut unique_ptr = UniquePtr::with_ptr(ptr);
146
147        let released_ptr = unique_ptr.release();
148
149        assert_eq!(unsafe { *Box::from_raw(released_ptr) }, 42);
150    }
151
152    #[test]
153    fn test_unique_ptr_deref() {
154        let ptr = Box::into_raw(Box::new(42));
155        let unique_ptr = UniquePtr::with_ptr(ptr);
156
157        assert_eq!(unsafe { *unique_ptr.ptr }, 42);
158    }
159}