Re: Conditional Compilation Multiple Versions

2017-01-09 Thread Claude via Digitalmars-d-learn

Druntime uses this for its translation of POSIX header files:

https://github.com/dlang/druntime/blob/master/src/core/sys/posix/config.d

An example:

https://github.com/dlang/druntime/blob/master/src/core/sys/posix/sys/resource.d#L96


Ok, I see. Thanks!
(I've gotta try reggae someday) :)




Re: Conditional Compilation Multiple Versions

2017-01-07 Thread Joakim via Digitalmars-d-learn

On Friday, 6 January 2017 at 13:44:37 UTC, Claude wrote:
Yes, it works quite well for most use cases and should 
generally be preferred. I disagree that it scales, though. At 
some point (a point that is highly project-dependent), it 
breaks down, requiring either very large modules or duplicated 
versions across multiple modules.


Yes, in that case, you would probably break it down into 
several specialized config modules. I meant it forces you not 
to put directly version(Windows) into your code, but rather 
version(ThatFeatureSupportedByWindowsAmongstOtherOSs).


Yes, this is the idiom that version() encourages.  You can put 
all your configuration logic in one place in your build script 
and then pass -version=hasFeature to your build.  If you use 
reggae, you can even write your configuration logic in D:


https://github.com/atilaneves/reggae/

My position is that I will always choose version blocks first, 
but if I find myself in a situation where I have to choose 
between duplicating version statements (e.g. version(A) 
{version=AorB; version=AorC;}) across multiple modules and 
restructuring my code to accommodate versioning, I much prefer 
to use the enum alternative as an escape hatch.


Ok, that's interesting.
Do you have code samples where you do that? I'm just curious.


Druntime uses this for its translation of POSIX header files:

https://github.com/dlang/druntime/blob/master/src/core/sys/posix/config.d

An example:

https://github.com/dlang/druntime/blob/master/src/core/sys/posix/sys/resource.d#L96


Re: Conditional Compilation Multiple Versions

2017-01-06 Thread Claude via Digitalmars-d-learn

On Friday, 6 January 2017 at 13:27:06 UTC, Mike Parker wrote:

version(Windows)
enum bool WindowsSupported = true;
else
enum bool WindowsSupported = false;


Well, yes, that was a bad example. I thought to change it before 
sending my post but I could find any other meaningful alternative.
My point was, that you can re-define WindowsSupported as a 
version even if it already defined, but not as an enum. And 
sometimes, you cannot simply use the else statement without 
creating another indented block (which seems a bit awkward).


Yes, it works quite well for most use cases and should 
generally be preferred. I disagree that it scales, though. At 
some point (a point that is highly project-dependent), it 
breaks down, requiring either very large modules or duplicated 
versions across multiple modules.


Yes, in that case, you would probably break it down into several 
specialized config modules. I meant it forces you not to put 
directly version(Windows) into your code, but rather 
version(ThatFeatureSupportedByWindowsAmongstOtherOSs).


My position is that I will always choose version blocks first, 
but if I find myself in a situation where I have to choose 
between duplicating version statements (e.g. version(A) 
{version=AorB; version=AorC;}) across multiple modules and 
restructuring my code to accommodate versioning, I much prefer 
to use the enum alternative as an escape hatch.


Ok, that's interesting.
Do you have code samples where you do that? I'm just curious.


Re: Conditional Compilation Multiple Versions

2017-01-06 Thread Mike Parker via Digitalmars-d-learn


Glad hear it's working for you!

On Friday, 6 January 2017 at 10:25:26 UTC, Claude wrote:


So I had a stream of:

version (Win32)
  enum bool WindowsSupported = true;
else
  enum bool WindowsSupported = false;

version (Win64)
  enum bool WindowsSupported = true; //Ooops
else
  enum bool WindowsSupported = false; //Ooops



These can be condensed to:

version(Win32)
enum bool WindowsSupported = true;
else version(Win64)
enum bool WindowsSupported = true;
else
enum bool WindowsSupported = false;

Or even better, since it doesn't appear you need to distinguish 
between 32-bit & 64-bit:


version(Windows)
enum bool WindowsSupported = true;
else
enum bool WindowsSupported = false;



It turned out to be not so readable (even when using a "string 
mixin" to make the code tighter), and I cannot define twice an 
enum without using "static if", which was a deal-breaker. Also 
the conciseness of the versions for the D compilers (only 4: 
DMD, GDC, LDC and SDC), as well as the different OS versions 
made the code a lot tighter than the C version.


For me, the readability is no issue. I would put that block above 
in a single module (which I like to call config.d) and then 
import it where I need it. This actually is a lot cleaner for the 
corner cases where version breaks down (see below).





So I just dropped the enum definition thing and just used 
"version" as it was designed to be used:


version (Win32)
  version = WindowsSupported;
else version (Win64)
  version = WindowsSupported;
else etc...


version(Windows) { }



That little experience showed that using version as it is 
designed currently is enough to elegantly cover my needs. And 
it seemed to scale well.
Also I think it may force developers to handle all version 
specific stuff into one specific module and define your own 
version identifiers to list features from compiler, OS, target 
architecture version identifiers; which is a good coding 
practice anyway.




Yes, it works quite well for most use cases and should generally 
be preferred. I disagree that it scales, though. At some point (a 
point that is highly project-dependent), it breaks down, 
requiring either very large modules or duplicated versions across 
multiple modules.


My position is that I will always choose version blocks first, 
but if I find myself in a situation where I have to choose 
between duplicating version statements (e.g. version(A) 
{version=AorB; version=AorC;}) across multiple modules and 
restructuring my code to accommodate versioning, I much prefer to 
use the enum alternative as an escape hatch.





Re: Conditional Compilation Multiple Versions

2017-01-06 Thread Claude via Digitalmars-d-learn

On Thursday, 20 October 2016 at 09:58:07 UTC, Claude wrote:
I'm digging up that thread, as I want to do some multiple 
conditional compilation a well.


Well I'm digging up that thread again, but to post some positive 
experience feedback this time as I've found an answer to my own 
questions, and I thought I could share them.


I wanted to convert some C preprocessing code to D: thousands of 
conditional compilation macros #ifdef, #if defined() used in a 
program that determine the capabilities of a platform (number of 
CPU cores, SIMD availability, etc). So it had to check compiler 
types and versions, combined with the target architecture, and 
the OS, and the endianess and so on.


So the C implementation is a stream of:
#if defined(MYOS) || defined(ARCHITECTURE) && 
defined(__weirdstuff)

# define SPECIFIC FEATURE
#else
# blabla
...

And I though I would have to use some || and && operators in my D 
code as well.


So I did. I used that trick from Mike Parker and anonymous (see 
above in the thread) by declaring "enum bool"s to be checked with 
"static if"s later to implement specific feature.


So I had a stream of:

version (Win32)
  enum bool WindowsSupported = true;
else
  enum bool WindowsSupported = false;

version (Win64)
  enum bool WindowsSupported = true; //Ooops
else
  enum bool WindowsSupported = false; //Ooops

It turned out to be not so readable (even when using a "string 
mixin" to make the code tighter), and I cannot define twice an 
enum without using "static if", which was a deal-breaker. Also 
the conciseness of the versions for the D compilers (only 4: DMD, 
GDC, LDC and SDC), as well as the different OS versions made the 
code a lot tighter than the C version.


So I just dropped the enum definition thing and just used 
"version" as it was designed to be used:


version (Win32)
  version = WindowsSupported;
else version (Win64)
  version = WindowsSupported;
else etc...

So to my older question:

* Is there an "idiomatic" or "elegant" way of doing it? Should 
we use Mike Parker solution, or use the "template 
Version(string name)" solution (which basically just circumvent 
"version" specific limitation)?


That little experience showed that using version as it is 
designed currently is enough to elegantly cover my needs. And it 
seemed to scale well.
Also I think it may force developers to handle all version 
specific stuff into one specific module and define your own 
version identifiers to list features from compiler, OS, target 
architecture version identifiers; which is a good coding practice 
anyway.


So:

module mylib.platform;

version (ThisOs)
 version = ThatFeature;
else
 version = blabla;
etc...

And:

module mylib.feature;

void doFeature()
{
version (ThatFeature)
  blabla;
}

But again, that's just my feedback from one single experience 
(even though I think that kind of code is quite common in C/C++ 
cross-platform libraries).


So I'm still curious as why Walter designed "version" that 
particular way, and if anyone has bumped on "version" 
(quasi-)limitations and what they think about it!




Re: Conditional Compilation Multiple Versions

2016-10-20 Thread Claude via Digitalmars-d-learn

On Saturday, 13 June 2015 at 12:21:50 UTC, ketmar wrote:

On Fri, 12 Jun 2015 20:41:59 -0400, bitwise wrote:


Is there a way to compile for multiple conditions?

Tried all these:

version(One | Two){ }
version(One || Two){ }
version(One && Two){ }
version(One) |  version(Two){ }
version(One) || version(Two){ }
version(One) && version(Two){ }

   Bit


nope. Walter is against that, so we'll not have it, despite the 
triviality of the patch.


I'm digging up that thread, as I want to do some multiple 
conditional compilation a well.


I have a couple of questions:
* Why is Walter against that? There must be some good reasons.
* Is there an "idiomatic" or "elegant" way of doing it? Should we 
use Mike Parker solution, or use the "template Version(string 
name)" solution (which basically just circumvent "version" 
specific limitation)?


