www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to avoid code duplication in static if branches?

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
import std.stdio;
void check() { writeln("check"); }

struct Foo { bool isTrue = true; }
struct Bar { }

void test(T)(T t)
{
    static if (is(T == Foo))
    {
        if (t.isTrue)
            check();
    }
    else
    {
        check();
    }
}

void main()
{
    Foo foo;
    Bar bar;
    test(foo);
    test(bar);
}

I want to avoid writing "check()" twice. I only have to statically
check a field of a member if it's of a certain type (Foo).

One solution would be to use a boolean:
void test(T)(T t)
{
    bool isTrue = true;
    static if (is(T == Foo))
        isTrue = t.isTrue;

    if (isTrue)
        check();
}

But that kind of defeats the purpose of static if (avoiding runtime
overhead). Does anyone have a trick up their sleeve for these types of
situations? :)
Mar 03 2012
next sibling parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message 
news:mailman.364.1330825349.24984.digitalmars-d-learn puremagic.com...
 import std.stdio;
 void check() { writeln("check"); }

 struct Foo { bool isTrue = true; }
 struct Bar { }

 void test(T)(T t)
 {
    static if (is(T == Foo))
    {
        if (t.isTrue)
            check();
    }
    else
    {
        check();
    }
 }

 void main()
 {
    Foo foo;
    Bar bar;
    test(foo);
    test(bar);
 }

 I want to avoid writing "check()" twice. I only have to statically
 check a field of a member if it's of a certain type (Foo).

 One solution would be to use a boolean:
 void test(T)(T t)
 {
    bool isTrue = true;
    static if (is(T == Foo))
        isTrue = t.isTrue;

    if (isTrue)
        check();
 }

 But that kind of defeats the purpose of static if (avoiding runtime
 overhead). Does anyone have a trick up their sleeve for these types of
 situations? :)

Have you checked the generated code? When the static if check fails, it should be reduced to:
 void test(T)(T t)
 {
    bool isTrue = true;

    if (isTrue)
        check();
 }

And the compiler should be able to tell that isTrue is always true. Otherwise, void test(T)(T t) { enum doCheck = is(T == Foo); bool isTrue = true; static if (is(T == Foo)) auto isTrue = t.isTrue; if (!doCheck || isTrue) check(); } The compiler takes care of it because doCheck is known at compile time.
Mar 03 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
You're right it should be able do that dead-code elimination thing.
Slipped my mind. :)

On 3/4/12, Daniel Murphy <yebblies nospamgmail.com> wrote:
 "Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message
 news:mailman.364.1330825349.24984.digitalmars-d-learn puremagic.com...
 import std.stdio;
 void check() { writeln("check"); }

 struct Foo { bool isTrue = true; }
 struct Bar { }

 void test(T)(T t)
 {
    static if (is(T == Foo))
    {
        if (t.isTrue)
            check();
    }
    else
    {
        check();
    }
 }

 void main()
 {
    Foo foo;
    Bar bar;
    test(foo);
    test(bar);
 }

 I want to avoid writing "check()" twice. I only have to statically
 check a field of a member if it's of a certain type (Foo).

 One solution would be to use a boolean:
 void test(T)(T t)
 {
    bool isTrue = true;
    static if (is(T == Foo))
        isTrue = t.isTrue;

    if (isTrue)
        check();
 }

 But that kind of defeats the purpose of static if (avoiding runtime
 overhead). Does anyone have a trick up their sleeve for these types of
 situations? :)

Have you checked the generated code? When the static if check fails, it should be reduced to:
 void test(T)(T t)
 {
    bool isTrue = true;

    if (isTrue)
        check();
 }

And the compiler should be able to tell that isTrue is always true. Otherwise, void test(T)(T t) { enum doCheck = is(T == Foo); bool isTrue = true; static if (is(T == Foo)) auto isTrue = t.isTrue; if (!doCheck || isTrue) check(); } The compiler takes care of it because doCheck is known at compile time.

Mar 03 2012
prev sibling parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Andrej Mitrovic wrote:
 ...snip...
 I want to avoid writing "check()" twice. I only have to statically
 check a field of a member if it's of a certain type (Foo).
=20
 One solution would be to use a boolean:
 void test(T)(T t)
 {
     bool isTrue =3D true;
     static if (is(T =3D=3D Foo))
         isTrue =3D t.isTrue;
=20
     if (isTrue)
         check();
 }
=20
 But that kind of defeats the purpose of static if (avoiding runtime
 overhead). Does anyone have a trick up their sleeve for these types of
 situations? :)

There's always this: void test(T)(T t) { static if (is (T =3D=3D Foo)) if (!t.isTrue) return; check(); } Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Mar 03 2012