www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Tango BitArray Initialization

reply Colin Huang <colin.hwong gmail.com> writes:
When reading the Tango documentation, I came across this piece of code:

import tango.core.BitArray;

void main()
{
    BitArray bitbag1 = bits( 1,0,1,1,1,0 );
    // or
    BitArray bitbag2( 1,0,1,1,1,0 );
}

The documentation says that "bitbag2 is initialized such that it uses a special
opCall overload for the BitArray".

Now the problem is that when I look at the source code, I don't see any
overload of opCall for BitArray, or any definition for the bits function. Am I
missing anything here?

BTW, is the last line legal D code at all? It doesn't look like it's gonna
compile (to me, at least).
Feb 10 2007
next sibling parent Sean Kelly <sean f4.ca> writes:
Colin Huang wrote:
 When reading the Tango documentation, I came across this piece of code:
 
 import tango.core.BitArray;
 
 void main()
 {
     BitArray bitbag1 = bits( 1,0,1,1,1,0 );
     // or
     BitArray bitbag2( 1,0,1,1,1,0 );
 }
 
 The documentation says that "bitbag2 is initialized such that it uses a special
 opCall overload for the BitArray".
 
 Now the problem is that when I look at the source code, I don't see any
overload
 of opCall for BitArray, or any definition for the bits function. Am I
 missing anything here?

Nope. The documentation for tango.core was the first to be written an as a result it may be a bit inaccurate in places. It would be easy to provide such a function however... something like this: BitArray bits( bool[] mask ... ) { BitArray temp; temp.length = mask.length; foreach( pos, val; mask ) temp[pos] = val; return temp; } It may be even better to simply make this a ctor for BitArray, so: auto b = BitArray( 1, 0, 1, 0 );
 BTW, is the last line legal D code at all? It doesn't look like it's gonna
 compile (to me, at least).

The last line doesn't seem correct. I'll give the docs a look tomorrow. Sean
Feb 11 2007
prev sibling parent reply John Reimer <terminal.node gmail.com> writes:
On Sat, 10 Feb 2007 09:10:07 -0500, Colin Huang wrote:

 When reading the Tango documentation, I came across this piece of code:
 
 import tango.core.BitArray;
 
 void main()
 {
     BitArray bitbag1 = bits( 1,0,1,1,1,0 );
     // or
     BitArray bitbag2( 1,0,1,1,1,0 );
 }
 
 The documentation says that "bitbag2 is initialized such that it uses a
special opCall overload for the BitArray".
 
 Now the problem is that when I look at the source code, I don't see any
overload of opCall for BitArray, or any definition for the bits function. Am I
missing anything here?
 
 BTW, is the last line legal D code at all? It doesn't look like it's gonna
compile (to me, at least).

The Doc is innacurrate in this respect on both counts. The "bits" function and "opCall" do not exist. When I wrote it, I was hoping that Tango would implement a "simple" way to initialize the BitArray. There were a number of options at the time, but nothing happened in this case because there were greater priorities. The examples above were intended to be suggestions for easier initialization syntax. What bothered me at the time was that there was no simple single line initialization of the BitArray... it involved two or more steps and more lines of code: creation of the bitarray and then initialization. What I was looking for was a simple one line declaration/initialization solution. (The last line could be legal if an opCall were implemented.) We'll get the doc fixed for now and explore the possibilities a little more. -JJR
Feb 11 2007
next sibling parent reply Colin Huang <colin.hwong gmail.com> writes:
John Reimer Wrote:

 (The last line could be legal if an opCall were implemented.)

Even if an opCall overload were in place, I doubt that the last line would compile. It certainly didn't last time I tried (I'm using gdc 0.22 on Windows). I may be wrong on this, of course. In fact, I've been wanting to be able to do that for quite some time now, so I can use structs like stack-allocated objects in C++ (syntax-wise, at least). If it actually works, pls give some examples. thx Colin
Feb 11 2007
parent reply Sean Kelly <sean f4.ca> writes:
Colin Huang wrote:
 John Reimer Wrote:
 
 (The last line could be legal if an opCall were implemented.)

