Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
June 20, 2012 Nullable types | ||||
---|---|---|---|---|
| ||||
I've made my own nullable type, and I think it works a bit more naturally than Phobos's in some cases, since it takes advantage of alias this and typeof(null) and some stuff. (It's designed to mimic C#'s nullable types.) Would it be a good addition to Phobos? If not, ideas on what could be improved? //============================= private struct NullableTag { } template isNullable(T) { enum isNullable = __traits(compiles, T.init == null); } template Nullable(T) { static if (isNullable!(T)) { alias T Nullable; } else { struct Nullable { // To tell if something is Nullable private alias .NullableTag NullableTag; private T _value; private bool _hasValue; public this(A)(auto ref A value) inout /+pure @safe nothrow+/ { this._value = value; this._hasValue = true; } public this(A : typeof(null))(A) inout /+pure @safe nothrow+/ { } public @property ref const(bool) hasValue() const /+pure @safe nothrow+/ { return this._hasValue; } public @property ref inout(T) value() inout /+pure @safe+/ { return *(this._hasValue ? &this._value : null); } public int opCmp(RHS)(scope RHS rhs) const /+pure @safe nothrow+/ if (!is(RHS.NullableTag == NullableTag)) { int r; if (this.hasValue) { static if (__traits(compiles, this._value.opCmp(rhs))) { r = this._value.opCmp(rhs._value); } else { r = this._value < rhs ? -1 : (this._value > rhs ? 1 : 0); } } else { r = -1; } return r; } public int opCmp(RHS)(scope RHS rhs) const /+pure @safe nothrow+/ if (is(RHS.NullableTag == NullableTag)) { int r; if (this.hasValue && rhs.hasValue) { r = 0; } else if (this.hasValue && !rhs.hasValue) { r = 1; } else if (!this.hasValue && rhs.hasValue) { r = -1; } else { r = this == rhs._value; } return r; } public int opCmp(RHS : typeof(null))(scope RHS) const /+pure @safe nothrow+/ { return this.hasValue ? 1 : 0; } public bool opEquals(RHS)(scope RHS rhs) const /+pure @safe nothrow+/ if (!is(RHS.NullableTag == NullableTag)) { return this.hasValue && this._value == rhs; } public bool opEquals(RHS)(scope RHS rhs) const /+pure @safe nothrow+/ if (is(RHS.NullableTag == NullableTag)) { return this.hasValue == rhs.hasValue && this._value == rhs._value; } public bool opEquals(RHS : typeof(null))(scope RHS) const /+pure @safe nothrow+/ { return !this.hasValue; } static if (!is(T == const(T))) { public auto ref opAssign(RHS)(auto ref RHS rhs) /+pure @safe nothrow+/ { this._value = rhs; this._hasValue = true; return rhs; } public auto ref opAssign(RHS : typeof(null))(auto ref RHS rhs) /+pure @safe nothrow+/ { this._value = T.init; this._hasValue = false; return rhs; } } public alias value this; } } } unittest { Nullable!int a = null; Nullable!int b = 5; int c = 5; assert(a != b); assert(b == c); assert(a == null); assert(b != null); assert(b + 1 == 6); struct S { public bool opEquals(S) const pure @safe nothrow { return true; } public bool opEquals(int) const pure @safe nothrow { return true; } } Nullable!S s; assert(s != 0); assert(s.opCmp(null) == 0); assert(a.opCmp(null) == 0); assert(b.opCmp(null) > 0); assert(b.opCmp(6) < 0); assert(b.opCmp(5) == 0); } @property Nullable!(T) nullable(T)(auto ref T value) /+pure @safe nothrow+/ { Nullable!(T) result = value; return result; } |
June 20, 2012 Re: Nullable types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mehrdad | Mehrdad: > Would it be a good addition to Phobos? If not, ideas on what could be improved? What are the advantages over this one? http://dlang.org/phobos/std_typecons.html#Nullable Bye, bearophile |
June 20, 2012 Re: Nullable types | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Wednesday, 20 June 2012 at 16:52:26 UTC, bearophile wrote:
> Mehrdad:
>
>> Would it be a good addition to Phobos? If not, ideas on what could be improved?
>
> What are the advantages over this one?
> http://dlang.org/phobos/std_typecons.html#Nullable
>
> Bye,
> bearophile
I thought I mentioned?
1. It uses typeof(null) to _actually_ integrate with _null_, instead of making up methods like nullify(), get(), etc.
2. It tries to do what C# does. (opEquals, opCmp, etc.)
|
June 20, 2012 Re: Nullable types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mehrdad | On Wednesday, 20 June 2012 at 17:43:27 UTC, Mehrdad wrote:
> I thought I mentioned?
>
> 1. It uses typeof(null) to _actually_ integrate with _null_, instead of making up methods like nullify(), get(), etc.
>
> 2. It tries to do what C# does. (opEquals, opCmp, etc.)
In case that wasn't clear...
1. You can't pass Phobos's Nullable type to something and expect "foo = null;" to work... even though it's supposed to be "nullable". The interface is pretty wacky. (opAssign, opCmp, opEquals)
2. It doesn't properly handle the comparison of e.g. Nullable!bool (or anything else for that matter).
3. It uses .clear(_value), which I believe is unnecessary. Just _value = T.init should be enough.
etc.
Also, side point:
I don't understand the point of Nullable(T, T nullValue) or NullableRef(T)... are they /actually/ useful? Or were they just there to span the entire vector space, so to speak? :P
|
June 21, 2012 Re: Nullable types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mehrdad | On Wednesday, 20 June 2012 at 17:43:27 UTC, Mehrdad wrote:
> On Wednesday, 20 June 2012 at 16:52:26 UTC, bearophile wrote:
>> Mehrdad:
>>
>>> Would it be a good addition to Phobos? If not, ideas on what could be improved?
>>
>> What are the advantages over this one?
>> http://dlang.org/phobos/std_typecons.html#Nullable
>>
>> Bye,
>> bearophile
>
> I thought I mentioned?
>
> 1. It uses typeof(null) to _actually_ integrate with _null_, instead of making up methods like nullify(), get(), etc.
>
> 2. It tries to do what C# does. (opEquals, opCmp, etc.)
It sounds to me like you address some bugs in the existing implementation, And possible poor design/limitation of the early days.
You should probably add 2 as a bug report, then you could have a pull request to address them.
Item 1 would be a breaking change, though in my limited view is the right direction. It would not be good for a pull request to address both 1 & 2 together. Unless of course you end up with more feedback contradicting such claim.
|
April 20, 2016 Re: Nullable types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mehrdad | On Wednesday, 20 June 2012 at 16:31:34 UTC, Mehrdad wrote:
> I've made my own nullable type, and I think it works a bit more naturally than Phobos's in some cases, since it takes advantage of alias this and typeof(null) and some stuff.
>
> [...]
Mehrdad, you sir, are a wizard. Hat off to you!
|
Copyright © 1999-2021 by the D Language Foundation