## digitalmars.D.learn - casting int[] to bool[]

• Saaa (12/12) Jan 28 2009 int[] a = [1,2,3,0];
• Bill Baxter (9/21) Jan 28 2009 bool is 1 byte under the hood. Int is 4 bytes.
• Jarrett Billingsley (2/26) Jan 28 2009 Stop beating me to things when I'm in the middle of typing!
• Bill Baxter (4/33) Jan 28 2009 Heh heh. I sensed this one was gonna be a race. :-P
• Saaa (24/24) Jan 28 2009 :D
• Bill Baxter (3/5) Jan 28 2009 Jarrett? You want to comment first? :-D
• Saaa (2/2) Jan 28 2009 Erm, anybody is fine to me..
• Bill Baxter (8/11) Jan 28 2009 It's just that casting is a very blunt tool and should be avoided
• Saaa (3/10) Jan 28 2009 Ok.
• Saaa (3/3) Jan 29 2009 Most of the std.math functions take reals and when I have a float or a
• Jarrett Billingsley (3/6) Jan 29 2009 You don't have to cast anything actually. floats and doubles are
• Saaa (9/9) Jan 29 2009 But then I get stuff like this:
• Daniel Keep (3/14) Jan 29 2009 -- Daniel
• Saaa (1/4) Jan 29 2009
• Jarrett Billingsley (6/7) Jan 29 2009 That's more an issue with D's extremely (overly?) strict overload
• Steven Schveighoffer (12/19) Jan 29 2009 This is such a common "mistake", and really more of an annoyance, I wond...
• Bill Baxter (5/24) Jan 29 2009 You may count me among the annoyed. I never use 'real' for anything,
• Jarrett Billingsley (4/14) Jan 29 2009 That's probably how it'd be written in modern D. Most of std.math is
• Don (12/37) Jan 30 2009 The underlying problem is the implicit conversions. A problem with sin()...
• Steven Schveighoffer (5/22) Jan 30 2009 http://d.puremagic.com/issues/show_bug.cgi?id=2636
• Don (4/31) Jan 30 2009 Of course. The Tango, phobos1, and phobos2 math files are a copy & paste...
• Jarrett Billingsley (2/8) Jan 28 2009 Blunt? Pfah! cast(bool)int is well-defined. ;)
• Bill Baxter (6/18) Jan 28 2009 Just you're more likely to catch an error if t changes from being an
• Jarrett Billingsley (2/6) Jan 28 2009 Ofine. He could use to!(bool) then.
• Saaa (15/16) Jan 29 2009 erm...
• Jarrett Billingsley (2/18) Jan 29 2009 Well that's stupid. Tango's to!() handles that case. Phobos needs to c...
• Saaa (4/6) Jan 29 2009 Well casting it is then for me, for now.
• Jarrett Billingsley (17/21) Jan 29 2009 It's probably due to the absurd amount of memory allocation you're
• Saaa (13/29) Jan 29 2009 Yay massive speedup!! (~2 sec for the loop)
• Saaa (2/2) Jan 29 2009 By manually I mean something between me typing all 60 off them and letti...
• Jarrett Billingsley (23/29) Jan 29 2009 No, just shorter to type. They compile down to pretty much the same
• Saaa (8/26) Jan 29 2009 This will take some time to understand.
• Daniel Keep (11/32) Jan 29 2009 Tuples are like arrays that have a fixed length, where each element can
• Saaa (1/20) Jan 29 2009
• Brad Roberts (8/27) Jan 28 2009 Oh, hey, that reminds me..
• Jarrett Billingsley (7/22) Jan 28 2009 Sorry, can't help but post this:
• Saaa (2/8) Jan 28 2009 Waa!
• Jarrett Billingsley (2/13) Jan 28 2009 MiniD !is D. There are no templates; toInt and toBool are just function...
• BCS (3/9) Jan 28 2009 cast is an O(1) op in all cases except opCast on UDTs. All array casts j...
• Derek Parnell (20/30) Jan 28 2009 Casting is not always the same as converting. In this case you are NOT
"Saaa" <empty needmail.com> writes:
 int[] a = [1,2,3,0];
int[] aa = [0,1,0,1];
bool[] b = cast(bool[])a.dup;
bool[] bb = cast(bool[])aa.dup;
writefln(a,-->,b);
writefln(aa,-->,bb);

--

