| // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| // Exceptions. See /LICENSE for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| use crate::crubit_cc_std_internal::std_allocator; |
| use core::ptr::null_mut; |
| |
| /// A smart pointer that owns and manages another object of type `T` via a |
| /// pointer, ABI-compatible with `std::unique_ptr` using default deleter from |
| /// C++. |
| #[allow(non_snake_case)] |
| #[repr(C)] |
| pub struct unique_ptr<T: Sized> { |
| // Invariants: |
| // 1. `ptr` is either null, or allocated by C++ `new`. |
| // 2. If `ptr` is not null, it is owned by this `unique_ptr`. |
| ptr: *mut T, |
| } |
| |
| impl<T: Sized> unique_ptr<T> { |
| /// Takes ownership of the provided raw pointer. |
| /// |
| /// # Safety |
| /// |
| /// `ptr` must either be null, or allocated by C++ `new`. Otherwise, the |
| /// behavior is undefined. |
| pub unsafe fn new(ptr: *mut T) -> Self { |
| Self { ptr } |
| } |
| |
| pub fn get(&self) -> *mut T { |
| self.ptr |
| } |
| |
| pub fn release(&mut self) -> *mut T { |
| core::mem::replace(&mut self.ptr, null_mut()) |
| } |
| } |
| |
| impl<T> Drop for unique_ptr<T> { |
| fn drop(&mut self) { |
| if !self.ptr.is_null() { |
| unsafe { |
| // SAFETY: a non-null `self.ptr` is a pointer to a `T` allocated with C++ `new`, |
| // which should be satisfied by the constructor. |
| core::ptr::drop_in_place(self.ptr); |
| std_allocator::cpp_delete( |
| self.ptr as _, |
| core::mem::size_of::<T>(), |
| core::mem::align_of::<T>(), |
| ); |
| } |
| } |
| } |
| } |