#![allow(clippy::needless_doctest_main)]
#![no_std]
#[macro_use]
#[allow(unused_imports)]
extern crate cpp_macros;
#[doc(hidden)]
pub use cpp_macros::*;
#[doc(hidden)]
#[macro_export]
macro_rules! __cpp_internal {
(@find_rust_macro [$($a:tt)*] rust!($($rust_body:tt)*) $($rest:tt)*) => {
$crate::__cpp_internal!{ @expand_rust_macro [$($a)*] $($rust_body)* }
$crate::__cpp_internal!{ @find_rust_macro [$($a)*] $($rest)* }
};
(@find_rust_macro [$($a:tt)*] ( $($in:tt)* ) $($rest:tt)* ) =>
{ $crate::__cpp_internal!{ @find_rust_macro [$($a)*] $($in)* $($rest)* } };
(@find_rust_macro [$($a:tt)*] [ $($in:tt)* ] $($rest:tt)* ) =>
{ $crate::__cpp_internal!{ @find_rust_macro [$($a)*] $($in)* $($rest)* } };
(@find_rust_macro [$($a:tt)*] { $($in:tt)* } $($rest:tt)* ) =>
{ $crate::__cpp_internal!{ @find_rust_macro [$($a)*] $($in)* $($rest)* } };
(@find_rust_macro [$($a:tt)*] $t:tt $($rest:tt)*) =>
{ $crate::__cpp_internal!{ @find_rust_macro [$($a)*] $($rest)* } };
(@find_rust_macro [$($a:tt)*]) => {};
(@expand_rust_macro [$($a:tt)*] $i:ident [$($an:ident : $at:ty as $ac:tt),*] {$($body:tt)*}) => {
#[allow(non_snake_case)]
#[allow(unused_unsafe)]
#[cfg_attr(feature = "cargo-clippy", allow(clippy::forget_copy))]
#[cfg_attr(feature = "cargo-clippy", allow(clippy::forget_ref))]
#[doc(hidden)]
$($a)* unsafe extern "C" fn $i($($an : *const $at),*) {
$(let $an : $at = unsafe { $an.read() };)*
(|| { $($body)* })();
$(::core::mem::forget($an);)*
}
};
(@expand_rust_macro [$($a:tt)*] $i:ident [$($an:ident : $at:ty as $ac:tt),*] -> $rt:ty as $rc:tt {$($body:tt)*}) => {
#[allow(non_snake_case)]
#[allow(unused_unsafe)]
#[cfg_attr(feature = "cargo-clippy", allow(clippy::forget_copy))]
#[cfg_attr(feature = "cargo-clippy", allow(clippy::forget_ref))]
#[doc(hidden)]
$($a)* unsafe extern "C" fn $i($($an : *const $at, )* rt : *mut $rt) -> *mut $rt {
$(let $an : $at = unsafe { $an.read() };)*
{
#[allow(unused_mut)]
let mut lambda = || {$($body)*};
unsafe { ::core::ptr::write(rt, lambda()) };
}
$(::core::mem::forget($an);)*
rt
}
};
(@expand_rust_macro $($invalid:tt)*) => {
compile_error!(concat!( "Cannot parse rust! macro: ", stringify!([ $($invalid)* ]) ))
};
}
#[macro_export]
macro_rules! cpp {
({$($body:tt)*}) => { $crate::__cpp_internal!{ @find_rust_macro [#[no_mangle] pub] $($body)*} };
([$($captures:tt)*] $($rest:tt)*) => {
{
$crate::__cpp_internal!{ @find_rust_macro [] $($rest)*}
#[allow(unused)]
#[derive($crate::__cpp_internal_closure)]
enum CppClosureInput {
Input = (stringify!([$($captures)*] $($rest)*), 0).1
}
__cpp_closure_impl![$($captures)*]
}
};
(unsafe $($tail:tt)*) => { unsafe { cpp!($($tail)*) } };
}
#[doc(hidden)]
pub trait CppTrait {
type BaseType;
const ARRAY_SIZE: usize;
const CPP_TYPE: &'static str;
}
#[macro_export]
macro_rules! cpp_class {
($(#[$($attrs:tt)*])* unsafe struct $name:ident as $type:expr) => {
$crate::__cpp_class_internal!{@parse [ $(#[$($attrs)*])* ] [] [unsafe struct $name as $type] }
};
($(#[$($attrs:tt)*])* pub unsafe struct $name:ident as $type:expr) => {
$crate::__cpp_class_internal!{@parse [ $(#[$($attrs)*])* ] [pub] [unsafe struct $name as $type] }
};
($(#[$($attrs:tt)*])* pub($($pub:tt)*) unsafe struct $name:ident as $type:expr) => {
$crate::__cpp_class_internal!{@parse [ $(#[$($attrs)*])* ] [pub($($pub)*)] [unsafe struct $name as $type] }
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __cpp_class_internal {
(@parse [$($attrs:tt)*] [$($vis:tt)*] [unsafe struct $name:ident as $type:expr]) => {
$crate::__cpp_class_internal!{@parse_attributes [ $($attrs)* ] [] [
#[derive($crate::__cpp_internal_class)]
#[repr(C)]
$($vis)* struct $name {
_opaque : [<$name as $crate::CppTrait>::BaseType ; <$name as $crate::CppTrait>::ARRAY_SIZE
+ (stringify!($($attrs)* $($vis)* unsafe struct $name as $type), 0).1]
}
]}
};
(@parse_attributes [] [$($attributes:tt)*] [$($result:tt)*]) => ( $($attributes)* $($result)* );
(@parse_attributes [#[derive($($der:ident),*)] $($tail:tt)* ] [$($attributes:tt)*] [$($result:tt)*] )
=> ($crate::__cpp_class_internal!{@parse_derive [$($der),*] @parse_attributes [$($tail)*] [ $($attributes)* ] [ $($result)* ] } );
(@parse_attributes [ #[$m:meta] $($tail:tt)* ] [$($attributes:tt)*] [$($result:tt)*])
=> ($crate::__cpp_class_internal!{@parse_attributes [$($tail)*] [$($attributes)* #[$m] ] [ $($result)* ] } );
(@parse_derive [] @parse_attributes $($result:tt)*) => ($crate::__cpp_class_internal!{@parse_attributes $($result)*} );
(@parse_derive [PartialEq $(,$tail:ident)*] $($result:tt)*)
=> ( $crate::__cpp_class_internal!{@parse_derive [$($tail),*] $($result)*} );
(@parse_derive [PartialOrd $(,$tail:ident)*] $($result:tt)*)
=> ( $crate::__cpp_class_internal!{@parse_derive [$($tail),*] $($result)*} );
(@parse_derive [Ord $(,$tail:ident)*] $($result:tt)*)
=> ( $crate::__cpp_class_internal!{@parse_derive [$($tail),*] $($result)*} );
(@parse_derive [Default $(,$tail:ident)*] $($result:tt)*)
=> ( $crate::__cpp_class_internal!{@parse_derive [$($tail),*] $($result)*} );
(@parse_derive [Clone $(,$tail:ident)*] $($result:tt)*)
=> ( $crate::__cpp_class_internal!{@parse_derive [$($tail),*] $($result)*} );
(@parse_derive [Copy $(,$tail:ident)*] $($result:tt)*)
=> ( $crate::__cpp_class_internal!{@parse_derive [$($tail),*] $($result)*} );
(@parse_derive [$i:ident $(,$tail:ident)*] @parse_attributes [$($attr:tt)*] [$($attributes:tt)*] [$($result:tt)*] )
=> ( $crate::__cpp_class_internal!{@parse_derive [$($tail),*] @parse_attributes [$($attr)*] [$($attributes)* #[derive($i)] ] [ $($result)* ] } );
}