Even if an opCall overload were in place, I doubt that the last line would compile. It certainly didn't last time I tried (I'm using gdc 0.22 on

 I may be wrong on this, of course.
 
 In fact, I've been wanting to be able to do that for quite some time now, so I
 can use structs like stack-allocated objects in C++ (syntax-wise, at
 least).   If it actually works, pls give some examples. thx

I don't think this is legal in D. In fact, the syntax is a huge problem in C++ because the parser often can't distinguish between a variable decl and a function prototype, and function prototypes take precedence. It may be uglier, but: BitArray b = BitArray( 1, 0, 1 ); is better than: BitArray b( 1, 0, 1 ); I only wish that the syntax worked for all stack variables. ie. int x = int( 1 ); Sean
Feb 11 2007
next sibling parent reply Colin Huang <colin.hwong gmail.com> writes:
Sean Kelly Wrote:

 I don't think this is legal in D.  In fact, the syntax is a huge problem 
 in C++ because the parser often can't distinguish between a variable 
 decl and a function prototype, and function prototypes take precedence. 

Yeah, that got me really confused when I first started learning C++
   It may be uglier, but:
 
      BitArray b = BitArray( 1, 0, 1 );
 
 is better than:
 
      BitArray b( 1, 0, 1 );
 
 I only wish that the syntax worked for all stack variables.  ie.
 
      int x = int( 1 );

Why is this useful? Isn't "int x = 1" enough?
Feb 11 2007
parent reply Sean Kelly <sean f4.ca> writes:
Colin Huang wrote:
 Sean Kelly Wrote:
 
 I don't think this is legal in D.  In fact, the syntax is a huge problem 
 in C++ because the parser often can't distinguish between a variable 
 decl and a function prototype, and function prototypes take precedence. 

Yeah, that got me really confused when I first started learning C++
   It may be uglier, but:

      BitArray b = BitArray( 1, 0, 1 );

 is better than:

      BitArray b( 1, 0, 1 );

 I only wish that the syntax worked for all stack variables.  ie.

      int x = int( 1 );

Why is this useful? Isn't "int x = 1" enough?

Templates. It still isn't perfect because classes can't be initialized this way, but: void buildAndCall(T, Call, Params...)( Call fn, Params p ) { T val = T( p ); fn( val ); } Probably a bad example, but you get the idea. It's nice to be able to initialize everything using the same syntax. I'd almost suggest: scope T val = new T( p ); as the "universal" scoped declaration syntax, but the presence of the 'new' is not terribly ideal, even though it should work for classes as well. Sean
Feb 11 2007
parent Colin Huang <colin.hwong gmail.com> writes:
Sean Kelly Wrote:

 Colin Huang wrote:
 Sean Kelly Wrote:
 
 I don't think this is legal in D.  In fact, the syntax is a huge problem 
 in C++ because the parser often can't distinguish between a variable 
 decl and a function prototype, and function prototypes take precedence. 

Yeah, that got me really confused when I first started learning C++
   It may be uglier, but:

      BitArray b = BitArray( 1, 0, 1 );

 is better than:

      BitArray b( 1, 0, 1 );

 I only wish that the syntax worked for all stack variables.  ie.

      int x = int( 1 );

Why is this useful? Isn't "int x = 1" enough?

Templates. It still isn't perfect because classes can't be initialized this way, but: void buildAndCall(T, Call, Params...)( Call fn, Params p ) { T val = T( p ); fn( val ); } Probably a bad example, but you get the idea. It's nice to be able to initialize everything using the same syntax. I'd almost suggest: scope T val = new T( p ); as the "universal" scoped declaration syntax, but the presence of the 'new' is not terribly ideal, even though it should work for classes as well.

