summaryrefslogtreecommitdiffstats
path: root/library/alloc/src/collections/btree/mem.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/alloc/src/collections/btree/mem.rs')
-rw-r--r--library/alloc/src/collections/btree/mem.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/library/alloc/src/collections/btree/mem.rs b/library/alloc/src/collections/btree/mem.rs
new file mode 100644
index 000000000..e1363d1ae
--- /dev/null
+++ b/library/alloc/src/collections/btree/mem.rs
@@ -0,0 +1,35 @@
+use core::intrinsics;
+use core::mem;
+use core::ptr;
+
+/// This replaces the value behind the `v` unique reference by calling the
+/// relevant function.
+///
+/// If a panic occurs in the `change` closure, the entire process will be aborted.
+#[allow(dead_code)] // keep as illustration and for future use
+#[inline]
+pub fn take_mut<T>(v: &mut T, change: impl FnOnce(T) -> T) {
+ replace(v, |value| (change(value), ()))
+}
+
+/// This replaces the value behind the `v` unique reference by calling the
+/// relevant function, and returns a result obtained along the way.
+///
+/// If a panic occurs in the `change` closure, the entire process will be aborted.
+#[inline]
+pub fn replace<T, R>(v: &mut T, change: impl FnOnce(T) -> (T, R)) -> R {
+ struct PanicGuard;
+ impl Drop for PanicGuard {
+ fn drop(&mut self) {
+ intrinsics::abort()
+ }
+ }
+ let guard = PanicGuard;
+ let value = unsafe { ptr::read(v) };
+ let (new_value, ret) = change(value);
+ unsafe {
+ ptr::write(v, new_value);
+ }
+ mem::forget(guard);
+ ret
+}