import std.string;

template isNonNullable(T)
{
    enum bool isNonNullable = !is(T == typeof(null)) && is (T : Object);
}

NN!T toNN(T)(T value) if (isNonNullable!(T))
{
    assert(value !is null);
    return NN!T(value);
}

struct NN(T) if (isNonNullable!(T))
{
    private T _value;
    alias value this;

    private this(T value)
    {
        _value = value;
    }

    public T value()
    out(result)
    {
        assert(result !is null);
    }
    body
    {
        return _value;
    }

    public NN!T opAssign(AT)(AT rhs)
        if (is(NN!T == AT))
    {
        return rhs;
    }

    public NN!T opAssign(AT)(AT rhs)
        if (__traits(compiles, _value = rhs.value) && !is(NN!T == AT))
    {
        return NN!T(rhs.value);
    }

    invariant()
    {
        assert(_value !is null);
    }
}