Ah, that makes sense. Should've thought of it :) Colin
Feb 12 2007
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
John Reimer wrote:
 On Sun, 11 Feb 2007 19:41:48 -0800, Sean Kelly wrote:
 

 Another simple alternative could employ a static opAssign.
 
 This would make things much simpler:
 
 BitArray bitbag = 0b11111000000;
 
 The value is limited to 64-bits, but at least it's clean and simple for
 those situations where we don't have a long initialization value.
 (this would work for hexidecimal value also).  For any larger values we
 can use an array literal assignment or something similar.
 

Does opAssign work that way? I think it has to be done in two lines: BitArray bitbag; bitbag = 0b11111000000; Yes that does seem to be the case. Otherwise you get, bizarrely, the error "no property 'opCall' for type 'Foo'". --bb
Feb 11 2007
parent reply Sean Kelly <sean f4.ca> writes:
Bill Baxter wrote:
 John Reimer wrote:
 On Sun, 11 Feb 2007 19:41:48 -0800, Sean Kelly wrote:

 Another simple alternative could employ a static opAssign.

 This would make things much simpler:

 BitArray bitbag = 0b11111000000;

 The value is limited to 64-bits, but at least it's clean and simple for
 those situations where we don't have a long initialization value.
 (this would work for hexidecimal value also).  For any larger values we
 can use an array literal assignment or something similar.

Does opAssign work that way? I think it has to be done in two lines: BitArray bitbag; bitbag = 0b11111000000; Yes that does seem to be the case. Otherwise you get, bizarrely, the error "no property 'opCall' for type 'Foo'".

Oddly, if you make the opCall static, it works. Sean
Feb 12 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Sean Kelly wrote:
 Bill Baxter wrote:
 John Reimer wrote:
 On Sun, 11 Feb 2007 19:41:48 -0800, Sean Kelly wrote:

 Another simple alternative could employ a static opAssign.

 This would make things much simpler:

 BitArray bitbag = 0b11111000000;

 The value is limited to 64-bits, but at least it's clean and simple for
 those situations where we don't have a long initialization value.
 (this would work for hexidecimal value also).  For any larger values we
 can use an array literal assignment or something similar.

Does opAssign work that way? I think it has to be done in two lines: BitArray bitbag; bitbag = 0b11111000000; Yes that does seem to be the case. Otherwise you get, bizarrely, the error "no property 'opCall' for type 'Foo'".

Oddly, if you make the opCall static, it works. Sean

Hmm. Show me how. This and several variations of this that I tried do not work: import std.stdio; struct Struct { static void opAssign(int i) { val = i; } int val = 0; } void main() { Struct s = 2; writefln("S.val=%s", s.val); } --bb
Feb 12 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Bill Baxter wrote:
 Sean Kelly wrote:
 Bill Baxter wrote:
 John Reimer wrote:
 On Sun, 11 Feb 2007 19:41:48 -0800, Sean Kelly wrote:

 Another simple alternative could employ a static opAssign.

 This would make things much simpler:

 BitArray bitbag = 0b11111000000;

 The value is limited to 64-bits, but at least it's clean and simple for
 those situations where we don't have a long initialization value.
 (this would work for hexidecimal value also).  For any larger values we
 can use an array literal assignment or something similar.

Does opAssign work that way? I think it has to be done in two lines: BitArray bitbag; bitbag = 0b11111000000; Yes that does seem to be the case. Otherwise you get, bizarrely, the error "no property 'opCall' for type 'Foo'".

Oddly, if you make the opCall static, it works. Sean

Hmm. Show me how. This and several variations of this that I tried do not work: import std.stdio; struct Struct { static void opAssign(int i) { val = i; } int val = 0; } void main() { Struct s = 2; writefln("S.val=%s", s.val); }

Oh, wait. "if you make the *opCall* static". Weird. This does work: import std.stdio; struct Struct { static Struct opCall(int i) { Struct s; s.val = i; return s; } void opAssign(int i) { val = i; } int val = 0; } void main() { Struct s = 2; writefln("S.val=%s", s.val); } Neat! --bb
Feb 12 2007
parent reply kris <foo bar.com> writes:
Bill Baxter wrote:
 Bill Baxter wrote:
 
 Sean Kelly wrote:

 Bill Baxter wrote:

 John Reimer wrote:

 On Sun, 11 Feb 2007 19:41:48 -0800, Sean Kelly wrote:

 Another simple alternative could employ a static opAssign.

 This would make things much simpler:

 BitArray bitbag = 0b11111000000;

 The value is limited to 64-bits, but at least it's clean and simple 
 for
 those situations where we don't have a long initialization value.
 (this would work for hexidecimal value also).  For any larger 
 values we
 can use an array literal assignment or something similar.