[1 2 3 0]-->[true false false false true false false false true false false
false false false false false]
[0 1 0 1]-->[false false false false true false false false false false
false false true false false false]

Why all this disagreeing?

Jan 28 2009
Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 10:20 AM, Saaa <empty needmail.com> wrote:
int[] a = [1,2,3,0];
int[] aa = [0,1,0,1];
bool[] b = cast(bool[])a.dup;
bool[] bb = cast(bool[])aa.dup;
writefln(a,-->,b);
writefln(aa,-->,bb);

--

[1 2 3 0]-->[true false false false true false false false true false false
false false false false false]
[0 1 0 1]-->[false false false false true false false false false false
false false true false false false]

Why all this disagreeing?

bool is 1 byte under the hood.  Int is 4 bytes.
So what you are seeing is the 4 bytes of each int being treated as 4
separate bools in an ordering determined by the endian-ness of your
platform.

Casting arrays in this way is generally not a good idea.

You need to write a function that makes a fresh bool array out of your
int array.

--bb

Jan 28 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 8:25 PM, Bill Baxter <wbaxter gmail.com> wrote:
On Thu, Jan 29, 2009 at 10:20 AM, Saaa <empty needmail.com> wrote:
int[] a = [1,2,3,0];
int[] aa = [0,1,0,1];
bool[] b = cast(bool[])a.dup;
bool[] bb = cast(bool[])aa.dup;
writefln(a,-->,b);
writefln(aa,-->,bb);

--

[1 2 3 0]-->[true false false false true false false false true false false
false false false false false]
[0 1 0 1]-->[false false false false true false false false false false
false false true false false false]

Why all this disagreeing?

bool is 1 byte under the hood.  Int is 4 bytes.
So what you are seeing is the 4 bytes of each int being treated as 4
separate bools in an ordering determined by the endian-ness of your
platform.

Casting arrays in this way is generally not a good idea.

You need to write a function that makes a fresh bool array out of your
int array.

Stop beating me to things when I'm in the middle of typing!

Jan 28 2009
Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 10:25 AM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
On Wed, Jan 28, 2009 at 8:25 PM, Bill Baxter <wbaxter gmail.com> wrote:
On Thu, Jan 29, 2009 at 10:20 AM, Saaa <empty needmail.com> wrote:
int[] a = [1,2,3,0];
int[] aa = [0,1,0,1];
bool[] b = cast(bool[])a.dup;
bool[] bb = cast(bool[])aa.dup;
writefln(a,-->,b);
writefln(aa,-->,bb);

--

[1 2 3 0]-->[true false false false true false false false true false false
false false false false false]
[0 1 0 1]-->[false false false false true false false false false false
false false true false false false]

Why all this disagreeing?

bool is 1 byte under the hood.  Int is 4 bytes.
So what you are seeing is the 4 bytes of each int being treated as 4
separate bools in an ordering determined by the endian-ness of your
platform.

Casting arrays in this way is generally not a good idea.

You need to write a function that makes a fresh bool array out of your
int array.

Stop beating me to things when I'm in the middle of typing!

Heh heh.  I sensed this one was gonna be a race.  :-P

--bb

Jan 28 2009
"Saaa" <empty needmail.com> writes:
:D

Casting an expression to bool means testing for 0 or !=0 for arithmetic
types, and null or !=null for pointers or references.
So a per element bool cast should be safe, right?

That makes my full code like this:

char[][] data;
data=cast(char[][])splitlines(cast(invariant
char[])read(data\parsed.dat));

bool[][] dataIn = new bool[][](data.length, 3);

for(int i; i<data.length; i++)
{
int[3] temp = to!(int[])(split(data[i][14..19].idup,,)); // 14..19 =
0,0,1
foreach(index, t; temp)
{
dataIn[i][index] = cast(bool) t;
}
}
writefln(data[0][14..19]);
writefln(dataIn[0]);

----------It writes correctly:
0,0,1
[false false true]

Yay, thanks

Jan 28 2009
Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 11:10 AM, Saaa <empty needmail.com> wrote:
:D

dataIn[i][index] = cast(bool) t;

Jarrett?  You want to comment first?  :-D

--bb

Jan 28 2009
"Saaa" <empty needmail.com> writes:
Erm, anybody is fine to me..

Is it the naming, still the casting or something else totally?

