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);
//}

Reply via email to