Thread overview
if auto and method call
Apr 18, 2017
Jethro
Apr 18, 2017
Stanislav Blinov
Apr 18, 2017
ag0aep6g
Apr 18, 2017
Andrea Fontana
Apr 18, 2017
Andrea Fontana
April 18, 2017
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)
{

}




April 18, 2017
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?");
    }
}

April 18, 2017
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 ... */
}
----
April 18, 2017
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
April 18, 2017
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;
}