Jan 28 2009
Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 11:57 AM, Saaa <empty needmail.com> wrote:
Erm, anybody is fine to me..

Is it the naming, still the casting or something else totally?

dataIn[i][index] = cast(bool) t;

It's just that casting is a very blunt tool and should be avoided
whenever possible, because the compiler won't tell you if you're doing
something completely crazy.

Here you could use somethign like:

dataIn[i][index] = (t!=0);

--bb

Jan 28 2009
"Saaa" <empty needmail.com> writes:
Ok.
I thought that in this particular case it would be equally safe.
Casting is so easy to read.. I'll try and minimize my usage  ; )

It's just that casting is a very blunt tool and should be avoided
whenever possible, because the compiler won't tell you if you're doing
something completely crazy.

Here you could use somethign like:

dataIn[i][index] = (t!=0);

--bb


Jan 28 2009
"Saaa" <empty needmail.com> writes:
Most of the std.math functions take reals and when I have a float or a
double I always cast them to real to make it fit.
Should I instead use to! here as well?

Jan 29 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 2:35 PM, Saaa <empty needmail.com> wrote:
Most of the std.math functions take reals and when I have a float or a
double I always cast them to real to make it fit.
Should I instead use to! here as well?

You don't have to cast anything actually.  floats and doubles are
implicitly convertible to real.  This isn't Pascal.

Jan 29 2009
"Saaa" <empty needmail.com> writes:
But then I get stuff like this:

value += pow( x, 2); //x=double
--
testcase.d(374): function std.math.pow called with argument types:
(double,int)
matches both:
std.math.pow(real x, uint n)
and:
std.math.pow(real x, int n)

Jan 29 2009
Daniel Keep <daniel.keep.lists gmail.com> writes:
Saaa wrote:
But then I get stuff like this:

value += pow( x, 2); //x=double
--
testcase.d(374): function std.math.pow called with argument types:
(double,int)
matches both:
std.math.pow(real x, uint n)
and:
std.math.pow(real x, int n)

That's because '2' as a literal is both an int and a uint.  Try this:

value += pow( x, 2u );

-- Daniel

Jan 29 2009
"Saaa" <empty needmail.com> writes:
That gives the same error.. only casting x to real works :/
That's because '2' as a literal is both an int and a uint.  Try this:

value += pow( x, 2u );

-- Daniel


Jan 29 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 6:15 PM, Saaa <empty needmail.com> wrote:
That gives the same error.. only casting x to real works :/

That's more an issue with D's extremely (overly?) strict overload
resolution rules.  Functions like sin() shouldn't be an issue, since
there is only one overload with those.  But yes, as far as pow() is
concerned, I guess you do have to cast to real.  Casting is fine here,
don't bother using to!().

Jan 29 2009
"Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Jarrett Billingsley" wrote
On Thu, Jan 29, 2009 at 6:15 PM, Saaa <empty needmail.com> wrote:
That gives the same error.. only casting x to real works :/

That's more an issue with D's extremely (overly?) strict overload
resolution rules.  Functions like sin() shouldn't be an issue, since
there is only one overload with those.  But yes, as far as pow() is
concerned, I guess you do have to cast to real.  Casting is fine here,
don't bother using to!().

This is such a common "mistake", and really more of an annoyance, I wonder
if it might be better if pow were switched to a template that called the
actual pow after casting the first argument to real.  Often times, one does
not use reals as their variable type, and I seem to recall this kind of
error happens even with literals for both arguments...

Something like:

real pow(T, U)(T t, U u)
{
return _pow(cast(real)t, u);
}

-Steve

Jan 29 2009
Bill Baxter <wbaxter gmail.com> writes:
On Fri, Jan 30, 2009 at 10:46 AM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
"Jarrett Billingsley" wrote
On Thu, Jan 29, 2009 at 6:15 PM, Saaa <empty needmail.com> wrote:
That gives the same error.. only casting x to real works :/

That's more an issue with D's extremely (overly?) strict overload
resolution rules.  Functions like sin() shouldn't be an issue, since
there is only one overload with those.  But yes, as far as pow() is
concerned, I guess you do have to cast to real.  Casting is fine here,
don't bother using to!().

This is such a common "mistake", and really more of an annoyance, I wonder
if it might be better if pow were switched to a template that called the
actual pow after casting the first argument to real.  Often times, one does
not use reals as their variable type, and I seem to recall this kind of
error happens even with literals for both arguments...

