diff --git a/inout/CHANGELOG.md b/inout/CHANGELOG.md index a10d6fc2..494b02f2 100644 --- a/inout/CHANGELOG.md +++ b/inout/CHANGELOG.md @@ -12,11 +12,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `InOut::into_out` and `InOutBufReserved::into_out` methods ([#1132]) - `InOutBufReserved::split_reserved` method ([#1133]) +- `InOut::into_out_with_copied_in` and `InOutBuf::into_out_with_copied_in` methods ([#1169]) [#944]: https://github.com/RustCrypto/utils/pull/944 [#1132]: https://github.com/RustCrypto/utils/pull/1132 [#1132]: https://github.com/RustCrypto/utils/pull/1132 [#1149]: https://github.com/RustCrypto/utils/pull/1149 +[#1169]: https://github.com/RustCrypto/utils/pull/1169 ## 0.1.4 (2025-02-21) ### Fixed diff --git a/inout/src/inout.rs b/inout/src/inout.rs index 20f5471e..6d0a05f0 100644 --- a/inout/src/inout.rs +++ b/inout/src/inout.rs @@ -33,6 +33,24 @@ impl<'inp, 'out, T> InOut<'inp, 'out, T> { unsafe { &mut *self.out_ptr } } + /// Consume `self` and get mutable reference to the output value with lifetime `'out` + /// and output value equal to the input value. + /// + /// In the case if the input and output references are the same, simply returns + /// the output reference. Otherwise, copies data from the former to the latter + /// before returning the output reference. + pub fn into_out_with_copied_in(self) -> &'out mut T + where + T: Copy, + { + if self.in_ptr != self.out_ptr { + unsafe { + ptr::copy(self.in_ptr, self.out_ptr, 1); + } + } + unsafe { &mut *self.out_ptr } + } + /// Consume `self` and get mutable reference to the output value with lifetime `'out`. #[inline(always)] pub fn into_out(self) -> &'out mut T { diff --git a/inout/src/inout_buf.rs b/inout/src/inout_buf.rs index e573b34d..618d0102 100644 --- a/inout/src/inout_buf.rs +++ b/inout/src/inout_buf.rs @@ -121,6 +121,24 @@ impl<'inp, 'out, T> InOutBuf<'inp, 'out, T> { unsafe { slice::from_raw_parts_mut(self.out_ptr, self.len) } } + /// Consume `self` and get the output slice with lifetime `'out` filled with data from + /// the input slice. + /// + /// In the case if the input and output slices point to the same memory, simply returns + /// the output slice. Otherwise, copies data from the former to the latter + /// before returning the output slice. + pub fn into_out_with_copied_in(self) -> &'out mut [T] + where + T: Copy, + { + if self.in_ptr != self.out_ptr { + unsafe { + core::ptr::copy(self.in_ptr, self.out_ptr, self.len); + } + } + unsafe { slice::from_raw_parts_mut(self.out_ptr, self.len) } + } + /// Consume `self` and get output slice with lifetime `'out`. #[inline(always)] pub fn into_out(self) -> &'out mut [T] {