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
#![cfg_attr(rustfmt, rustfmt::skip)]
use_prelude!();
use crate::prelude::c_slice;

pub
unsafe
trait HasNiche : ReprC {
    fn is_niche (it: &'_ <Self as ReprC>::CLayout)
      -> bool
    ;
}

unsafe
impl<T : ReprC + HasNiche> ReprC
    for Option<T>
{
    type CLayout = <T as ReprC>::CLayout;

    #[inline]
    fn is_valid (it: &'_ Self::CLayout)
      -> bool
    {
        T::is_niche(it) || <T as ReprC>::is_valid(it)
    }
}

macro_rules! unsafe_impls {(
    $(
        $(@for[$($generics:tt)*])?
        $T:ty => |$it:pat_param| $expr:expr
    ),* $(,)?
) => (
    $(
        unsafe
        impl$(<$($generics)*>)? HasNiche
            for $T
        {
            #[inline]
            fn is_niche ($it: &'_ <Self as ReprC>::CLayout)
              -> bool
            {
                $expr
            }
        }
    )*
)}

unsafe_impls! {
    @for['__, T : '__ + ReprC]
    &'__ T => |it| it.is_null(),
    @for['__, T : '__ + ReprC]
    &'__ mut T => |it| it.is_null(),

    @for[T : ReprC]
    ptr::NonNull<T> => |it| it.is_null(),
    @for[T : ReprC]
    ptr::NonNullRef<T> => |it| it.is_null(),
    @for[T : ReprC]
    ptr::NonNullMut<T> => |it| it.is_null(),
    @for[T : ReprC]
    ptr::NonNullOwned<T> => |it| it.is_null(),

    @for['__, T : '__ + ReprC]
    c_slice::Mut<'__, T> => |it| it.ptr.is_null(),
    @for['__, T : '__ + ReprC]
    c_slice::Ref<'__, T> => |it| it.ptr.is_null(),
    @for[T : ReprC]
    c_slice::Raw<T> => |it| it.ptr.is_null(),

    // crate::str::Raw => |it| it.ptr.is_null(),
    // str::Ref<'_> => |it| it.ptr.is_null(),

    // char_p::Ref<'_> => |it| it.is_null(),
    // char_p::Raw => |it| it.is_null(),

    // bool => |&it| {
    //     it == unsafe { mem::transmute(None::<bool>) }
    // },
}

cfg_alloc! {
    unsafe_impls! {
        // @for[T : ReprC]
        // repr_c::Box<T> => |it| it.is_null(),
        @for[T : ReprC]
        c_slice::Box<T> => |it| it.ptr.is_null(),
        @for[T : ReprC]
        repr_c::Vec<T> => |it| it.ptr.is_null(),

        // str::Box => |it| it.ptr.is_null(),
        // repr_c::String => |it| it.ptr.is_null(),

        // char_p::Box => |it| it.is_null(),
    }
}

unsafe_impls! {
    @for['out, T : 'out + ReprC]
    Out<'out, T> => |it| it.is_null()
}