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
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| $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]
        // Box<T> => |it| it.is_null(),
        @for[T : ReprC]
        c_slice::Box<T> => |it| it.ptr.is_null(),
        @for[T : ReprC]
        Vec<T> => |it| it.ptr.is_null(),

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

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

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