cpp_core/
convert.rs

1use crate::ptr::NullPtr;
2use crate::{CppBox, CppDeletable, Ptr, Ref, StaticUpcast};
3
4/// Performs some of the conversions that are available implicitly in C++.
5///
6/// `CastInto` is automatically implemented for all `CastFrom` conversions,
7/// similar to `From` and `Into` traits from `std`.
8pub trait CastFrom<T>: Sized {
9    /// Performs the conversion.
10    ///
11    /// ### Safety
12    ///
13    /// This operation is safe as long as `value` is valid.
14    unsafe fn cast_from(value: T) -> Self;
15}
16
17/// Performs some of the conversions that are available implicitly in C++.
18///
19/// `CastInto` is automatically implemented for all `CastFrom` conversions,
20/// similar to `From` and `Into` traits from `std`.
21pub trait CastInto<T>: Sized {
22    /// Performs the conversion.
23    ///
24    /// ### Safety
25    ///
26    /// This operation is safe as long as `self` is valid.
27    unsafe fn cast_into(self) -> T;
28}
29
30impl<T, U: CastFrom<T>> CastInto<U> for T {
31    unsafe fn cast_into(self) -> U {
32        U::cast_from(self)
33    }
34}
35
36impl<T, U> CastFrom<Ref<U>> for Ptr<T>
37where
38    U: StaticUpcast<T>,
39{
40    unsafe fn cast_from(value: Ref<U>) -> Self {
41        StaticUpcast::static_upcast(value.as_ptr())
42    }
43}
44
45impl<'a, T, U: CppDeletable> CastFrom<&'a CppBox<U>> for Ptr<T>
46where
47    U: StaticUpcast<T>,
48{
49    unsafe fn cast_from(value: &'a CppBox<U>) -> Self {
50        StaticUpcast::static_upcast(value.as_ptr())
51    }
52}
53
54impl<'a, T, U: CppDeletable> CastFrom<&'a CppBox<U>> for Ref<T>
55where
56    U: StaticUpcast<T>,
57{
58    unsafe fn cast_from(value: &'a CppBox<U>) -> Self {
59        StaticUpcast::static_upcast(value.as_ptr())
60            .as_ref()
61            .expect("StaticUpcast returned null on CppBox input")
62    }
63}
64
65impl<T, U> CastFrom<Ptr<U>> for Ptr<T>
66where
67    U: StaticUpcast<T>,
68{
69    unsafe fn cast_from(value: Ptr<U>) -> Self {
70        StaticUpcast::static_upcast(value)
71    }
72}
73
74impl<T, U> CastFrom<Ref<U>> for Ref<T>
75where
76    U: StaticUpcast<T>,
77{
78    unsafe fn cast_from(value: Ref<U>) -> Self {
79        StaticUpcast::static_upcast(value.as_ptr())
80            .as_ref()
81            .expect("StaticUpcast returned null on Ref input")
82    }
83}
84
85impl<T> CastFrom<NullPtr> for Ptr<T> {
86    unsafe fn cast_from(_value: NullPtr) -> Self {
87        Self::null()
88    }
89}
90
91impl<T, U> CastFrom<*const U> for Ptr<T>
92where
93    U: StaticUpcast<T>,
94{
95    unsafe fn cast_from(value: *const U) -> Self {
96        Self::cast_from(Ptr::from_raw(value))
97    }
98}
99
100impl<T, U> CastFrom<*mut U> for Ptr<T>
101where
102    U: StaticUpcast<T>,
103{
104    unsafe fn cast_from(value: *mut U) -> Self {
105        Self::cast_from(Ptr::from_raw(value))
106    }
107}