www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Trouble checking for null-ness

reply Bahman Movaqar <Bahma BahmanM.com> writes:
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
Jul 25 2016
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
static if (is(typeof(r is null))) { ...you can do your assert 
here... }
Jul 25 2016
prev sibling next sibling parent ag0aep6g <anonymous example.com> writes:
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.
Jul 25 2016
prev sibling next sibling parent reply Cauterite <cauterite gmail.com> writes:
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
Jul 25 2016
parent Cauterite <cauterite gmail.com> writes:
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.
Jul 25 2016
prev sibling next sibling parent Mike Parker <aldacron gmail.com> writes:
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); }
Jul 25 2016
prev sibling parent reply Bahman Movaqar <Bahma BahmanM.com> writes:
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
Jul 25 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Jul 25 2016
parent Bahman Movaqar <Bahma BahmanM.com> writes:
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
Jul 25 2016