Does opAssign work that way? I think it has to be done in two lines: BitArray bitbag; bitbag = 0b11111000000; Yes that does seem to be the case. Otherwise you get, bizarrely, the error "no property 'opCall' for type 'Foo'".

Oddly, if you make the opCall static, it works. Sean

Hmm. Show me how. This and several variations of this that I tried do not work: import std.stdio; struct Struct { static void opAssign(int i) { val = i; } int val = 0; } void main() { Struct s = 2; writefln("S.val=%s", s.val); }

Oh, wait. "if you make the *opCall* static". Weird. This does work: import std.stdio; struct Struct { static Struct opCall(int i) { Struct s; s.val = i; return s; } void opAssign(int i) { val = i; } int val = 0; } void main() { Struct s = 2; writefln("S.val=%s", s.val); } Neat! --bb

No opCall needed. Just return the struct from the static opAssign() instead
Feb 12 2007
parent reply Sean Kelly <sean f4.ca> writes:
kris wrote:
 Bill Baxter wrote:
 Bill Baxter wrote:

 Sean Kelly wrote:

 Bill Baxter wrote:

 John Reimer wrote:

 On Sun, 11 Feb 2007 19:41:48 -0800, Sean Kelly wrote:

 Another simple alternative could employ a static opAssign.

 This would make things much simpler:

 BitArray bitbag = 0b11111000000;

 The value is limited to 64-bits, but at least it's clean and 
 simple for
 those situations where we don't have a long initialization value.
 (this would work for hexidecimal value also).  For any larger 
 values we
 can use an array literal assignment or something similar.

Does opAssign work that way? I think it has to be done in two lines: BitArray bitbag; bitbag = 0b11111000000; Yes that does seem to be the case. Otherwise you get, bizarrely, the error "no property 'opCall' for type 'Foo'".

Oddly, if you make the opCall static, it works. Sean

Hmm. Show me how. This and several variations of this that I tried do not work: import std.stdio; struct Struct { static void opAssign(int i) { val = i; } int val = 0; } void main() { Struct s = 2; writefln("S.val=%s", s.val); }

Oh, wait. "if you make the *opCall* static". Weird. This does work: import std.stdio; struct Struct { static Struct opCall(int i) { Struct s; s.val = i; return s; } void opAssign(int i) { val = i; } int val = 0; } void main() { Struct s = 2; writefln("S.val=%s", s.val); } Neat! --bb

No opCall needed. Just return the struct from the static opAssign() instead

Oddly, I wasn't able to get static opAssign to work with this syntax. It seemed to want "BitArray = 0" rather than "BitArray b = 0". I've modified Tango's BitArray to support: BitArray b = [0,1,0,1]; b = [1,0,1,0]; which is consistent with how built-in arrays work. Sean
Feb 13 2007
parent reply Colin Huang <colin.hwong gmail.com> writes:
Sean Kelly Wrote:

 Oddly, I wasn't able to get static opAssign to work with this syntax. 
 It seemed to want "BitArray = 0" rather than "BitArray b = 0".  I've 
 modified Tango's BitArray to support:
 
      BitArray b = [0,1,0,1];
      b = [1,0,1,0];
 
 which is consistent with how built-in arrays work.
 
 
 Sean

Good work :) Colin
Feb 13 2007
parent reply Sean Kelly <sean f4.ca> writes:
Colin Huang wrote:
 Sean Kelly Wrote:
 
 Oddly, I wasn't able to get static opAssign to work with this syntax. 
 It seemed to want "BitArray = 0" rather than "BitArray b = 0".  I've 
 modified Tango's BitArray to support:

      BitArray b = [0,1,0,1];
      b = [1,0,1,0];

 which is consistent with how built-in arrays work.


 Sean

