www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Set variable at compile time

reply "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
Hello,

I am writing code that uses a structure containing an array of
points where the points may be of arbitrary dimension (though
generally small).  I would like to be able to pass the point
dimension to my structure as a template parameter.

One solution is to create instances of these structures for all
reasonable dimensions and then select the correct instance at run
time I suppose. However, I don't really want to set a limit on
the point dimension.

Since the actual program is quite small, and the datasets I want
to apply it to are generally going to be large, I thought it
would make sense to generate the program from source for each
'run' and simply specify the dimension at compile time.  But that
is where I am stuck.

I looked at the compiler switches
(http://dlang.org/dmd-linux.html) but if there is a compiler
switch to do this I missed it.  I suppose I could use version()
statements, but that seems like a bit of a hack.

So my question is, is there some straightforward way of doing
what I want here.

Cheers,

Craig
Oct 30 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
It won't really work on the command line alone, but the way I do 
it is a two step thing. First, make the thing use a config module:

import myproject.config;

alias Thing Thing_Impl!dim;

then you go ahead and use Thing, which is instantiated with the 
dimension. Then the user makes a file:

module myproject.config;

enum dim = 10; // or whatever


and compiles it all:

dmd main.d yourlib.d config.d

and it works out. They can swap out config.d for other files with 
other values and definitions on the command line to customize it.


It would also be possible to provide a default if you go with the 
whole library route, compiling the default into the .lib and 
giving the default in the project include path, both of which 
would be overridden by the user's explicit config source file on 
the command line.



So not as simple as -Ddim=10, but gets the job done. You can also 
use this technique with static if to version stuff out they don't 
want and other similar tasks; I actually like it better than 
-version for the most part.
Oct 30 2013
parent "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Wednesday, 30 October 2013 at 20:19:11 UTC, Adam D. Ruppe
wrote:
 It won't really work on the command line alone, but the way I 
 do it is a two step thing. First, make the thing use a config 
 module:

 import myproject.config;

 alias Thing Thing_Impl!dim;

 then you go ahead and use Thing, which is instantiated with the 
 dimension. Then the user makes a file:

 module myproject.config;

 enum dim = 10; // or whatever


 and compiles it all:

 dmd main.d yourlib.d config.d

 and it works out. They can swap out config.d for other files 
 with other values and definitions on the command line to 
 customize it.


 It would also be possible to provide a default if you go with 
 the whole library route, compiling the default into the .lib 
 and giving the default in the project include path, both of 
 which would be overridden by the user's explicit config source 
 file on the command line.



 So not as simple as -Ddim=10, but gets the job done. You can 
 also use this technique with static if to version stuff out 
 they don't want and other similar tasks; I actually like it 
 better than -version for the most part.
This should work for what I want, and I was thinking of something along these lines, but was hoping there might be a simpler solution. Craig
Oct 30 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/30/2013 01:11 PM, Craig Dillabaugh wrote:

 I am writing code that uses a structure containing an array of
 points where the points may be of arbitrary dimension (though
 generally small).  I would like to be able to pass the point
 dimension to my structure as a template parameter.
struct Point {} struct S(size_t N) { Point[N] points; } alias S2D = S!2; alias S3D = S!3; void main() {}
 One solution is to create instances of these structures for all
 reasonable dimensions and then select the correct instance at run
 time I suppose.
Do you need a common interface, or all of the algoritms will be templatized as well? In other words, what is the type that the following function returns? ??? selectInstance(size_t N) { // return S2D or S3D? } You can have an interface that the template implements: interface SInterface { void foo(); } class S(size_t N) : SInterface { Point[N] points; void foo() { /* implementation for N */ } } Now selectInstance() returns SInterface: SInterface selectInstance(size_t N) { // ... }
 However, I don't really want to set a limit on
 the point dimension.
All of the instances must be known at compile time. So, your program is always limited with the number of actual instances that the program is using. Ali
Oct 30 2013
parent reply "Craig Dillabaugh" <cdillaba cg.scs.carleton.ca> writes:
On Wednesday, 30 October 2013 at 20:23:58 UTC, Ali Çehreli wrote:
 On 10/30/2013 01:11 PM, Craig Dillabaugh wrote:

 I am writing code that uses a structure containing an array of
 points where the points may be of arbitrary dimension (though
 generally small).  I would like to be able to pass the point
 dimension to my structure as a template parameter.
struct Point {} struct S(size_t N) { Point[N] points; } alias S2D = S!2; alias S3D = S!3; void main() {}
 One solution is to create instances of these structures for
all
 reasonable dimensions and then select the correct instance at
run
 time I suppose.
Do you need a common interface, or all of the algoritms will be templatized as well? In other words, what is the type that the following function returns? ??? selectInstance(size_t N) { // return S2D or S3D? } You can have an interface that the template implements: interface SInterface { void foo(); } class S(size_t N) : SInterface { Point[N] points; void foo() { /* implementation for N */ } } Now selectInstance() returns SInterface: SInterface selectInstance(size_t N) { // ... }
 However, I don't really want to set a limit on
 the point dimension.
All of the instances must be known at compile time. So, your program is always limited with the number of actual instances that the program is using. Ali
Ali thanks. The algorithms will be templatized as well. As you point out, I need to know all instances at compile time, but want to 'get around' this, thus my idea of compiling the specific instance I need. Adam's idea should work. I like the interface idea, but just to make sure I understand the purpose - you use the interface to provide a common interface so that the instantiated objects can be used by algorithms which do not have any knowledge of the particular dimension of a given point. Is that correct? Craig
Oct 30 2013
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/30/2013 01:41 PM, Craig Dillabaugh wrote:

 you use the interface to provide a common interface so
 that the instantiated objects can be used by algorithms which do
 not have any knowledge of the particular dimension of a given
 point.  Is that correct?
Yes, classic run-time vs. compile-time polymorphism. Apparently, you need the latter. :) Ali
Oct 30 2013