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};