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
90
91
92
93
94
95
96
97
98
99
100
//! Hierarchy of traits for abstracting over different types of pointers and their capabilities.
//!
//! The hierarchy is as follows:
//! * [`Pointer`]: Base trait for any heap-allocated pointer.
//! * [`RefCountedPointer`][super::ref_counted_pointer::RefCountedPointer]: Extension for pointers that allow shared ownership (cloning).
//! * [`SendRefCountedPointer`][super::send_ref_counted_pointer::SendRefCountedPointer]: Extension for thread-safe reference-counted pointers.
//!
//! Additionally, [`UnsizedCoercible`][super::unsized_coercible::UnsizedCoercible] and [`SendUnsizedCoercible`][super::send_unsized_coercible::SendUnsizedCoercible] are provided to support
//! coercing sized closures into trait objects (`dyn Fn`).
//!
//! ### Examples
//!
//! ```
//! use fp_library::{
//! brands::*,
//! functions::*,
//! };
//!
//! let ptr = pointer_new::<RcBrand, _>(42);
//! assert_eq!(*ptr, 42);
//! ```
#[fp_macros::document_module]
mod inner {
use {
fp_macros::*,
std::ops::Deref,
};
/// Base type class for heap-allocated pointers.
///
/// This is the minimal abstraction: any type that can wrap a value and
/// dereference to it. Does NOT require Clone - that's added by subtraits.
///
/// By explicitly requiring that the type parameter `T` outlives the application lifetime `'a`,
/// we provide the compiler with the necessary guarantees to handle trait objects
/// (like `dyn Fn`) commonly used in pointer implementations. This resolves potential
/// E0310 errors where the compiler cannot otherwise prove that captured variables in
/// closures satisfy the required lifetime bounds.
pub trait Pointer {
/// The pointer type constructor.
///
/// For `RcBrand`, this is `Rc<T>`. For `ArcBrand`, this is `Arc<T>`.
type Of<'a, T: ?Sized + 'a>: Deref<Target = T> + 'a;
/// Wraps a sized value in the pointer.
#[document_signature]
///
#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
///
#[document_parameters("The value to wrap.")]
///
#[document_returns("The value wrapped in the pointer type.")]
#[document_examples]
///
/// ```
/// use fp_library::{
/// brands::*,
/// classes::*,
/// };
///
/// let ptr = <RcBrand as Pointer>::new(42);
/// assert_eq!(*ptr, 42);
/// ```
fn new<'a, T: 'a>(value: T) -> Self::Of<'a, T>
where
Self::Of<'a, T>: Sized;
}
/// Wraps a sized value in the pointer.
#[document_signature]
///
#[document_type_parameters(
"The pointer brand.",
"The lifetime of the value.",
"The type of the value to wrap."
)]
///
#[document_parameters("The value to wrap.")]
///
#[document_returns("The value wrapped in the pointer type.")]
#[document_examples]
///
/// ```
/// use fp_library::{
/// brands::*,
/// functions::*,
/// };
///
/// let ptr = pointer_new::<RcBrand, _>(42);
/// assert_eq!(*ptr, 42);
/// ```
pub fn new<'a, P: Pointer, T: 'a>(value: T) -> P::Of<'a, T>
where
P::Of<'a, T>: Sized, {
P::new(value)
}
}
pub use inner::*;