On Thursday, 13 August 2015 at 19:13:55 UTC, D_Learner wrote:
I was wondering how I could change the code below such the
`bmBc` is computed at compile time . The one below works for
runtime but it is not ideal since I need to know the `bmBc`
table at compile-time . I could appreciate advice on how I
could improve on this.
import std.conv:to;
import std.stdio;
int [string] bmBc;
immutable string pattern = "GCAGAGAG";
const int size = to!int(pattern.length);
struct king {
void calculatebmBc(int i)()
{
static if ( i < size -1 )
bmBc[to!string(pattern[i])]=to!int(size-i-1);
// bmBc[pattern[i]] ~= i-1;
calculatebmBc!(i+1)();
}
void calculatebmBc(int i: size-1)() {
}
}
void main(){
king myKing;
const int start = 0;
myKing.calculatebmBc!(start)();
//1. enum bmBcTable = bmBc;
}
I think you may have some fundamental misunderstandings regarding
CTFE, templates, etc. Your code seems to be half-way between a
template-based and a CTFE-based solution.
The simple way to do compile-time computation in D is CTFE
(Compile Time Function Evaluation). That is, you write a pure
function that can be evaluated both at run-time and at
compile-time. CTFE doesn't need template parameters.
Here's some code that should do the same as yours and is
compatible with CTFE:
----
import std.conv: to;
import std.stdio;
int[char] calculatebmBc(string pattern) pure
{
const int size = to!int(pattern.length);
int[char] result;
foreach(i; 0 .. size - 1)
{
result[pattern[i]] = to!int(size - i - 1);
}
return result;
}
void main()
{
auto bmBc = calculatebmBc("GCAGAGAG");
enum bmBcTable = calculatebmBc("GCAGAGAG");
}
----
The key is that calculatebmBc is pure, i.e. it doesn't read or
write any module-level mutables.
I touched some things here and here I didn't like that are not
related to purity/CTFE.
Adam D. Ruppe already mentioned an issue with associative arrays:
This doesn't work:
----
static foo = calculatebmBc("GCAGAGAG");
----
It's annoying, but if you need that you have to use some other
data structure. See Adam's post.