www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - if auto and method call

reply Jethro <qyzz gr.ff> writes:
How to combine the need to localize a result for an if statement 
and have to call a method to get proper comparison:

if (((auto x = X.value()).empty())
{

}

instead of having to do the long and winded way

auto x = X.value();
if (x.empty())
{

}

Many times I need the result of a function inside the if but need 
to check on other value of the function:

auto x = foo();
if (foo().valid())
{
  // use x
}

which should simplify to

if ((auto x = foo()).valid())
{

}

but this code does not work.


I generally need this for regex stuff and it's quite annoying it 
doesn't work.

if (!match(s, "\s*(?P<t>.),").empty())
{
// Need the result of match to do things!
}

but this doesn't work:


if (!(auto r = match(s, "\s*(?P<t>.),")).empty())
{

}


which then requires one to do

auto r = match(s, "\s*(?P<t>.),");
if (!r.empty())
{

}

Doesn't seem like a big deal but seems trivial to implement. We 
can't always do a simple boolean test of the variable we are 
defining:

if (auto x = something)

so we should be able to do

if ((auto x = something).bar())

which is equivalent to

x = something;
if (x.bar())

or even allow

if ((auto x = something) == 3)
{

}
Apr 17
next sibling parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
Would be prettier as a language feature, but still:

template test(alias pred)
{
     import std.functional : unaryFun;
     alias P = unaryFun!pred;

     auto test(R)(R r)
     {
         struct Test
         {
             R v;

             string toString()
             {
                 import std.conv : to;
                 return v.to!string;
             }

             bool opCast(B : bool)() const
             {
                 return P(v);
             }

             ref inout(R) get() inout
             {
                 return v;
             }

             alias get this;
         }

         import std.algorithm : move;
         return Test(move(r));
     }
}

void main()
{
     import std.regex;
     import std.stdio;
     string s1 = "hello";
     string s2 = "world";

     if (auto x = test!"!a.empty"(match(s1, "hello")))
     {
         writeln(x.captures[0]);
     }

     if (auto x = test!"!a.empty"(match(s2, "hello")))
     {
         writeln(x.captures[0]);
         assert(0);
     }

     // UFCS:

     if (auto x = s1.match("world").test!"!a.empty")
     {
         writeln(x.captures[0]);
         assert(0);
     }

     if (auto x = s2.match("world").test!"!a.empty")
     {
         writeln(x.captures[0]);
     }

     if (auto x = 3.test!"a == 3")
     {
         writeln(x, " equals 3, huh?");
     }
}
Apr 17
prev sibling next sibling parent ag0aep6g <anonymous example.com> writes:
On 04/18/2017 02:48 AM, Jethro wrote:
 I generally need this for regex stuff and it's quite annoying it doesn't
 work.

 if (!match(s, "\s*(?P<t>.),").empty())
 {
 // Need the result of match to do things!
 }

 but this doesn't work:


 if (!(auto r = match(s, "\s*(?P<t>.),")).empty())
 {

 }
Stanislav Blinov has shown how overloading `cast(bool)` can help here. In fact, std.regex.RegexMatch does just that. So this works: ---- if (auto r = match(s, "\s*(?P<t>.),")) { /* ... use r here ... */ } ----
Apr 17
prev sibling parent reply Andrea Fontana <nospam example.com> writes:
On Tuesday, 18 April 2017 at 00:48:05 UTC, Jethro wrote:
 How to combine the need to localize a result for an if 
 statement and have to call a method to get proper comparison:
 [...]
 which should simplify to

 if ((auto x = foo()).valid())
 {

 }

 but this code does not work.
 [...]
for(auto x = foo(); foo.valid();) { ... your code here ... break; } it would be useful if this syntax was supported: for(auto x = foo(); foo.valid(); break) { } Andrea
Apr 18
parent Andrea Fontana <nospam example.com> writes:
On Tuesday, 18 April 2017 at 09:05:10 UTC, Andrea Fontana wrote:
 On Tuesday, 18 April 2017 at 00:48:05 UTC, Jethro wrote:
 How to combine the need to localize a result for an if 
 statement and have to call a method to get proper comparison:
 [...]
 which should simplify to

 if ((auto x = foo()).valid())
 {

 }

 but this code does not work.
 [...]
for(auto x = foo(); foo.valid();) { ... your code here ... break; } it would be useful if this syntax was supported: for(auto x = foo(); foo.valid(); break) { } Andrea
Whoops i mean: for (auto x = foo(); x.valid;) { ... break; }
Apr 18