View mode: basic / threaded / horizontal-split · Log in · Help
March 04, 2012
How to avoid code duplication in static if branches?
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
Re: How to avoid code duplication in static if branches?
"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
Re: How to avoid code duplication in static if branches?
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
Re: How to avoid code duplication in static if branches?
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
Top | Discussion index | About this forum | D home