beef/
lean.rs

1//! Namespace containing the 2-word `Cow` implementation.
2
3use crate::traits::Capacity;
4
5/// Faster, 2-word `Cow`. This version is available only on 64-bit architecture,
6/// and it puts both capacity and length together in a fat pointer. Both length and capacity
7/// is limited to 32 bits.
8///
9/// # Panics
10///
11/// [`Cow::owned`](../generic/struct.Cow.html#method.owned) will panic if capacity is larger than `u32::max_size()`. Use the
12/// top level `beef::Cow` if you wish to avoid this problem.
13pub type Cow<'a, T> = crate::generic::Cow<'a, T, Lean>;
14
15pub(crate) mod internal {
16    #[derive(Clone, Copy, PartialEq, Eq)]
17    pub struct Lean;
18}
19use internal::Lean;
20
21const MASK_LO: usize = u32::MAX as usize;
22const MASK_HI: usize = !MASK_LO;
23
24impl Lean {
25    #[inline]
26    pub const fn mask_len(len: usize) -> usize {
27        len & MASK_LO
28    }
29}
30
31impl Capacity for Lean {
32    type Field = Lean;
33    type NonZero = Lean;
34
35    #[inline]
36    fn len(fat: usize) -> usize {
37        fat & MASK_LO
38    }
39
40    #[inline]
41    fn empty(len: usize) -> (usize, Lean) {
42        (len & MASK_LO, Lean)
43    }
44
45    #[inline]
46    fn store(len: usize, capacity: usize) -> (usize, Lean) {
47        if capacity & MASK_HI != 0 {
48            panic!("beef::lean::Cow: Capacity out of bounds");
49        }
50
51        let fat = ((capacity & MASK_LO) << 32) | (len & MASK_LO);
52
53        (fat, Lean)
54    }
55
56    #[inline]
57    fn unpack(fat: usize, _: Lean) -> (usize, usize) {
58        (fat & MASK_LO, (fat & MASK_HI) >> 32)
59    }
60
61    #[inline]
62    fn maybe(fat: usize, _: Lean) -> Option<Lean> {
63        if fat & MASK_HI != 0 {
64            Some(Lean)
65        } else {
66            None
67        }
68    }
69}