1#![cfg_attr(rustfmt, rustfmt::skip)]
2use super::*;
3
4#[cfg(not(any(target_arch = "wasm32", not(feature = "std"))))] const_assert! {
6 ::core::mem::size_of::<crate::libc::uintptr_t>()
7 ==
8 ::core::mem::size_of::<crate::libc::size_t>()
9}
10
11const _: () = { macro_rules! impl_CTypes {
12 () => (
13 impl_CTypes! { @pointers }
14 impl_CTypes! { @zsts }
15 impl_CTypes! { @floats
16 unsafe
17 f32 => "float",
18
19 unsafe
20 f64 => "double",
21 }
22 impl_CTypes! { @integers
23 unsafe u8 => "uint8" "byte",
27
28 unsafe u16 => "uint16" "UInt16",
30
31 unsafe u32 => "uint32" "UInt32",
33
34 unsafe u64 => "uint64" "UInt64",
36
37 unsafe usize => "size" "UIntPtr",
61
62
63 unsafe i8 => "int8" "sbyte",
65
66 unsafe i16 => "int16" "Int16",
68
69 unsafe i32 => "int32" "Int32",
71
72 unsafe i64 => "int64" "Int64",
74
75 unsafe isize => "ssize" "IntPtr",
79 }
80 #[cfg(docs)] impl_CTypes! { @fns (A1, A2) } #[cfg(not(docs))]
81 impl_CTypes! { @fns
82 (A10, A9, A8, A7, A6, A5, A4, A3, A2, A1)
83 }
84 #[cfg(docs)] impl_CTypes! { @arrays 1 2 } #[cfg(not(docs))]
85 impl_CTypes! { @arrays
86 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
88 26 27 28 29 30 31 32 40 48 50 60 64 70 75 80 90 96 100 125 128 192
89 200 250 256 300 400 500 512 600 700 750 800 900 1000 1024
90 }
91 );
92
93 (
94 @arrays
95 $($N:tt)*
96 ) => ($(
97 unsafe impl<Item : CType> LegacyCType
103 for [Item; $N]
104 { __cfg_headers__! {
105 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
106 -> fmt::Result
107 {
108 write!(fmt,
110 concat!("{}_", stringify!($N), "_array"),
111 Item::short_name(),
112 )
113 }
114
115 fn c_define_self (definer: &'_ mut dyn Definer)
116 -> io::Result<()>
117 {
118 let ref me = Self::c_var("").to_string();
119 definer.define_once(
120 me,
121 &mut |definer| {
122 Item::define_self(&crate::headers::languages::C, definer)?;
123 writeln!(definer.out(),
124 concat!(
125 "typedef struct {{\n",
126 " {inline_array};\n",
127 "}} {me};\n",
128 ),
129 inline_array = Item::name_wrapping_var(&crate::headers::languages::C, concat!(
130 "idx[", stringify!($N), "]",
131 )),
132 me = me,
133 )
134 }
135 )
136 }
137
138 fn c_var_fmt (
139 fmt: &'_ mut fmt::Formatter<'_>,
140 var_name: &'_ str,
141 ) -> fmt::Result
142 {
143 write!(fmt,
145 "{}_t{sep}{}",
146 Self::c_short_name(),
147 var_name,
148 sep = if var_name.is_empty() { "" } else { " " },
149 )
150 }
151
152 __cfg_csharp__! {
153 fn csharp_define_self (definer: &'_ mut dyn Definer)
154 -> io::Result<()>
155 {
156 let ref me = Self::csharp_ty();
157 Item::define_self(&crate::headers::languages::CSharp, definer)?;
158 definer.define_once(me, &mut |definer| {
159 let array_items = {
160 if [
162 "bool",
163 "u8", "u16", "u32", "u64", "usize",
164 "i8", "i16", "i32", "i64", "isize",
165 "float", "double",
166 ].contains(&::core::any::type_name::<Item>())
167 {
168 format!(
169 " public fixed {ItemTy} arr[{N}];\n",
170 ItemTy = Item::name(&crate::headers::languages::CSharp),
171 N = $N,
172 )
174 } else {
175 (0 .. $N)
178 .map(|i| format!(
179 " \
180 {marshaler}\
181 public {ItemTy} _{i};\n",
182 ItemTy = Item::name(&crate::headers::languages::CSharp),
183 i = i,
184 marshaler =
185 Item::csharp_marshaler()
186 .map(|m| format!("[MarshalAs({})]\n ", m))
187 .as_deref()
188 .unwrap_or("")
189 ,
190 ))
191 .collect::<rust::String>()
192 }
193 };
194 writeln!(definer.out(),
195 concat!(
196 "[StructLayout(LayoutKind.Sequential, Size = {size})]\n",
197 "public unsafe struct {me} {{\n",
198 "{array_items}",
199 "}}\n",
200 ),
201 me = me,
202 array_items = array_items,
203 size = mem::size_of::<Self>(),
204 )
205 })
206 }
207 }
208 } type OPAQUE_KIND = OpaqueKind::Concrete; }
209
210 unsafe
215 impl<Item : ReprC> ReprC
216 for [Item; $N]
217 {
218 type CLayout = [Item::CLayout; $N];
219
220 #[inline]
221 fn is_valid (it: &'_ Self::CLayout)
222 -> bool
223 {
224 it.iter().all(Item::is_valid)
225 }
226 }
227 )*);
228
229 (@fns
230 (
231 $(
232 $An:ident $(,
233 $Ai:ident)* $(,)?
234 )?
235 )
236 ) => (
237 $(
239 impl_CTypes! {
240 @fns
241 ($($Ai ,)*)
242 }
243 )?
244
245 unsafe
246 impl<
247 Ret : ReprC, $(
248 $An : ReprC, $(
249 $Ai : ReprC,
250 )*)?> $crate::layout::__HasNiche__
251 for
252 unsafe extern "C" fn ($($An, $($Ai ,)*)?) -> Ret
253 {}
254
255 unsafe
256 impl<
257 Ret : ReprC, $(
258 $An : ReprC, $(
259 $Ai : ReprC,
260 )*)?> $crate::layout::__HasNiche__
261 for
262 extern "C" fn ($($An, $($Ai ,)*)?) -> Ret
263 {}
264
265 unsafe impl<
272 Ret : CType, $(
273 $An : CType, $(
274 $Ai : CType,
275 )*)?> LegacyCType
276 for Option<unsafe extern "C" fn ($($An, $($Ai ,)*)?) -> Ret>
277 { __cfg_headers__! {
278 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
279 -> fmt::Result
280 {
281 fmt.write_str(&Ret::short_name())?; $(
283 write!(fmt, "_{}", $An::short_name())?; $(
284 write!(fmt, "_{}", $Ai::short_name())?; )*)?
285 fmt.write_str("_fptr")
286 }
287
288 fn c_define_self (definer: &'_ mut dyn Definer)
289 -> io::Result<()>
290 {
291 Ret::define_self(&crate::headers::languages::C, definer)?; $(
292 $An::define_self(&crate::headers::languages::C, definer)?; $(
293 $Ai::define_self(&crate::headers::languages::C, definer)?; )*)?
294 Ok(())
295 }
296
297 fn c_var_fmt (
298 fmt: &'_ mut fmt::Formatter<'_>,
299 var_name: &'_ str,
300 ) -> fmt::Result
301 {
302 write!(fmt, "{} ", Ret::name(&crate::headers::languages::C))?;
303 write!(fmt, "(*{})(", var_name)?;
304 let _empty = true; $(
305 let _empty = false;
306 write!(fmt, "{}", $An::name(&crate::headers::languages::C))?; $(
307 write!(fmt, ", {}", $Ai::name(&crate::headers::languages::C))?; )*)?
308 if _empty {
309 fmt.write_str("void")?;
310 }
311 fmt.write_str(")")
312 }
313
314 __cfg_csharp__! {
315 fn csharp_define_self (definer: &'_ mut dyn Definer)
316 -> io::Result<()>
317 {
318 Ret::define_self(&crate::headers::languages::CSharp, definer)?; $(
319 $An::define_self(&crate::headers::languages::CSharp, definer)?; $(
320 $Ai::define_self(&crate::headers::languages::CSharp, definer)?; )*)?
321 let ref me = Self::name(&crate::headers::languages::CSharp).to_string();
322 let ref mut _arg = {
323 let mut iter = (0 ..).map(|c| format!("_{}", c));
324 move || iter.next().unwrap()
325 };
326 definer.define_once(me, &mut |definer| writeln!(definer.out(),
327 concat!(
328 "[UnmanagedFunctionPointer(CallingConvention.Winapi)]\n",
336
337 "{ret_marshaler}public unsafe /* static */ delegate\n",
338 " {Ret}\n",
339 " {me} (", $("\n",
340 " {}{", stringify!($An), "}", $(",\n",
341 " {}{", stringify!($Ai), "}", )*)?
342 ");\n"
343 ),$(
344 $An::csharp_marshaler()
345 .map(|m| format!("[MarshalAs({})]\n ", m))
346 .as_deref()
347 .unwrap_or("")
348 , $(
349 $Ai::csharp_marshaler()
350 .map(|m| format!("[MarshalAs({})]\n ", m))
351 .as_deref()
352 .unwrap_or("")
353 , )*)?
354 me = me,
355 ret_marshaler =
356 Ret::csharp_marshaler()
357 .map(|m| format!("[return: MarshalAs({})]\n", m))
358 .as_deref()
359 .unwrap_or("")
360 ,
361 Ret = Ret::name(&crate::headers::languages::CSharp), $(
362 $An = $An::name_wrapping_var(&crate::headers::languages::CSharp, &_arg()), $(
363 $Ai = $Ai::name_wrapping_var(&crate::headers::languages::CSharp, &_arg()), )*)?
364 ))
365 }
366
367 fn csharp_ty ()
368 -> rust::String
369 {
370 Self::c_short_name().to_string()
371 }
372
373 fn legacy_csharp_marshaler ()
374 -> Option<rust::String>
375 {
376 Some("UnmanagedType.FunctionPtr".into())
379 }
380 }
381 } type OPAQUE_KIND = OpaqueKind::Concrete; }
382
383 unsafe impl<
390 Ret : ReprC, $(
391 $An : ReprC, $(
392 $Ai : ReprC,
393 )*)?> ReprC
394 for unsafe extern "C" fn ($($An, $($Ai ,)*)?) -> Ret
395 {
396 type CLayout = Option<
397 unsafe extern "C"
398 fn ($($An::CLayout, $($Ai::CLayout ,)*)?) -> Ret::CLayout
399 >;
400
401 #[inline]
402 fn is_valid (c_layout: &'_ Self::CLayout)
403 -> bool
404 {
405 c_layout.is_some()
406 }
407 }
408
409 unsafe impl<
414 Ret : ReprC, $(
415 $An : ReprC, $(
416 $Ai : ReprC,
417 )*)?> ReprC
418 for extern "C" fn ($($An, $($Ai ,)*)?) -> Ret
419 {
420 type CLayout = Option<
421 unsafe extern "C"
422 fn ($($An::CLayout, $($Ai::CLayout ,)*)?) -> Ret::CLayout
423 >;
424
425 #[inline]
426 fn is_valid (c_layout: &'_ Self::CLayout)
427 -> bool
428 {
429 c_layout.is_some()
430 }
431 }
432
433 unsafe impl<
438 Ret : ReprC, $(
439 $An : ReprC, $(
440 $Ai : ReprC,
441 )*)?> crate::layout::__HasNiche__
442 for fn ($($An, $($Ai ,)*)?) -> Ret
443 where
444 Self : ReprC, {
446 #[inline]
447 fn is_niche (_: &'_ Self::CLayout)
448 -> bool
449 {
450 unreachable!()
451 }
452 }
453 unsafe impl<
455 Ret : ReprC, $(
456 $An : ReprC, $(
457 $Ai : ReprC,
458 )*)?> crate::layout::__HasNiche__
459 for unsafe fn ($($An, $($Ai ,)*)?) -> Ret
460 where
461 Self : ReprC, {
463 #[inline]
464 fn is_niche (_: &'_ Self::CLayout)
465 -> bool
466 {
467 unreachable!()
468 }
469 }
470 );
471
472 (@integers
473 $(
474 $unsafe:tt
475 $RustInt:ident => $CInt:literal $CSharpInt:literal,
476 )*
477 ) => ($(
478 $unsafe impl LegacyCType
480 for $RustInt
481 { __cfg_headers__! {
482 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
483 -> fmt::Result
484 {
485 fmt.write_str($CInt)
486 }
487
488 fn c_define_self (definer: &'_ mut dyn Definer)
489 -> io::Result<()>
490 {
491 definer.define_once(
492 "__int_headers__",
493 &mut |definer| write!(definer.out(),
494 concat!(
495 "\n",
496 "#include <stddef.h>\n",
497 "#include <stdint.h>\n",
498 "\n",
499 ),
500 ),
501 )
502 }
503
504 fn c_var_fmt (
505 fmt: &'_ mut fmt::Formatter<'_>,
506 var_name: &'_ str,
507 ) -> fmt::Result
508 {
509 write!(fmt,
510 concat!($CInt, "_t{sep}{}"),
511 var_name,
512 sep = if var_name.is_empty() { "" } else { " " },
513 )
514 }
515
516 __cfg_csharp__! {
517 fn csharp_define_self (
518 _: &'_ mut dyn crate::headers::Definer,
519 ) -> io::Result<()>
520 {
521 Ok(())
522 }
523
524 fn csharp_ty ()
525 -> rust::String
526 {
527 $CSharpInt.into()
528 }
529 }
530 } type OPAQUE_KIND = OpaqueKind::Concrete; }
531 from_CType_impl_ReprC! { $RustInt }
532 )*);
533
534 (@floats
535 $(
536 $unsafe:tt
537 $fN:ident => $Cty:literal,
538 )*
539 ) => ($(
540 $unsafe impl LegacyCType
542 for $fN
543 { __cfg_headers__! {
544 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
545 -> fmt::Result
546 {
547 fmt.write_str($Cty)
548 }
549
550 fn c_var_fmt (
551 fmt: &'_ mut fmt::Formatter<'_>,
552 var_name: &'_ str,
553 ) -> fmt::Result
554 {
555 write!(fmt,
556 concat!($Cty, "{sep}{}"),
557 var_name,
558 sep = if var_name.is_empty() { "" } else { " " },
559 )
560 }
561
562 fn c_define_self (
563 _: &'_ mut dyn crate::headers::Definer,
564 ) -> io::Result<()>
565 {
566 Ok(())
567 }
568
569 __cfg_csharp__! {
570 fn csharp_define_self (
571 _: &'_ mut dyn crate::headers::Definer,
572 ) -> io::Result<()>
573 {
574 Ok(())
575 }
576
577 fn csharp_ty ()
578 -> rust::String
579 {
580 $Cty.into()
581 }
582 }
583 } type OPAQUE_KIND = OpaqueKind::Concrete; }
584 from_CType_impl_ReprC! { $fN }
585 )*);
586
587 (
588 @pointers
589 ) => (
590 unsafe
591 impl<T : CType> LegacyCType
592 for *const T
593 { __cfg_headers__! {
594 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
595 -> fmt::Result
596 {
597 write!(fmt, "{}_const_ptr", T::short_name())
598 }
599
600 fn c_define_self (definer: &'_ mut dyn Definer)
601 -> io::Result<()>
602 {
603 T::define_self(&crate::headers::languages::C, definer)
604 }
605
606 fn c_var_fmt (
607 fmt: &'_ mut fmt::Formatter<'_>,
608 var_name: &'_ str,
609 ) -> fmt::Result
610 {
611 write!(fmt,
612 "{} const *{sep}{}",
613 T::name(&crate::headers::languages::C),
614 var_name,
615 sep = if var_name.is_empty() { "" } else { " " },
616 )
617 }
618
619 __cfg_csharp__! {
620 fn csharp_define_self (definer: &'_ mut dyn $crate::headers::Definer)
621 -> $crate::ඞ::io::Result<()>
622 {
623 T::define_self(&crate::headers::languages::CSharp, definer)?;
624 Ok(())
633 }
634
635 fn csharp_ty ()
636 -> rust::String
637 {
638 format!("{} /*const*/ *", T::name(&crate::headers::languages::CSharp))
639 }
640 }
641 } type OPAQUE_KIND = OpaqueKind::Concrete; }
642
643 unsafe
644 impl<T : ReprC> ReprC
645 for *const T
646 {
647 type CLayout = *const T::CLayout;
648
649 #[inline]
650 fn is_valid (_: &'_ Self::CLayout)
651 -> bool
652 {
653 true
654 }
655 }
656
657 unsafe
658 impl<T : CType> LegacyCType
659 for *mut T
660 { __cfg_headers__! {
661 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
662 -> fmt::Result
663 {
664 write!(fmt, "{}_ptr", T::short_name())
665 }
666
667 fn c_define_self (definer: &'_ mut dyn Definer)
668 -> io::Result<()>
669 {
670 T::define_self(&crate::headers::languages::C, definer)
671 }
672
673 fn c_var_fmt (
674 fmt: &'_ mut fmt::Formatter<'_>,
675 var_name: &'_ str,
676 ) -> fmt::Result
677 {
678 write!(fmt,
679 "{} *{sep}{}",
680 T::name(&crate::headers::languages::C),
681 var_name,
682 sep = if var_name.is_empty() { "" } else { " " },
683 )
684 }
685
686 __cfg_csharp__! {
687 fn csharp_define_self (definer: &'_ mut dyn $crate::headers::Definer)
688 -> $crate::ඞ::io::Result<()>
689 {
690 T::define_self(&crate::headers::languages::CSharp, definer)
691 }
692
693 fn csharp_ty ()
694 -> rust::String
695 {
696 format!("{} *", T::name(&crate::headers::languages::CSharp))
697 }
698 }
699 } type OPAQUE_KIND = OpaqueKind::Concrete; }
700 unsafe
701 impl<T : ReprC> ReprC
702 for *mut T
703 {
704 type CLayout = *mut T::CLayout;
705
706 #[inline]
707 fn is_valid (_: &'_ Self::CLayout)
708 -> bool
709 {
710 true
711 }
712 }
713 );
714
715 (
716 @zsts
717 ) => (
718 unsafe
721 impl ReprC
722 for ()
723 {
724 type CLayout = CVoid;
725
726 #[inline]
727 fn is_valid (_: &'_ CVoid)
728 -> bool
729 {
730 panic!("It is a logic error to try and get a ZST from C");
731 }
732 }
733 unsafe
735 impl<T : ?Sized> ReprC
736 for PhantomData<T>
737 {
738 type CLayout = CVoid;
739
740 #[inline]
741 fn is_valid (_: &'_ CVoid)
742 -> bool
743 {
744 panic!("It is a logic error to try and get a ZST from C");
745 }
746 }
747 );
748} impl_CTypes! {} };
749
750macro_rules! impl_ReprC_for {(
751 $unsafe:tt {
752 $(
753 $(@for [$($generics:tt)+])? $T:ty
754 => |ref $it:tt : $Layout:ty| $expr:expr
755 ),* $(,)?
756 }
757) => (
758 $(
759 $unsafe
760 impl $(<$($generics)+>)? ReprC
761 for $T
762 {
763 type CLayout = $Layout;
764
765 #[inline]
766 fn is_valid (it: &'_ $Layout)
767 -> bool
768 {
769 let $it = it;
770 if $expr {
771 true
772 } else {
773 #[cfg(feature = "log")]
774 ::log::error!(
775 "{:#x?} is not a _valid_ bit pattern for the type `{}`",
776 unsafe {
777 ::core::slice::from_raw_parts(
778 <*const _>::cast::<u8>(it),
779 ::core::mem::size_of_val(it),
780 )
781 },
782 ::core::any::type_name::<Self>(),
783 );
784 false
785 }
786 }
787 }
788 )*
789)}
790
791#[repr(transparent)]
792#[derive(Clone, Copy, PartialEq, Eq)]
793#[allow(missing_debug_implementations)]
794pub
795struct Bool(u8);
796
797#[cfg(feature = "js")]
798const _: () = {
799 use crate::js::*;
800
801 impl ReprNapi for Bool {
802 type NapiValue = JsBoolean;
803
804 fn to_napi_value (
805 self: Self,
806 env: &'_ Env,
807 ) -> Result< JsBoolean >
808 {
809 env.get_boolean(match self.0 {
810 0 => false,
811 1 => true,
812 bad => unreachable!("({:#x}: Bool) != 0x0, 0x1", bad),
813 })
814 }
815
816 fn from_napi_value (
817 _env: &'_ Env,
818 napi_value: JsBoolean,
819 ) -> Result<Self>
820 {
821 napi_value.get_value().map(|b: bool| Self(b as _))
822 }
823 }
824};
825
826unsafe
827 impl LegacyCType
828 for Bool
829 {
830 __cfg_headers__! {
831 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
832 -> fmt::Result
833 {
834 fmt.write_str("bool")
835 }
836
837 fn c_define_self (definer: &'_ mut dyn Definer)
838 -> io::Result<()>
839 {
840 definer.define_once(
841 "bool",
842 &mut |definer| {
843 definer.out().write_all(
844 b"\n#include <stdbool.h>\n\n"
845 )
846 },
847 )
848 }
849
850 fn c_var_fmt (
851 fmt: &'_ mut fmt::Formatter<'_>,
852 var_name: &'_ str,
853 ) -> fmt::Result
854 {
855 write!(fmt,
856 "bool{sep}{}",
857 var_name,
858 sep = if var_name.is_empty() { "" } else { " " },
859 )
860 }
861
862 __cfg_csharp__! {
863 fn csharp_define_self (
864 _: &'_ mut dyn crate::headers::Definer,
865 ) -> io::Result<()>
866 {
867 Ok(())
868 }
869
870 fn legacy_csharp_marshaler ()
871 -> Option<rust::String>
872 {
873 Some("UnmanagedType.U1".into())
874 }
875
876 fn csharp_ty ()
877 -> rust::String
878 {
879 "bool".into()
880 }
881 }
882 }
883
884 type OPAQUE_KIND = OpaqueKind::Concrete;
885 }
886from_CType_impl_ReprC! { Bool }
887
888#[repr(transparent)]
897#[derive(Clone, Copy, PartialEq, Eq)]
898pub
899struct c_int(pub crate::libc::c_int);
900
901impl ::core::fmt::Debug for c_int {
902 fn fmt (self: &'_ c_int, fmt: &'_ mut ::core::fmt::Formatter<'_>)
903 -> ::core::fmt::Result
904 {
905 ::core::fmt::Debug::fmt(&self.0, fmt)
906 }
907}
908
909unsafe
910 impl LegacyCType
911 for c_int
912 {
913 __cfg_headers__! {
914 fn c_short_name_fmt (fmt: &'_ mut fmt::Formatter<'_>)
915 -> fmt::Result
916 {
917 fmt.write_str("int")
918 }
919
920 fn c_var_fmt (
921 fmt: &'_ mut fmt::Formatter<'_>,
922 var_name: &'_ str,
923 ) -> fmt::Result
924 {
925 write!(fmt,
926 "int{sep}{}",
927 var_name,
928 sep = if var_name.is_empty() { "" } else { " " },
929 )
930 }
931
932 fn c_define_self (
933 _: &'_ mut dyn crate::headers::Definer,
934 ) -> io::Result<()>
935 {
936 Ok(())
937 }
938
939 __cfg_csharp__! {
940 fn csharp_define_self (
941 _: &'_ mut dyn crate::headers::Definer,
942 ) -> io::Result<()>
943 {
944 Ok(())
945 }
946
947 fn csharp_ty ()
948 -> rust::String
949 {
950 "int".into()
951 }
952
953 fn legacy_csharp_marshaler ()
954 -> Option<rust::String>
955 {
956 Some("UnmanagedType.SysInt".into())
957 }
958 }
959 }
960
961 type OPAQUE_KIND = OpaqueKind::Concrete;
962 }
963
964impl_ReprC_for! { unsafe {
965 bool
966 => |ref byte: Bool| (byte.0 & !0b1) == 0
967 ,
968
969 @for[T : ReprC]
970 ptr::NonNull<T>
971 => |ref it: *mut T::CLayout| {
972 it.is_null().not() &&
973 (*it as usize) % ::core::mem::align_of::<T>() == 0
974 }
975 ,
976 @for[T : ReprC]
977 ptr::NonNullRef<T>
978 => |ref it: *const T::CLayout| {
979 it.is_null().not() &&
980 (*it as usize) % ::core::mem::align_of::<T>() == 0
981 }
982 ,
983 @for[T : ReprC]
984 ptr::NonNullMut<T>
985 => |ref it: *mut T::CLayout| {
986 it.is_null().not() &&
987 (*it as usize) % ::core::mem::align_of::<T>() == 0
988 }
989 ,
990 @for[T : ReprC]
991 ptr::NonNullOwned<T>
992 => |ref it: *mut T::CLayout| {
993 it.is_null().not() &&
994 (*it as usize) % ::core::mem::align_of::<T>() == 0
995 }
996 ,
997 @for['a, T : 'a + ReprC]
998 &'a T
999 => |ref it: *const T::CLayout| {
1000 it.is_null().not() &&
1001 (*it as usize) % ::core::mem::align_of::<T>() == 0
1002 }
1003 ,
1004 @for['a, T : 'a + ReprC]
1005 &'a mut T
1006 => |ref it: *mut T::CLayout| {
1007 it.is_null().not() &&
1008 (*it as usize) % ::core::mem::align_of::<T>() == 0
1009 }
1010 ,
1011}}
1012
1013impl_ReprC_for! { unsafe {
1016 @for['out, T : 'out + Sized + ReprC]
1017 Out<'out, T>
1018 => |ref it: *mut T::CLayout| {
1019 (*it as usize) % ::core::mem::align_of::<T>() == 0
1020 },
1021}}
1022
1023pub
1024type OpaqueLayout<T> = OpaqueLayout_<
1025 ::core::marker::PhantomData<T>,
1026>;
1027
1028#[derive(Debug, Clone, Copy)]
1029pub
1030struct OpaqueLayout_<Phantom> (
1031 Phantom,
1032);
1033
1034from_CType_impl_ReprC!(@for[T] OpaqueLayout<T>);
1035unsafe
1036impl<T> CType for OpaqueLayout<T> {
1037 type OPAQUE_KIND = OpaqueKind::Opaque;
1038
1039 __cfg_headers__! {
1040 fn short_name ()
1041 -> String
1042 {
1043 let mut it = String::from("Opaque");
1044 crate::ඞ::append_unqualified_name(&mut it, ::core::any::type_name::<T>());
1045 it
1046 }
1047
1048 fn define_self__impl (
1049 language: &'_ dyn HeaderLanguage,
1050 definer: &'_ mut dyn Definer,
1051 ) -> io::Result<()>
1052 {
1053 language.emit_opaque_type(
1054 definer,
1055 &[
1056 &format!(
1057 "The layout of `{}` is opaque/subject to changes.",
1058 ::core::any::type_name::<T>(),
1059 ),
1060 ],
1061 &PhantomData::<Self>,
1062 )
1063 }
1064 }
1065}
1066
1067#[derive(Debug)]
1068#[repr(transparent)]
1069pub
1070struct Opaque<T> {
1071 pub concrete: T,
1072}
1073
1074impl<T> ::core::ops::Deref for Opaque<T> {
1075 type Target = T;
1076
1077 fn deref (self: &'_ Opaque<T>)
1078 -> &'_ T
1079 {
1080 &self.concrete
1081 }
1082}
1083
1084impl<T> ::core::ops::DerefMut for Opaque<T> {
1085 fn deref_mut (self: &'_ mut Opaque<T>)
1086 -> &'_ mut T
1087 {
1088 &mut self.concrete
1089 }
1090}
1091
1092#[apply(cfg_alloc)]
1093impl<T> From<rust::Box<T>> for rust::Box<Opaque<T>> {
1094 fn from (b: rust::Box<T>)
1095 -> rust::Box<Opaque<T>>
1096 {
1097 unsafe {
1098 rust::Box::from_raw(rust::Box::into_raw(b).cast())
1099 }
1100 }
1101}
1102
1103#[apply(cfg_alloc)]
1104impl<T> From<rust::Box<T>> for crate::boxed::Box_<Opaque<T>> {
1105 fn from (b: rust::Box<T>)
1106 -> repr_c::Box<Opaque<T>>
1107 {
1108 rust::Box::<Opaque<T>>::from(b).into()
1109 }
1110}
1111
1112impl<'r, T> From<&'r T> for &'r Opaque<T> {
1113 fn from (r: &'r T)
1114 -> &'r Opaque<T>
1115 {
1116 unsafe {
1117 &* <*const _>::cast::<Opaque<T>>(r)
1118 }
1119 }
1120}
1121
1122impl<'r, T> From<&'r mut T> for &'r mut Opaque<T> {
1123 fn from (r: &'r mut T)
1124 -> &'r mut Opaque<T>
1125 {
1126 unsafe {
1127 &mut* <*mut _>::cast::<Opaque<T>>(r)
1128 }
1129 }
1130}
1131
1132unsafe
1133impl<T> ReprC for Opaque<T> {
1134 type CLayout = OpaqueLayout<T>;
1135
1136 fn is_valid (_: &'_ Self::CLayout)
1137 -> bool
1138 {
1139 unreachable! {"\
1140 wondering about the validity of an opaque type \
1141 makes no sense\
1142 "};
1143 }
1144}
1145
1146opaque_impls! {
1147 @for['c] ::core::task::Context<'c>,
1148 @for['r] &'r str,
1149 @for['r, T] &'r [T],
1150 @for['r, T] &'r mut [T],
1151 @for[T] ::core::cell::RefCell<T>,
1152}
1153
1154#[cfg(feature = "alloc")]
1155opaque_impls! {
1156 rust::String,
1157 @for[T] rust::Box<T>,
1158 @for[T] ::alloc::rc::Rc<T>,
1159 @for[T] rust::Vec<T>,
1160 @for[K, V] ::alloc::collections::BTreeMap<K, V>,
1161}
1162
1163#[cfg(feature = "std")]
1164opaque_impls! {
1165 @for[K, V] ::std::collections::HashMap<K, V>,
1166 @for[T] ::std::sync::Arc<T>,
1167 @for[T] ::std::sync::Mutex<T>,
1168 @for[T] ::std::sync::RwLock<T>,
1169}
1170
1171macro_rules! opaque_impls {(
1173 $(
1174 $(@for[$($generics:tt)*])? $T:ty
1175 ),* $(,)?
1176) => (
1177 $(
1178 unsafe
1179 impl<$($($generics)*)?>
1180 ReprC
1181 for
1182 $T
1183 where
1184 {
1186 type CLayout = OpaqueLayout<$T>;
1187
1188 fn is_valid (_: &'_ Self::CLayout)
1189 -> bool
1190 {
1191 unreachable! {"\
1192 wondering about the validity of an opaque type \
1193 makes no sense\
1194 "};
1195 }
1196 }
1197 )*
1198)} use opaque_impls;