1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! `StaticRc`, resp. `StaticRcRef`, use Rust's affine type system and const generics to track the shared ownership
//!  of a heap-allocated, resp. reference, value safely at compile-time, with no run-time overhead.
//!
//! The amount of `unsafe` used within is minimal, `StaticRc` mostly leverages `Box` for most of the heavy-duty
//! operations.
//!
//! #   Example of usage.
//!
//! ```
//! use static_rc::StaticRc;
//!
//! type Full<T> = StaticRc<T, 3, 3>;
//! type TwoThird<T> = StaticRc<T, 2, 3>;
//! type OneThird<T> = StaticRc<T, 1, 3>;
//!
//! let mut full = Full::new("Hello, world!".to_string());
//!
//! assert_eq!("Hello, world!", &*full);
//!
//! //  Mutation is allowed when having full ownership, just like for `Box`.
//! *full = "Hello, you!".to_string();
//!
//! assert_eq!("Hello, you!", &*full);
//!
//! //  Mutation is no longer allowed from now on, due to aliasing, just like for `Rc`.
//! let (two_third, one_third) = Full::split::<2, 1>(full);
//!
//! assert_eq!("Hello, you!", &*two_third);
//! assert_eq!("Hello, you!", &*one_third);
//!
//! let mut full = Full::join(one_third, two_third);
//!
//! assert_eq!("Hello, you!", &*full);
//!
//! //  Mutation is allowed again, since `full` has full ownership.
//! *full = "Hello, world!".to_string();
//!
//! assert_eq!("Hello, world!", &*full);
//!
//! //  Finally, the value is dropped when `full` is.
//! ```
//!
//! #   Options
//!
//! The crate is defined for `no_std` environment and only relies on `core` and `alloc` by default.
//!
//! The `alloc` crate can be opted out of, though this disables `StaticRc`.
//!
//! The crate only uses stable features by default, with a MSRV of 1.51 due to the use of const generics.
//!
//! Additional, the crate offers several optional features which unlock additional capabilities by using nightly.
//! Please see `Cargo.toml` for an up-to-date list of features, and their effects.

//  Regular features
#![cfg_attr(not(test), no_std)]

//  Nightly features
#![cfg_attr(feature = "compile-time-ratio", allow(incomplete_features))]
#![cfg_attr(feature = "compile-time-ratio", feature(generic_const_exprs))]
#![cfg_attr(feature = "nightly-async-iterator", feature(async_iterator))]
#![cfg_attr(feature = "nightly-coerce-unsized", feature(coerce_unsized))]
#![cfg_attr(feature = "nightly-dispatch-from-dyn", feature(dispatch_from_dyn))]
#![cfg_attr(any(feature = "nightly-dispatch-from-dyn", feature = "nightly-coerce-unsized"), feature(unsize))]
#![cfg_attr(feature = "nightly-generator-trait", feature(generator_trait))]

//  Lints
#![deny(missing_docs)]

#[cfg(feature = "alloc")]
extern crate alloc;

#[macro_use]
mod utils;

pub mod rcref;

pub use self::rcref::StaticRcRef;

#[cfg(feature = "alloc")]
pub mod rc;

#[cfg(feature = "alloc")]
pub use self::rc::StaticRc;

#[cfg(feature = "experimental-lift")]
pub mod lift;

#[cfg(feature = "experimental-lift")]
pub use self::lift::{lift, lift_with, lift_with_mut};