A Box like type that keeps small objects on the stack and can allocate bigger objects as
Box, Rc or Arc. DerefMut is copy-on-write when the Smox is backed by Rc or Arc
# Rationale
In generic contexts one often does not know how big the objects will be. If they are small
enough
they can be kept on the stack for better performance. If they are bigger they need to be
allocated on the heap. Smox allows to do this in a transparent way.
# Example
```rust
use smox::*;
// For the copy-on-write behavior we need T: Clone
#[derive(Clone)]
struct Generic<T: Clone> {
value: SmoxRc<T, 16>,
}
impl<T: Clone> Generic<T> {
fn new(value: T) -> Self {
Self {
value: SmoxRc::new_rc(value),
}
}
}
fn main() {
// we have the guarantee that Generic<T> will always be at most 16 bytes large.
assert!(std::mem::size_of::<Generic<i32>>() <= 16);
assert!(std::mem::size_of::<Generic<[i32; 100]>>() <= 16);
let mut small = Generic::new(42i32);
*small.value += 1;
assert_eq!(*small.value, 43);
let big = Generic::new([0i32;100]);
// Cheap cloning the underlying Rc
let mut big_clone = big.clone();
// Modifying big_clone will trigger a copy-on-write
big_clone.value[0] = 1;
assert_eq!(big.value[0], 0);
assert_eq!(big_clone.value[0], 1);
}
```