Good work :)

By the way, I think the above will break when implicit type conversions are added, because [0,1,0,1] is currently passed as a bool[]. I'll need to think about this a bit more, since [true,false,true,false] kind of stinks, as does accepting an array of ubyte or some such. This is an issue Walter will have to face as well since Phobos BitArray will have the same problem. Sean
Feb 13 2007
parent reply Thomas Brix Larsen <brix brix-verden.dk> writes:
Sean Kelly wrote:

 Colin Huang wrote:
 Sean Kelly Wrote:
 
 Oddly, I wasn't able to get static opAssign to work with this syntax.
 It seemed to want "BitArray = 0" rather than "BitArray b = 0".  I've
 modified Tango's BitArray to support:

      BitArray b = [0,1,0,1];
      b = [1,0,1,0];

 which is consistent with how built-in arrays work.


 Sean

Good work :)

By the way, I think the above will break when implicit type conversions are added, because [0,1,0,1] is currently passed as a bool[]. I'll need to think about this a bit more, since [true,false,true,false] kind of stinks, as does accepting an array of ubyte or some such. This is an issue Walter will have to face as well since Phobos BitArray will have the same problem. Sean

Can't you just make it a ubyte array, and throw an error if it isn't filled with ones and zeros? Something like: if(... throw new Error("Stupid human! Bits are made up of ones and zeros!!"); - Brix ps. ;)
Feb 13 2007
parent Sean Kelly <sean f4.ca> writes:
Thomas Brix Larsen wrote:
 Sean Kelly wrote:
 
 Colin Huang wrote:
 Sean Kelly Wrote:

 Oddly, I wasn't able to get static opAssign to work with this syntax.
 It seemed to want "BitArray = 0" rather than "BitArray b = 0".  I've
 modified Tango's BitArray to support:

      BitArray b = [0,1,0,1];
      b = [1,0,1,0];

 which is consistent with how built-in arrays work.


 Sean


are added, because [0,1,0,1] is currently passed as a bool[]. I'll need to think about this a bit more, since [true,false,true,false] kind of stinks, as does accepting an array of ubyte or some such. This is an issue Walter will have to face as well since Phobos BitArray will have the same problem. Sean

Can't you just make it a ubyte array, and throw an error if it isn't filled with ones and zeros? Something like: if(... throw new Error("Stupid human! Bits are made up of ones and zeros!!");

Yup, and this is what will probably happen. Sean
Feb 13 2007
prev sibling parent John Reimer <terminal.node gmail.com> writes:
On Sun, 11 Feb 2007 19:41:48 -0800, Sean Kelly wrote:

 Colin Huang wrote:
 John Reimer Wrote:
 
 (The last line could be legal if an opCall were implemented.)

Even if an opCall overload were in place, I doubt that the last line would

Windows).
 I may be wrong on this, of course.
 
 In fact, I've been wanting to be able to do that for quite some time now, so I

 least).   If it actually works, pls give some examples. thx

I don't think this is legal in D. In fact, the syntax is a huge problem in C++ because the parser often can't distinguish between a variable decl and a function prototype, and function prototypes take precedence. It may be uglier, but: BitArray b = BitArray( 1, 0, 1 ); is better than: BitArray b( 1, 0, 1 ); I only wish that the syntax worked for all stack variables. ie. int x = int( 1 ); Sean

Apparently I missed the issue completely, Sorry. I'm not sure how or why I came up with the notation in the first place. What I'm actually interested in seeing is a simple solution here for assignment of a binary type. Another simple alternative could employ a static opAssign. This would make things much simpler: BitArray bitbag = 0b11111000000; The value is limited to 64-bits, but at least it's clean and simple for those situations where we don't have a long initialization value. (this would work for hexidecimal value also). For any larger values we can use an array literal assignment or something similar. -JJR
Feb 11 2007