On 07/15/2016 10:11 AM, nik wrote:
One thing I cant figure out/don't know if is possible is to have a type
that takes "void" (see last unittest)
[...]
Result type:
struct Result(T, E)
{
this(inout T result) inout
{
_result = result;
_is_result = true;
}
this(inout E error) inout
{
_error = error;
_is_result = false;
}
bool is_result() const pure nothrow @safe @property
{
return _is_result;
}
T result() const pure nothrow @safe @property
{
return _result;
}
bool is_error() const pure nothrow @safe @property
{
return !_is_result;
}
E error() const pure nothrow @safe @property
{
return _error;
}
private:
T _result;
bool _is_result;
E _error;
}
void is somewhat special. It can't be used to declare variables or as a
parameter type. So you'll have to approach this a bit differently. You
also can't have a struct constructor with zero parameters.
You can detect void and make it a special case where slightly different
code is generated:
----
struct Result(T, E)
{
static if (!is(T == void)) this(inout T result) inout
{
...
}
...
T result() const pure nothrow @safe @property
{
static if (!is(T == void)) return _result;
}
...
static if (!is(T == void)) T _result;
bool _is_result = true; /* important when T is void */
}
----
[...]
//unittest
//{
// auto result_1 = Result!(void, string)(void);
// auto result_2 = Result!(void, string)(void);
`void` can't be an argument in D. Just leave the list empty:
`Result!(void, string)()`.
// assert(result_1.is_result);
// assert(result_1 == result_2);
//}