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
//! `static_cast` and `dynamic_cast`. use crate::Ptr; /// Converts a class pointer to a base class pointer. /// /// A null pointer is always converted to a null pointer. /// Otherwise, the provided pointer must be valid. /// /// It's recommended to perform the conversion by calling `static_upcast` /// method on pointer types (`CppBox`, `Ptr`, `Ref`) /// instead of importing the trait directly. /// /// Provides access to C++ `static_cast` conversion from derived class to base class. /// The conversion in opposite direction can be done with `StaticDowncast`. /// /// If `T1` class is derived (in C++) from `T2` class (directly or indirectly), /// `StaticUpcast<T2>` is implemented for `T1`. /// The implementation is generated by `ritual` automatically. /// /// Note that Rust functions associated with this trait have runtime overhead. /// In C++, `static_cast` is usually a no-op if there is no multiple inheritance, /// and multiple inheritance requires pointer adjustment. However, Rust compiler /// and `ritual` do not have any information about these implementation details, /// so all calls of `static_cast` are wrapper in FFI functions. pub trait StaticUpcast<T>: Sized { /// Convert type of a const pointer. /// /// ### Safety /// /// This operation is safe as long as `ptr` is either valid or null. unsafe fn static_upcast(ptr: Ptr<Self>) -> Ptr<T>; } impl<T> StaticUpcast<T> for T { unsafe fn static_upcast(ptr: Ptr<T>) -> Ptr<T> { ptr } } /// Converts a class pointer to a base class pointer without a runtime check. /// /// A null pointer is always converted to a null pointer. /// Otherwise, the provided pointer must be valid and point to the object of the specified type. /// /// It's generally safer to use `DynamicCast` instead because it performs a checked conversion. /// This trait should only be used if the type of the object is known. /// /// It's recommended to perform the conversion by calling `static_downcast` /// method on pointer types (`CppBox`, `Ptr`, `Ref`) /// instead of importing the trait directly. /// /// Provides access to C++ `static_cast` conversion from base class to derived class. /// The conversion in opposite direction can be done with `StaticUpcast`. /// /// If `T1` class is derived (in C++) from `T2` class (directly or indirectly), /// `StaticDowncast<T1>` is implemented for `T2`. /// The implementation is generated by `ritual` automatically. /// /// Note that Rust functions associated with this trait have runtime overhead. /// In C++, `static_cast` is usually a no-op if there is no multiple inheritance, /// and multiple inheritance requires pointer adjustment. However, Rust compiler /// and `ritual` do not have any information about these implementation details, /// so all calls of `static_cast` are wrapper in FFI functions. pub trait StaticDowncast<T>: Sized { /// Convert type of a const pointer. /// /// ### Safety /// /// This operation is safe as long as `ptr` is either null or points to an object /// of the `T` class or a class inherited by `T`. unsafe fn static_downcast(ptr: Ptr<Self>) -> Ptr<T>; } /// Converts a class pointer to a base class pointer. /// /// A null pointer is always converted to a null pointer. /// If the object can't be converted to the requested type, a null pointer is returned. /// /// It's recommended to perform the conversion by calling `dynamic_cast` /// method on pointer types (`CppBox`, `Ptr`, `Ref`) /// instead of importing the trait directly. /// /// Provides access to C++ `dynamic_cast` conversion from base class to derived class. /// The conversion in opposite direction can be done with `StaticUpcast`. /// /// If `T1` class is derived (in C++) from `T2` class (directly or indirectly), /// `DynamicCast<T1>` is implemented for `T2`. /// The implementation is generated by `ritual` automatically. pub trait DynamicCast<T>: Sized { /// Convert type of a const pointer. /// /// Returns a null pointer if the object doesn't have the requested type. /// /// ### Safety /// /// This operation is safe as long as `ptr` is either valid or null. unsafe fn dynamic_cast(ptr: Ptr<Self>) -> Ptr<T>; }