//! The [`Token`] trait and its common patterns.
//!
//! A token is a zero-sized type, at most one instance of which ever exists.
//! This concept is ubiquitous in Drone. It is used for representing
//! memory-mapped registers, threads, one-time initializers, mutable statics
//! ownership. While affinity (also called move-semantics in Rust) could be
//! represented by Rust type-system, the other properties couldn't. Therefore
//! the concept relies on the two `unsafe` contracts below.
//!
//! 1. *Implementing* the trait is `unsafe`, and it is the implementer
//! responsibility to ensure the following:
//!
//! * The type must not implement [`Clone`].
//! * The type must be instantiated only inside [`Token::take`] method.
//! * The type must be zero-sized.
//!
//! 2. *Calling* [`Token::take`] is `unsafe`, and it is the caller
//! responsibility to ensure that at most one instance of the type ever exists.
//!
//! Tokens are often nested to minimize the usage of `unsafe` [`Token::take`]
//! constructor. It is supposed to instantiate all needed tokens at the very
//! beginning of the program and pass the instances further to the code.
//!
//! Since tokens are zero-sized, [`Token::take`] is no-op from the assembly
//! perspective. Likewise passing the instance around doesn't consume the stack,
//! and storing the instance inside other types doesn't consume the memory.
//!
//! # Simple Tokens
//!
//! Here is a usage example of tokens of their simplest form - `simple_token!`
//! macro. In this example we implement one-timer initializers.
//!
//! ```
//! use drone_core::token::{simple_token, unsafe_simple_tokens, Token};
//!
//! simple_token! {
//! /// The token for Foo initializer.
//! pub struct FooInitToken;
//! }
//!
//! simple_token! {
//! /// The token for Bar initializer.
//! pub struct BarInitToken;
//! }
//!
//! // Here is `unsafe`, we need to ensure that `FooInitToken` and `BarInitToken`
//! // are not used anywhere else.
//! unsafe_simple_tokens! {
//! /// The group token for all initializers.
//! pub struct Inits {
//! FooInitToken,
//! BarInitToken,
//! }
//! }
//!
//! // Define one-time initializers. They should accept tokens by-value and
//! // shouldn't return them.
//!
//! fn init_foo(token: FooInitToken) {
//! // Initialize Foo.
//! }
//!
//! fn init_bar(token: BarInitToken) {
//! // Initialize Bar.
//! }
//!
//! // Your entry point.
//! fn main() {
//! // Various unsafe initializations goes here.
//! unsafe {
//! // Calling unsafe `take()`, we need to ensure that it is the only place
//! // we call it and we are not in a cycle or recursion.
//! let ini = Inits::take();
//! // Pass the token instance to your safe entry point.
//! trunk(ini);
//! }
//! }
//!
//! fn trunk(ini: Inits) {
//! init_foo(ini.foo_init);
//! init_bar(ini.bar_init);
//! // Calling them again won't compile, because the tokens were consumed.
//! // init_foo(ini.foo_init);
//! // init_bar(ini.bar_init);
//! }
//! ```
//!
//! # Static Tokens
//!
//! Mutable statics are unsafe in Rust. One way to make them safe is to use
//! interior-mutability. For example [`Mutex`](crate::sync::mutex::Mutex)
//! ensures that concurrent access to the data is safe. If you don't need
//! simultaneous access to the static but still need other static
//! characteristics like known and stable address, you can use static tokens:
//!
//! ```
//! use drone_core::token::{unsafe_static_tokens, StaticToken, Token};
//!
//! // Define some statics.
//! static mut FOO: usize = 0;
//! static mut BAR: &str = "data";
//!
//! // Here is `unsafe`, we need to ensure that `FOO` and `BAR` are not used
//! // anywhere else.
//! unsafe_static_tokens! {
//! /// The group token for all statics.
//! pub struct Statics {
//! FOO: usize,
//! BAR: &'static str,
//! }
//! }
//!
//! // Your entry point.
//! fn main() {
//! // Various unsafe initializations goes here.
//! unsafe {
//! // Calling unsafe `take()`, we need to ensure that it is the only place
//! // we call it and we are not in a cycle or recursion.
//! let stc = Statics::take();
//! // Pass the token instance to your safe entry point.
//! trunk(stc);
//! }
//! }
//!
//! fn trunk(mut stc: Statics) {
//! // Borrow a mutable reference.
//! add_one(stc.foo.get());
//! add_one(stc.foo.get());
//! assert_eq!(*stc.foo.get(), 2);
//! assert_eq!(core::mem::size_of_val(&stc), 0);
//! // Permanently convert to `&'static usize`. Note that `foo` is no longer a ZST.
//! let foo = stc.foo.into_static();
//! // Calling it again won't compile, because the token was consumed.
//! // let foo = stc.foo.into_static();
//! }
//!
//! fn add_one(foo: &mut usize) {
//! *foo += 1;
//! }
//! ```
/// Defines a new simple [`Token`].
///
/// See [the module-level documentation](self) for details.
pub use simple_token;
/// Defines a new token for the set of simple [`Token`]s.
///
/// See [the module-level documentation](self) for details.
///
/// # Safety
///
/// The tokens must not be instantiated anywhere else.
pub use unsafe_simple_tokens;
/// Defines a new token for the set of [`StaticToken`]s.
///
/// See [the module-level documentation](self) for details.
///
/// # Safety
///
/// The tokens must not be instantiated anywhere else.
pub use unsafe_static_tokens;
/// A zero-sized affine type, at most one instance of which ever exists.
///
/// The above properties can't be expressed with Rust type-system, therefore the
/// trait is marked `unsafe`, and it is the implementer responsibility to keep
/// the following invariants:
///
/// 1. The type must not implement [`Clone`].
/// 2. The type must be instantiated only inside [`Token::take`] method.
/// 3. The type must be zero-sized.
pub unsafe
/// A token for a mutable static variable.
///
/// See [the module-level documentation](self) for details.
///
/// # Safety
///
/// * The type must not implement [`Sync`].
/// * The target static must not be used anywhere else.
pub unsafe