Something like:

real pow(T, U)(T t, U u)
{
return _pow(cast(real)t, u);
}

You may count me among the annoyed.  I never use 'real' for anything,
so I get those errors a lot.

--bb

Jan 29 2009
"Saaa" <empty needmail.com> writes:
Good to see it isn't just me doing something stupid :)

You may count me among the annoyed.  I never use 'real' for anything,
so I get those errors a lot.

--bb


Jan 29 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 8:46 PM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
This is such a common "mistake", and really more of an annoyance, I wonder
if it might be better if pow were switched to a template that called the
actual pow after casting the first argument to real.  Often times, one does
not use reals as their variable type, and I seem to recall this kind of
error happens even with literals for both arguments...

Something like:

real pow(T, U)(T t, U u)
{
return _pow(cast(real)t, u);
}

That's probably how it'd be written in modern D.  Most of std.math is
probably 8 years old and pre-templates.

Jan 29 2009
Don <nospam nospam.com> writes:
Steven Schveighoffer wrote:
"Jarrett Billingsley" wrote
On Thu, Jan 29, 2009 at 6:15 PM, Saaa <empty needmail.com> wrote:
That gives the same error.. only casting x to real works :/

That's more an issue with D's extremely (overly?) strict overload
resolution rules.  Functions like sin() shouldn't be an issue, since
there is only one overload with those.

The underlying problem is the implicit conversions. A problem with sin()
used to exist: There was sin(creal) and sin(ireal). Then if you have
sin(float) there are so many conversion options:
float->double -> real
\        \       \
cfloat->cdouble-> creal
So once you've implemented any two of those functions, you have to
implement all of the others. It's really quite ridiculous. I got Walter
to remove the implicit conversions real->complex for that reason.

But yes, as far as pow() is
concerned, I guess you do have to cast to real.  Casting is fine here,
don't bother using to!().

This is such a common "mistake", and really more of an annoyance, I wonder
if it might be better if pow were switched to a template that called the
actual pow after casting the first argument to real.  Often times, one does
not use reals as their variable type, and I seem to recall this kind of
error happens even with literals for both arguments...

Something like:

real pow(T, U)(T t, U u)
{
return _pow(cast(real)t, u);
}

-Steve

It would be better. Please create a bugzilla report, and I'll fix it.

Jan 30 2009
"Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Don" wrote
Steven Schveighoffer wrote:
This is such a common "mistake", and really more of an annoyance, I
wonder if it might be better if pow were switched to a template that
called the actual pow after casting the first argument to real.  Often
times, one does not use reals as their variable type, and I seem to
recall this kind of error happens even with literals for both
arguments...

Something like:

real pow(T, U)(T t, U u)
{
return _pow(cast(real)t, u);
}

-Steve

It would be better. Please create a bugzilla report, and I'll fix it.

http://d.puremagic.com/issues/show_bug.cgi?id=2636

BTW, I assigned to the only Don in the list, not sure if that is you...

Please fix in Tango as well if you wouldn't mind ;)

-Steve

Jan 30 2009
Don <nospam nospam.com> writes:
Steven Schveighoffer wrote:
"Don" wrote
Steven Schveighoffer wrote:
This is such a common "mistake", and really more of an annoyance, I
wonder if it might be better if pow were switched to a template that
called the actual pow after casting the first argument to real.  Often
times, one does not use reals as their variable type, and I seem to
recall this kind of error happens even with literals for both
arguments...

Something like:

real pow(T, U)(T t, U u)
{
return _pow(cast(real)t, u);
}

-Steve

It would be better. Please create a bugzilla report, and I'll fix it.

http://d.puremagic.com/issues/show_bug.cgi?id=2636

BTW, I assigned to the only Don in the list, not sure if that is you...

Yes.

Please fix in Tango as well if you wouldn't mind ;)

Of course. The Tango, phobos1, and phobos2 math files are a copy & paste
of each other, with a few name changes.

-Steve


Jan 30 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 9:57 PM, Bill Baxter <wbaxter gmail.com> wrote:
It's just that casting is a very blunt tool and should be avoided
whenever possible, because the compiler won't tell you if you're doing
something completely crazy.

Here you could use somethign like:

dataIn[i][index] = (t!=0);

Blunt?  Pfah!  cast(bool)int is well-defined.  ;)

