www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Quick help on version function parameter

reply "Jonathan Marler" <johnnymarler gmail.com> writes:
Does anyone know a good way to support versioned function 
parameters?  Say, in one version I want a variable to be a global 
and in another I want it to be a parameter.

version(GlobalVersion)
{
     int x;
     void foo()
     {
         // A huge function that uses x
     }
} else {
     void foo(int x)
     {
         // A huge function that uses x (same code as 
GlobalVersion)
     }
}

The problem with this is that the code is duplicated.  Is there a 
way to do this versioning without having 2 copies of the same 
function body?  The following definitely does not work:

version(GlobalVersion)
{
     int x;
     void foo()
} else {
     void foo(int x)
}
     {
         // A huge function that uses x
     }
Feb 18 2015
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
I'd write a foo_impl which always takes a parameter. Then do the 
versioned foo() functions which just forward to it:

void foo_impl(int x) { long function using x here }

version(globals) {
    int x;
    void foo() {
       foo_impl(x);
    }
} else {
    void foo(int x) { foo_impl(x); }
}

Minimal duplication with both interfaces.
Feb 18 2015
parent reply "Jonathan Marler" <johnnymarler gmail.com> writes:
On Wednesday, 18 February 2015 at 23:49:26 UTC, Adam D. Ruppe 
wrote:
 I'd write a foo_impl which always takes a parameter. Then do 
 the versioned foo() functions which just forward to it:

 void foo_impl(int x) { long function using x here }

 version(globals) {
    int x;
    void foo() {
       foo_impl(x);
    }
 } else {
    void foo(int x) { foo_impl(x); }
 }

 Minimal duplication with both interfaces.
That kinda defeats the purpose of why I want this. It's for performance reasons. I need one version to have NO arguments and one version to have one ref argument.
Feb 18 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Thursday, 19 February 2015 at 01:39:19 UTC, Jonathan Marler 
wrote:
 On Wednesday, 18 February 2015 at 23:49:26 UTC, Adam D. Ruppe 
 wrote:
 I'd write a foo_impl which always takes a parameter. Then do 
 the versioned foo() functions which just forward to it:

 void foo_impl(int x) { long function using x here }

 version(globals) {
   int x;
   void foo() {
      foo_impl(x);
   }
 } else {
   void foo(int x) { foo_impl(x); }
 }

 Minimal duplication with both interfaces.
That kinda defeats the purpose of why I want this. It's for performance reasons. I need one version to have NO arguments and one version to have one ref argument.
If it's a `ref` argument (your original example doesn't have one), are you sure there will be a performance problem? Anyway, how about using a template and an alias, respectively: void foo_impl(ref ExpensiveStruct x) { ... } version(globals) { ExpensiveStruct x; void foo()() { foo_impl(x); } } else { alias foo = foo_impl; } That way, you'd force `foo` to be instantiated at the call site, making it more likely to be inlinable. In the non-global case, there will be no overhead at all because of the `alias`. But, as always for things related to performance: profile first, then optimize.
Feb 19 2015