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}