• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::ops::{Deref, DerefMut};
2 use core::fmt;
3 
4 #[cfg(feature = "std")]
5 use std::boxed::Box;
6 #[cfg(all(feature = "alloc", not(feature = "std")))]
7 use alloc::boxed::Box;
8 #[cfg(feature = "std")]
9 use std::vec::Vec;
10 #[cfg(all(feature = "alloc", not(feature = "std")))]
11 use alloc::vec::Vec;
12 
13 /// A managed slice.
14 ///
15 /// This enum can be used to represent exclusive access to slices of objects.
16 /// In Rust, exclusive access to an object is obtained by either owning the object,
17 /// or owning a mutable pointer to the object; hence, "managed".
18 ///
19 /// The purpose of this enum is providing good ergonomics with `std` present while making
20 /// it possible to avoid having a heap at all (which of course means that `std` is not present).
21 /// To achieve this, the variants other than `Borrowed` are only available when the corresponding
22 /// feature is opted in.
23 ///
24 /// A function that requires a managed object should be generic over an `Into<ManagedSlice<'a, T>>`
25 /// argument; then, it will be possible to pass either a `Vec<T>`, or a `&'a mut [T]`
26 /// without any conversion at the call site.
27 ///
28 /// See also [Managed](enum.Managed.html).
29 pub enum ManagedSlice<'a, T: 'a> {
30     /// Borrowed variant.
31     Borrowed(&'a mut [T]),
32     /// Owned variant, only available with the `std` or `alloc` feature enabled.
33     #[cfg(any(feature = "std", feature = "alloc"))]
34     Owned(Vec<T>)
35 }
36 
37 impl<'a, T: 'a> fmt::Debug for ManagedSlice<'a, T>
38         where T: fmt::Debug {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result39     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40         match self {
41             &ManagedSlice::Borrowed(ref x) => write!(f, "Borrowed({:?})", x),
42             #[cfg(any(feature = "std", feature = "alloc"))]
43             &ManagedSlice::Owned(ref x)    => write!(f, "Owned({:?})", x)
44         }
45     }
46 }
47 
48 impl<'a, T: 'a> From<&'a mut [T]> for ManagedSlice<'a, T> {
from(value: &'a mut [T]) -> Self49     fn from(value: &'a mut [T]) -> Self {
50         ManagedSlice::Borrowed(value)
51     }
52 }
53 
54 macro_rules! from_unboxed_slice {
55     ($n:expr) => (
56         impl<'a, T> From<[T; $n]> for ManagedSlice<'a, T> {
57             #[inline]
58             fn from(value: [T; $n]) -> Self {
59                 ManagedSlice::Owned((Box::new(value) as Box<[T]>).into_vec())
60             }
61         }
62     );
63     ($n:expr, $( $r:expr ),*) => (
64         from_unboxed_slice!($n);
65         from_unboxed_slice!($( $r ),*);
66     )
67 }
68 
69 #[cfg(any(feature = "std", feature = "alloc"))]
70 from_unboxed_slice!(0,  1,   2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
71                     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
72 
73 #[cfg(any(feature = "std", feature = "alloc"))]
74 impl<'a, T: 'a> From<Vec<T>> for ManagedSlice<'a, T> {
from(value: Vec<T>) -> Self75     fn from(value: Vec<T>) -> Self {
76         ManagedSlice::Owned(value)
77     }
78 }
79 
80 impl<'a, T: 'a> Deref for ManagedSlice<'a, T> {
81     type Target = [T];
82 
deref(&self) -> &Self::Target83     fn deref(&self) -> &Self::Target {
84         match self {
85             &ManagedSlice::Borrowed(ref value) => value,
86             #[cfg(any(feature = "std", feature = "alloc"))]
87             &ManagedSlice::Owned(ref value) => value
88         }
89     }
90 }
91 
92 impl<'a, T: 'a> DerefMut for ManagedSlice<'a, T> {
deref_mut(&mut self) -> &mut Self::Target93     fn deref_mut(&mut self) -> &mut Self::Target {
94         match self {
95             &mut ManagedSlice::Borrowed(ref mut value) => value,
96             #[cfg(any(feature = "std", feature = "alloc"))]
97             &mut ManagedSlice::Owned(ref mut value) => value
98         }
99     }
100 }
101