Thread overview
Trouble checking for null-ness
Jul 25, 2016
Bahman Movaqar
Jul 25, 2016
ketmar
Jul 25, 2016
ag0aep6g
Jul 25, 2016
Cauterite
Jul 25, 2016
Cauterite
Jul 25, 2016
Mike Parker
Jul 25, 2016
Bahman Movaqar
Jul 25, 2016
Adam D. Ruppe
Jul 26, 2016
Bahman Movaqar
July 25, 2016
Suppose I have the following function:

    public auto max(alias comp, Range)(Range r)
    in {
      assert(r !is null && !r.empty);
    }
    body {
      // ...
    }

When the function after a series of chained `map` operations, I get the following error:

    Error: incompatible types for ((r) !is (null)):
'MapResult!(__lambda2, SInvoiceLine[])' and 'typeof(null)'

Of course if I remove `r !is null` from the `in` block, everything will work.  But I'm curious; how can I check for a `null` in this case?

Thanks,
-- 
Bahman
July 25, 2016
static if (is(typeof(r is null))) { ...you can do your assert here... }
July 25, 2016
On Monday, 25 July 2016 at 12:37:18 UTC, Bahman Movaqar wrote:
>     Error: incompatible types for ((r) !is (null)):
> 'MapResult!(__lambda2, SInvoiceLine[])' and 'typeof(null)'
>
> Of course if I remove `r !is null` from the `in` block, everything will work.  But I'm curious; how can I check for a `null` in this case?

You can't. null is not a valid value for the return type of map.
July 25, 2016
On Monday, 25 July 2016 at 12:37:18 UTC, Bahman Movaqar wrote:
But I'm curious; how can I check for a
> `null` in this case?

Well, if you're happy with assertion failure by access violation, you may not even need to check for null, because generally if you try to call .empty on a null pointer you'll get an access violation (killing two birds with one stone).

Otherwise you could try
(!__traits(compiles, r is null) || r !is null) && !r.empty
July 25, 2016
On Monday, 25 July 2016 at 12:47:25 UTC, Cauterite wrote:
> (!__traits(compiles, r is null) || r !is null) && !r.empty

Ah, whoops that's wrong, looks like ketmar had the right idea.
July 25, 2016
On Monday, 25 July 2016 at 12:37:18 UTC, Bahman Movaqar wrote:
> Suppose I have the following function:
>
>     public auto max(alias comp, Range)(Range r)
>     in {
>       assert(r !is null && !r.empty);
>     }
>     body {
>       // ...
>     }
>
> When the function after a series of chained `map` operations, I get the following error:
>
>     Error: incompatible types for ((r) !is (null)):
> 'MapResult!(__lambda2, SInvoiceLine[])' and 'typeof(null)'
>
> Of course if I remove `r !is null` from the `in` block, everything will work.  But I'm curious; how can I check for a `null` in this case?

In the general case, the vast majority of ranges you work with will be value types. In the rare case where it's a reference type, you can use static if to specialize the assert. Two possibilities have already been suggested in this thread, but given that ranges are nearly always going to be a struct or a class, then you might do this inside the template:

static if(is(Range == class)) { // check for null }

You may also want to add a constraint:

import std.range : isInputRange;
public auto max(alias comp, Range)(Range r) if(isInputRange!Range) {
   static if(is(Range == class)) assert(r !is null && !r.empty);
   else assert(!r.empty);
}



July 25, 2016
On 07/25/2016 05:07 PM, Bahman Movaqar wrote:
> Suppose I have the following function:
> 
>     public auto max(alias comp, Range)(Range r)
>     in {
>       assert(r !is null && !r.empty);
>     }
>     body {
>       // ...
>     }
> 
> When the function after a series of chained `map` operations, I get the following error:
> 
>     Error: incompatible types for ((r) !is (null)):
> 'MapResult!(__lambda2, SInvoiceLine[])' and 'typeof(null)'
> 
> Of course if I remove `r !is null` from the `in` block, everything will work.  But I'm curious; how can I check for a `null` in this case?

Thank you people for the answers.
From what I could gather, it's not possible to check for `null` at
runtime for reference based types.  Am I right?

-- 
Bahman
July 25, 2016
On Monday, 25 July 2016 at 13:09:22 UTC, Bahman Movaqar wrote:
> From what I could gather, it's not possible to check for `null` at
> runtime for reference based types.  Am I right?

No, it is only possible to check for null for reference based types. But map's result is not a reference based type.
July 26, 2016
On 07/25/2016 05:47 PM, Adam D. Ruppe wrote:
> On Monday, 25 July 2016 at 13:09:22 UTC, Bahman Movaqar wrote:
>> From what I could gather, it's not possible to check for `null` at runtime for reference based types.  Am I right?
> 
> No, it is only possible to check for null for reference based types. But map's result is not a reference based type.

Oh, I see now.  Thanks.

-- 
Bahman