Thread overview
How to avoid code duplication in static if branches?
Mar 04, 2012
Andrej Mitrovic
Mar 04, 2012
Daniel Murphy
Mar 04, 2012
Andrej Mitrovic
Mar 04, 2012
Jérôme M. Berger
March 04, 2012
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? :)
March 04, 2012
"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.


March 04, 2012
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.
>
>
>
March 04, 2012
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).
> 
> 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? :)

	There's always this:

void test(T)(T t)
{
   static if (is (T == Foo))
      if (!t.isTrue)
         return;

   check();
}

		Jerome
-- 
mailto:jeberger@free.fr
http://jeberger.free.fr
Jabber: jeberger@jabber.fr