Here' the kind of stuff I'd like to translate from C:

#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
#define YEP_MICROSOFT_COMPILER
#elif defined(__GNUC__) && !defined(__clang__) && 
!defined(__INTEL_COMPILER) && !defined(__CUDA_ARCH__)

#define YEP_GNU_COMPILER
#elif defined(__INTEL_COMPILER)
...

#if defined(_M_IX86) || defined(i386) || defined(__i386) || 
defined(__i386__) || defined(_X86_) || defined(__X86__) || 
defined(__I86__) || defined(__INTEL__) || defined(__THW_INTEL__)

#define YEP_X86_CPU
#define YEP_X86_ABI
#elif defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__) 
|| defined(__amd64) || defined(__x86_64__) || defined(__x86_64)

...


Re: Conditional Compilation Multiple Versions

2015-06-13 Thread bitwise via Digitalmars-d-learn

On Sat, 13 Jun 2015 12:20:40 -0400, ketmar  wrote:


On Sat, 13 Jun 2015 13:49:49 +, anonymous wrote:


Taking it one step further:

template Version(string name)
{
 mixin("
 version("~name~") enum Version = true;
 else enum Version = false;
 ");
}

static if(Version!"One" || Version!"Two")
{
 ...
}


very elegant.


Elegant indeed, but I think my pull request would be frowned upon if I  
tried to use this in druntime.


  Bit


Re: Conditional Compilation Multiple Versions

2015-06-13 Thread ketmar via Digitalmars-d-learn
On Sat, 13 Jun 2015 13:49:49 +, anonymous wrote:

> Taking it one step further:
> 
> template Version(string name)
> {
>  mixin("
>  version("~name~") enum Version = true;
>  else enum Version = false;
>  ");
> }
> 
> static if(Version!"One" || Version!"Two")
> {
>  ...
> }

very elegant.

signature.asc
Description: PGP signature


Re: Conditional Compilation Multiple Versions

2015-06-13 Thread ketmar via Digitalmars-d-learn
On Sat, 13 Jun 2015 12:01:29 -0400, bitwise wrote:

>> nope. Walter is against that, so we'll not have it, despite the
>> triviality of the patch.
> 
> Any idea what the rationale was for not allowing it?

i don't remember. that murmuring about "it makes the code harder to read" 
goes beyond me, so it's hard to remember.

signature.asc
Description: PGP signature


Re: Conditional Compilation Multiple Versions

2015-06-13 Thread bitwise via Digitalmars-d-learn

On Sat, 13 Jun 2015 08:21:50 -0400, ketmar  wrote:


On Fri, 12 Jun 2015 20:41:59 -0400, bitwise wrote:


Is there a way to compile for multiple conditions?

Tried all these:

version(One | Two){ }
version(One || Two){ }
version(One && Two){ }
version(One) |  version(Two){ }
version(One) || version(Two){ }
version(One) && version(Two){ }

   Bit


nope. Walter is against that, so we'll not have it, despite the
triviality of the patch.


Any idea what the rationale was for not allowing it?

  Bit


Re: Conditional Compilation Multiple Versions

2015-06-13 Thread anonymous via Digitalmars-d-learn

On Saturday, 13 June 2015 at 00:47:37 UTC, Mike Parker wrote:

// config.d
version(One) enum One = true;
else enum One = false;

version(Two) enum Two = true;
else enum Two = false;

// other.d
import config;
static if(One || Two) {
...
}


Taking it one step further:

template Version(string name)
{
mixin("
version("~name~") enum Version = true;
else enum Version = false;
");
}

static if(Version!"One" || Version!"Two")
{
...
}



Re: Conditional Compilation Multiple Versions

2015-06-13 Thread ketmar via Digitalmars-d-learn
On Fri, 12 Jun 2015 20:41:59 -0400, bitwise wrote:

> Is there a way to compile for multiple conditions?
> 
> Tried all these:
> 
> version(One | Two){ }
> version(One || Two){ }
> version(One && Two){ }
> version(One) |  version(Two){ }
> version(One) || version(Two){ }
> version(One) && version(Two){ }
> 
>Bit

nope. Walter is against that, so we'll not have it, despite the 
triviality of the patch.

signature.asc
Description: PGP signature


Re: Conditional Compilation Multiple Versions

2015-06-12 Thread bitwise via Digitalmars-d-learn
On Fri, 12 Jun 2015 20:55:51 -0400, Márcio Martins   
wrote:



I know... I too hate that one can't use simple logic ops...


Indeed...

Thanks.

  Bit


Re: Conditional Compilation Multiple Versions

2015-06-12 Thread via Digitalmars-d-learn

On Saturday, 13 June 2015 at 00:42:00 UTC, bitwise wrote:

Is there a way to compile for multiple conditions?


version(One) version = OneOrTwo;
else version(Two) version = OneOrTwo;

version(OneOrTwo) {
  writeln("moo");
}


---

version(One) version(Two) version = OneAndTwo;

version(OneAndTwo) {
  writeln("moo moo");
}


I know... I too hate that one can't use simple logic ops...


Re: Conditional Compilation Multiple Versions

2015-06-12 Thread Mike Parker via Digitalmars-d-learn

On 6/13/2015 9:41 AM, bitwise wrote:

Is there a way to compile for multiple conditions?

Tried all these:

version(One | Two){ }
version(One || Two){ }
version(One && Two){ }
version(One) |  version(Two){ }
version(One) || version(Two){ }
version(One) && version(Two){ }

   Bit


// config.d
version(One) enum One = true;
else enum One = false;

version(Two) enum Two = true;
else enum Two = false;

// other.d
import config;
static if(One || Two) {
...
}


Conditional Compilation Multiple Versions

2015-06-12 Thread bitwise via Digitalmars-d-learn

Is there a way to compile for multiple conditions?

Tried all these:

version(One | Two){ }
version(One || Two){ }
version(One && Two){ }
version(One) |  version(Two){ }
version(One) || version(Two){ }
version(One) && version(Two){ }

  Bit