www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to check for combinations of versions

reply Blatnik <blatblatnik gmail.com> writes:
Is there any way to check for multiple conditions in a `version` 
statement?

For example, my platform may have `Version_A` and `Version_B`, 
and both versions provide some shiny feature I want to use. Is 
there some nice way to write:

```D
version (Version_A || Version_B) {
   // Use the cool feature.
} else {
   // Do something less cool but portable.
}
```

Currently I resort to something like this, but I'm curious if 
there's a nicer way to do it.

```D
version (Version_A) {
   enum Cool_Feature_Supported = true;
} else version (Version_B) {
   enum Cool_Feature_Supported = true;
} else {
   enum Cool_Feature_Supported = false;
}

...

void do_something_cool() {
   static if (Cool_Feature_Supported) {
     ...
   } else {
     ...
   }
}
```
May 05 2021
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 5 May 2021 at 15:03:16 UTC, Blatnik wrote:
 Currently I resort to something like this, but I'm curious if 
 there's a nicer way to do it.

 ```D
 version (Version_A) {
   enum Cool_Feature_Supported = true;
 } else version (Version_B) {
   enum Cool_Feature_Supported = true;
 } else {
   enum Cool_Feature_Supported = false;
 }
 ```
This is the officially-recommended way to do it. D's `version` system is deliberately restricted, in order to avoid the "`#ifdef` hell" that often plagues C and C++ projects. However, if you really want something more expressive, and are confident in your ability to use the extra power responsibly, it is possible to work around these limitations: template hasVersion(string identifier) { mixin( "version(", identifier, ") enum hasVersion = true;", "else enum hasVersion = false;" ); } // Usage static if (hasVersion!"Version_A" || hasVersion!"Version_B") { enum Cool_Feature_Supported = true; } else { enum Cool_Feature_Supported = false; }
May 05 2021
parent Blatnik <blatblatnik gmail.com> writes:
On Wednesday, 5 May 2021 at 15:25:31 UTC, Paul Backus wrote:
 However, if you really want something more expressive, and are 
 confident in your ability to use the extra power responsibly, 
 it is possible to work around these limitations:

     template hasVersion(string identifier) {
         mixin(
             "version(", identifier, ") enum hasVersion = true;",
             "else enum hasVersion = false;"
         );
     }
Hmm, I'll keep this in mind in case things start getting start getting more out of hand. Thanks! :) Mixin strings are still kind of like black magic to me, so I prefer not to use them unless I really think they would help a lot. In this case, I only do this 3 times in the entire codebase, so it's not worth it yet. And Dennis, sadly that wouldn't work for me since `version = XYZ` only affects the current module and I'm using this check in multiple modules. Thanks for the help!
May 05 2021
prev sibling parent Dennis <dkorpel gmail.com> writes:
On Wednesday, 5 May 2021 at 15:03:16 UTC, Blatnik wrote:
 Is there any way to check for multiple conditions in a 
 `version` statement?
No, and that's by design to discourage complex version logic. The recommended approach is: ```D version (Version_A) version = Cool_Feature_Supported; version (Version_B) version = Cool_Feature_Supported; void do_something_cool() { version(Cool_Feature_Supported) { ... } else { ... } } ```
May 05 2021