Jan 28 2009
Bill Baxter <wbaxter gmail.com> writes:
On Thu, Jan 29, 2009 at 12:04 PM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
On Wed, Jan 28, 2009 at 9:57 PM, Bill Baxter <wbaxter gmail.com> wrote:
It's just that casting is a very blunt tool and should be avoided
whenever possible, because the compiler won't tell you if you're doing
something completely crazy.

Here you could use somethign like:

dataIn[i][index] = (t!=0);

Blunt?  Pfah!  cast(bool)int is well-defined.  ;)

Just you're more likely to catch an error if t changes from being an
int to something else later on.
I wish D had a "tame and well-behaved casts only please" kind of cast. :-(

--bb

Jan 28 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 10:07 PM, Bill Baxter <wbaxter gmail.com> wrote:
Just you're more likely to catch an error if t changes from being an
int to something else later on.
I wish D had a "tame and well-behaved casts only please" kind of cast. :-(

--bb

Ofine.  He could use to!(bool) then.

Jan 28 2009
"Saaa" <empty needmail.com> writes:
 Ofine.  He could use to!(bool) then.

erm...

for(int i; i<data.length; i++)
{
int[60] tempIn = to!(int[])(split(data[i][22..141].idup,,));

foreach(index, t; tempIn)
{
dataIn[i][index] = to!(bool)(t);
}
}

C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(344):
Error: cannot implicitly convert expression (value) of type int to bool

C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(206):
template instance std.conv.toImpl!(int,bool) error instantiating

C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(34):
template instance std.conv.to!(bool).to!(int) error instantiating

Jan 29 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 10:56 AM, Saaa <empty needmail.com> wrote:
Ofine.  He could use to!(bool) then.

erm...

for(int i; i<data.length; i++)
{
int[60] tempIn = to!(int[])(split(data[i][22..141].idup,,));

foreach(index, t; tempIn)
{
dataIn[i][index] = to!(bool)(t);
}
}

C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(344):
Error: cannot implicitly convert expression (value) of type int to bool

C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(206):
template instance std.conv.toImpl!(int,bool) error instantiating

C:\D\dmd.2.023\dmd\src\phobos\std\conv.d(34):
template instance std.conv.to!(bool).to!(int) error instantiating

Well that's stupid.  Tango's to!() handles that case.  Phobos needs to catch up!

Jan 29 2009
"Saaa" <empty needmail.com> writes:
Well casting it is then for me, for now.

This way of reading all these booleans is a bit slow... a minute for 700_000
lines

Is there some way to speed this up?

Well that's stupid.  Tango's to!() handles that case.  Phobos needs to
catch up!


Jan 29 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 11:28 AM, Saaa <empty needmail.com> wrote:
Well casting it is then for me, for now.

This way of reading all these booleans is a bit slow... a minute for 700_000
lines

Is there some way to speed this up?

It's probably due to the absurd amount of memory allocation you're
causing.  Each call to split() allocates an array (whose size is not
known in advance, so it requires several appends), and each call to
to!(int[]) allocates _another_ array.  That's 1.4 million arrays
you're allocating, most of which are garbage, and each allocation can
potentially trigger a GC cycle.

It would be a lot more efficient if you just parsed out the line yourself.

auto data = splitlines(read(data\parsed.dat).idup);
auto dataIn = new bool[][](data.length, 3);

foreach(i, line; data)
{
dataIn[i][0] = line[14] == '1';
dataIn[i][1] = line[16] == '1';
dataIn[i][2] = line[18] == '1';
}

Now we perform only a few allocations, all of which are before the loop.

Jan 29 2009
"Saaa" <empty needmail.com> writes:
 It's probably due to the absurd amount of memory allocation you're
causing.  Each call to split() allocates an array (whose size is not
known in advance, so it requires several appends), and each call to
to!(int[]) allocates _another_ array.  That's 1.4 million arrays
you're allocating, most of which are garbage, and each allocation can
potentially trigger a GC cycle.

It would be a lot more efficient if you just parsed out the line yourself.

auto data = splitlines(read(data\parsed.dat).idup);
auto dataIn = new bool[][](data.length, 3);

foreach(i, line; data)
{
dataIn[i][0] = line[14] == '1';
dataIn[i][1] = line[16] == '1';
dataIn[i][2] = line[18] == '1';
}

Now we perform only a few allocations, all of which are before the loop.

Yay massive speedup!! (~2 sec for the loop)
Is bool = x == y faster than if ( x == y ) true else false ?

For the 60 large boolean part I used a loop.
Not that I really need the extra speedup (if any) but how could I manually
unroll that loop?
I know you can do things like that in D..

btw. side note: I love slices :D

auto sliceIn = dataIn[0..300];
auto sliceOut = dataOut[0..300];

rndGen.seed(1);
randomShuffle(sliceIn, rndGen);
rndGen.seed(1);
randomShuffle(sliceOut, rndGen);

Jan 29 2009
"Saaa" <empty needmail.com> writes:
By manually I mean something between me typing all 60 off them and letting
the compiler optimize it as such.

Jan 29 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jan 29, 2009 at 1:57 PM, Saaa <empty needmail.com> wrote:

Yay massive speedup!! (~2 sec for the loop)
Is bool = x == y faster than if ( x == y ) true else false ?

No, just shorter to type.  They compile down to pretty much the same
machine code.

For the 60 large boolean part I used a loop.
Not that I really need the extra speedup (if any) but how could I manually
unroll that loop?
I know you can do things like that in D..

Oh, so you mean you have 60 bools on each line?  You can do that with
some templating and string mixin magic:

// declare these at global scope
template Tuple(T...) { alias T Tuple; }

// Generates a tuple of numbers in the range [0, n)
template Range(int n)
{
static if(n == 0)
alias Tuple!() Range;
else
alias Tuple!(Range!(n - 1), n - 1) Range;
}

// then this is your loop in main
foreach(i, line; data)
{
// this foreach loop is run at compile time
foreach(j; Range!(60))
mixin("dataIn[i][" ~ j.stringof ~
"] = line[14 + 2 * " ~ j.stringof ~ "] == '1';");
}

Jan 29 2009
"Saaa" <empty needmail.com> writes:
This will take some time to understand.
Things I have never used before : D
.stringof(can't find this one), static if

I'll read up until I understand this.

Why is that foreach loop run at compile time?
The compiler checks for a template parameter?

// declare these at global scope
template Tuple(T...) { alias T Tuple; }

// Generates a tuple of numbers in the range [0, n)
template Range(int n)
{
static if(n == 0)
alias Tuple!() Range;
else
alias Tuple!(Range!(n - 1), n - 1) Range;
}

// then this is your loop in main
foreach(i, line; data)
{
// this foreach loop is run at compile time
foreach(j; Range!(60))
mixin("dataIn[i][" ~ j.stringof ~
"] = line[14 + 2 * " ~ j.stringof ~ "] == '1';");
}


Jan 29 2009
Daniel Keep <daniel.keep.lists gmail.com> writes:
Saaa wrote:
This will take some time to understand.
Things I have never used before : D
..stringof(can't find this one), static if

I'll read up until I understand this.

Why is that foreach loop run at compile time?
The compiler checks for a template parameter?

[snip]

Tuples are like arrays that have a fixed length, where each element can
be of absolutely any type at all.

What this means is that it potentially takes different code to access
each element of a tuple.  So when you see

foreach( i ; Range!(4) ) foo(i);

What is actually being generated is this:

foo(0);
foo(1);
foo(2);
foo(3);

It's not really doing the foreach at compile time, but it is unrolling
it.  You might think "but why doesn't this happen for arrays?"  Because
you can't do THIS with arrays:

foreach( i,x ; Tuple!(0, "b", 3.0) ) writefln("Element %s == %s",i,x);

Which expands to:

writefln("Element %s == %s",0,0);
writefln("Element %s == %s",1,"b");
writefln("Element %s == %s",2,3.0);

-- Daniel

Jan 29 2009
"Saaa" <empty needmail.com> writes:
Thanks, that makes sense!
Tuples are like arrays that have a fixed length, where each element can
be of absolutely any type at all.

What this means is that it potentially takes different code to access
each element of a tuple.  So when you see

foreach( i ; Range!(4) ) foo(i);

What is actually being generated is this:

foo(0);
foo(1);
foo(2);
foo(3);

It's not really doing the foreach at compile time, but it is unrolling
it.  You might think "but why doesn't this happen for arrays?"  Because
you can't do THIS with arrays:

foreach( i,x ; Tuple!(0, "b", 3.0) ) writefln("Element %s == %s",i,x);

Which expands to:

writefln("Element %s == %s",0,0);
writefln("Element %s == %s",1,"b");
writefln("Element %s == %s",2,3.0);

-- Daniel


Jan 29 2009
Bill Baxter wrote:
On Thu, Jan 29, 2009 at 12:04 PM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
On Wed, Jan 28, 2009 at 9:57 PM, Bill Baxter <wbaxter gmail.com> wrote:
It's just that casting is a very blunt tool and should be avoided
whenever possible, because the compiler won't tell you if you're doing
something completely crazy.

Here you could use somethign like:

dataIn[i][index] = (t!=0);

Blunt?  Pfah!  cast(bool)int is well-defined.  ;)

Just you're more likely to catch an error if t changes from being an
int to something else later on.
I wish D had a "tame and well-behaved casts only please" kind of cast. :-(

--bb

Oh, hey, that reminds me..

Walter!  When are we going to get the equivalent to const_cast?  And the
related restriction that cast can't alter constness?

I've already made the mistake at least once changing type and constness,
without meaning to do the latter, at the same time.

Thanks,

Jan 28 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 9:10 PM, Saaa <empty needmail.com> wrote:
char[][] data;
data=cast(char[][])splitlines(cast(invariant
char[])read(data\parsed.dat));

bool[][] dataIn = new bool[][](data.length, 3);

for(int i; i<data.length; i++)
{
int[3] temp = to!(int[])(split(data[i][14..19].idup,,)); // 14..19 =
0,0,1
foreach(index, t; temp)
{
dataIn[i][index] = cast(bool) t;
}
}
writefln(data[0][14..19]);
writefln(dataIn[0]);

Sorry, can't help but post this:

local data = io.readFile("data/parsed.dat").splitLines().apply$\line -> line[14 .. 19].split(",").apply$
\item -> toBool$toInt$ item

writeln$data[0] It's a one-liner (one-..statementer) in MiniD! <_<  Jan 28 2009 "Saaa" <empty needmail.com> writes:  Sorry, can't help but post this: local data = io.readFile("data/parsed.dat").splitLines().apply$
\line -> line[14 .. 19].split(",").apply$\item -> toBool$ toInt$item writeln$ data[0]

It's a one-liner (one-..statementer) in MiniD!  <_<

Waa!

Can't toInt be skipped when you use the to! template?

Jan 28 2009
Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Jan 28, 2009 at 10:37 PM, Saaa <empty needmail.com> wrote:
Sorry, can't help but post this:

local data = io.readFile("data/parsed.dat").splitLines().apply$\line -> line[14 .. 19].split(",").apply$
\item -> toBool$toInt$ item

writeln\$ data[0]

It's a one-liner (one-..statementer) in MiniD!  <_<

Waa!

Can't toInt be skipped when you use the to! template?

MiniD !is D.  There are no templates; toInt and toBool are just functions.

Jan 28 2009
BCS <none anon.com> writes:
Hello Saaa,

:D

Casting an expression to bool means testing for 0 or !=0 for
arithmetic
types, and null or !=null for pointers or references.
So a per element bool cast should be safe, right?

cast is an O(1) op in all cases except opCast on UDTs. All array casts just
paint an array of the old type over the new.

Jan 28 2009
Derek Parnell <derek psych.ward> writes:
On Thu, 29 Jan 2009 02:20:08 +0100, Saaa wrote:

int[] a = [1,2,3,0];
int[] aa = [0,1,0,1];
bool[] b = cast(bool[])a.dup;
bool[] bb = cast(bool[])aa.dup;
writefln(a,-->,b);
writefln(aa,-->,bb);

Casting is not always the same as converting. In this case you are NOT
converting an array of ints to an array of bools, instead you are telling
the compiler to pretend that the array of ints is really an array of bools.

[1 2 3 0]-->[true false false false true false false false true false
false false false false false false]
[0 1 0 1]-->[false false false false true false false false false
false false false true false false false]

In each case you have sixteen bools because each of the four ints uses four
bytes and is thus is sixteen bytes long. Each byte is interpreted by
writefln() as a bool value.

If you need to use 'ints' as bool values you have to provide your own
conversion routine. For example ...

int[] a = [1,2,3,0];
bool[] b;
-- Convert to int array to bool array.
b.length = a.length;
foreach( i, x; a)
b[i] = (x != 0);

writefln(a,-->,b);

--
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell

Jan 28 2009