www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Nameless Static Array

reply "Taylor Hillegeist" <taylorh140 gmail.com> writes:
So, Lately I have been avoiding the NEW keyword. I have recently 
given up static allocation of classes using CTFE. I guess they 
must be const or immutable?  So naturally i can do most of what i 
need to with structs. They are statically allocated no NEW 
necessary. But without the NEW strategy. I must allocate static 
arrays and set them to a pointer in my struct. Not too big of 
deal really.

	uint[12] Buffer;
	R_R_Buffer RRB=R_R_Buffer(Buffer);
	
	uint[24] OtherBuffer;
	R_R_Buffer RRB2 = R_R_Buffer(OtherBuffer);

I feel though i might end up having OtherOtherOtherBuffers, and 
it pollutes my local symbols. I just dont like it.

Is there a way to not give the buffer a name and do lika dis:

	R_R_Buffer RRB=R_R_Buffer(uint[12]);
	R_R_Buffer RRB2 = R_R_Buffer(uint[24]);

This obviously fails to compile, but i think you get the idea. 
Mostly, I don't care what the static array name is.
Jun 12 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 12 June 2014 at 15:58:25 UTC, Taylor Hillegeist 
wrote:
 But without the NEW strategy. I must allocate static arrays and 
 set them to a pointer in my struct. Not too big of deal really.
Have you considered just making the buffer a struct member?
Jun 12 2014
parent reply "Taylor Hillegeist" <taylorh140 gmail.com> writes:
On Thursday, 12 June 2014 at 16:02:18 UTC, Adam D. Ruppe wrote:
 On Thursday, 12 June 2014 at 15:58:25 UTC, Taylor Hillegeist 
 wrote:
 But without the NEW strategy. I must allocate static arrays 
 and set them to a pointer in my struct. Not too big of deal 
 really.
Have you considered just making the buffer a struct member?
I have indeed! I am considering having different sized arrays for the buffer. I just figured that meant having different structs with various sizes.
Jun 12 2014
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 12 June 2014 at 16:08:49 UTC, Taylor Hillegeist 
wrote:
 I am considering having different sized arrays for the buffer. 
 I just figured that meant having different structs with various 
 sizes.
You might be able to do it with a templated struct and alias this. Check this out: struct R_Buffer { int[] buffer; } struct R_Buffer_Sized(size_t bufferSize) { int[bufferSize] buffer; R_Buffer getGenericBuffer() { return R_Buffer(buffer[]); } alias getGenericBuffer this; } usage: R_Buffer_Sized!48 buffer; then you can pass buffer to any function expecting a regular R_Buffer and it will just work. Be careful not to store the buffer though, since it is stack allocated, escaping a reference to it will lead to crashes. That's also the reason why something like this is a bit problematic: R_R_Buffer RRB=R_R_Buffer(uint[12]); What's the lifetime of the uint[12]? It is in the scope of the function call only, so if this were allowed, the compiler might consider it a temporary... and then you'd escape a reference to it and get corrupted data. Putting the buffer up top as a separate variable at least gives it a clear lifetime scope.
Jun 12 2014
prev sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 12 June 2014 at 15:58:25 UTC, Taylor Hillegeist 
wrote:
 So, Lately I have been avoiding the NEW keyword.
Why? Is malloc OK?
 I have recently given up static allocation of classes using 
 CTFE. I guess they must be const or immutable?
Funny, because you *are* allowed to default initialized a class member variable to a static class instance. And basically, it's just a thread local global. So you can "work around" with: //---- class MyClass { int i = 5; } void main() { static struct S { MyClass g = new MyClass(); } static S s; writeln(s.g.i); } //---- Disclaimer: Not sure if actually legal, or will cease to work in a few releases.
 So naturally i can do most of what i need to with structs. They 
 are statically allocated no NEW necessary. But without the NEW 
 strategy. I must allocate static arrays and set them to a 
 pointer in my struct. Not too big of deal really.

 	uint[12] Buffer;
 	R_R_Buffer RRB=R_R_Buffer(Buffer);
 	
 	uint[24] OtherBuffer;
 	R_R_Buffer RRB2 = R_R_Buffer(OtherBuffer);

 I feel though i might end up having OtherOtherOtherBuffers, and 
 it pollutes my local symbols. I just dont like it.

 Is there a way to not give the buffer a name and do lika dis:

 	R_R_Buffer RRB=R_R_Buffer(uint[12]);
 	R_R_Buffer RRB2 = R_R_Buffer(uint[24]);

 This obviously fails to compile, but i think you get the idea. 
 Mostly, I don't care what the static array name is.
If you have a pointer, then at the end of the day *someone* *somewhere*, is going to have to declare and hold the buffers. That said, you could simply have a *single* static array that holds all your data. Furthermore, you could package it into a single convenient struct package: struct Buffer(T, size_t N) { T[N] buffer; size_t used; T[] getBufferSlice(size_t n) { assert(used + n <= N, "You've overused your buffer!"); auto low = used; used += n; return buffer[low .. used]; } ref T[n] getBufferSlice(size_t n)() { return *cast(T[n]*) getBufferSlice(n).ptr; } } void main() { Buffer!(int, 36) myData; int[] a = myData.getBufferSlice(12); int[24]* p = &myData.getBufferSlice!24(); } Notice that with this approach, you can extract a dynamic slice referencing stack data, if you don't know the size you want. If you statically know the size you want, then you can call your function template style, and have a more strongly typed return value, that can be passed by ref.
Jun 12 2014