digitalmars.D.learn - Using the Variant (Setting it's memory location)
- "Era Scarecrow" <rtcvb32 yahoo.com> Feb 05 2012
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> Feb 05 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Feb 06 2012
- "Jesse Phillips" <jessekphillips+D gmail.com> Feb 06 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Feb 06 2012
- "Jesse Phillips" <jessekphillips+D gmail.com> Feb 07 2012
- Pedro Lacerda <pslacerda gmail.com> Feb 07 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Feb 08 2012
- Pedro Lacerda <pslacerda gmail.com> Feb 08 2012
I've been working and building a struct called 'AllTypes' which I've come to the conclusion is already available as a variant. However as I look at the documentation I don't see any methods/constructors to use where I can specify where I want the data to be access from. The data I will be accessing has dozens of different structures of records which I keep the formatting and types saved in an array. I see the problem where although variant can handle what I need, but I don't see a way to specify a specific memory range/access in order to use it. ubyte[] buffer; //buffer is loaded at some point with data so length > 0; buffer.length = 2; //0 is the offset from the buffer rather than making a range. Variant v(buffer, int8, 0); v = 10; assert(buffer[0] == 10); v = Variant(buffer, int8, 1); v = 25; assert(buffer[0] == 10); assert(buffer[1] == 25);
Feb 05 2012
On 02/05/2012 12:20 PM, Era Scarecrow wrote:I've been working and building a struct called 'AllTypes' which I've come to the conclusion is already available as a variant. However as I look at the documentation I don't see any methods/constructors to use where I can specify where I want the data to be access from. The data I will be accessing has dozens of different structures of records which I keep the formatting and types saved in an array. I see the problem where although variant can handle what I need, but I don't see a way to specify a specific memory range/access in order to use it. ubyte[] buffer; //buffer is loaded at some point with data so length > 0; buffer.length = 2; //0 is the offset from the buffer rather than making a range. Variant v(buffer, int8, 0); v = 10; assert(buffer[0] == 10); v = Variant(buffer, int8, 1); v = 25; assert(buffer[0] == 10); assert(buffer[1] == 25);
I see that it's not exactly what you are looking for, but have you looked at std.conv.emplace()? Ali
Feb 05 2012
I see that it's not exactly what you are looking for, but have you looked at std.conv.emplace()?
I've glanced it over, and I don't understand it, but it also doesn't quite seem right. I know sometimes I'll know what the type and size is, but most of the time only my array of data will tell me. I can likely handle it all in the type I was making, or a switch case. I was just hoping to avoid that if I could. the structure of the data can sometimes be something like (int, int, int, float, float, float, char[1], char[3], char[32]). Wow... serious case of Déjà vu...
Feb 06 2012
On Sunday, 5 February 2012 at 20:20:58 UTC, Era Scarecrow wrote:The data I will be accessing has dozens of different structures of records which I keep the formatting and types saved in an array. I see the problem where although variant can handle what I need, but I don't see a way to specify a specific memory range/access in order to use it.
Variant allows you to store any value, but it does not need a buffer or have interaction like an array. It can hold any value because it the size of the data structure is the max size of the times it can hold. For this reason it can not actually hold any structure. For an array of any values you use a Variant[] foo = new Variant[100]. foo[0] = myInt; foo[1] = myFloat; However depending on the length of char[static size], you may need to give Variant a larger maximum size. VariantN!(mySize)[]... You can also use the Algebraic type to specified allowed types: Algebraic!(int,float,char[3],char[100]...)[]... This will calculate the max size you need and only allow those times to be assigned. Accessing is different. The Variant type does not convert to any type, so you must know the type or ask if it is a type. foo.get!int() if(foo[0].type == int) // I think that was valid check. Maybe typeid(int) foo[0].get!int()
Feb 06 2012
Variant allows you to store any value, but it does not need a buffer or have interaction like an array. It can hold any value because it the size of the data structure is the max size of the times it can hold. For this reason it can not actually hold any structure. For an array of any values you use a Variant[] foo = new Variant[100]. foo[0] = myInt; foo[1] = myFloat; However depending on the length of char[static size], you may need to give Variant a larger maximum size.
Unfortunately I'd need to reference a buffer for the known structured types. Variant seems far more useful for making an interpreted language, than for my purposes. I'll just have to simplify the access/reading/writing structures to basically doing just that (Drop any compare and added complexity), and use native data types to handle and work with the data.
Feb 06 2012
On Tuesday, 7 February 2012 at 00:39:00 UTC, Era Scarecrow wrote:Unfortunately I'd need to reference a buffer for the known structured types. Variant seems far more useful for making an interpreted language, than for my purposes.
I've been using Variant with LuaD for some time. Sorry it isn't what you need but hopefully you'll know when it will be useful.
Feb 07 2012
--0015175df040cc46ac04b861fc7f
Content-Type: text/plain; charset=UTF-8
You can roll your own tagged union instead. The S struct can store long and
byte[], S.ptr is a pointer to the data.
enum Type { Long, Bytes }
struct S {
Type type;
void* ptr;
union {
long _long;
byte[] _bytes;
}
this(long l) {
_long = l;
type = Type.Long;
ptr = &_long;
}
this(byte[] bytes) {
_bytes = bytes;
type = Type.Bytes;
ptr = &_long;
}
}
auto s = S(99);
assert(s.ptr == &(s._long));
assert(s.ptr == &(s._bytes));
Pedro Lacerda
2012/2/7 Jesse Phillips <jessekphillips+D gmail.com>
On Tuesday, 7 February 2012 at 00:39:00 UTC, Era Scarecrow wrote:
Unfortunately I'd need to reference a buffer for the known structured
types. Variant seems far more useful for making an interpreted language,
than for my purposes.
I've been using Variant with LuaD for some time. Sorry it isn't what you
need but hopefully you'll know when it will be useful.
--0015175df040cc46ac04b861fc7f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
You can roll your own tagged union instead. The S struct can store long and=
byte[], S.ptr is a pointer to the data.<div><br></div><div><div>=C2=A0 =C2=
=A0 enum Type { Long, Bytes }</div><div>=C2=A0 =C2=A0 struct S {</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Type type;</div>
<div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 void* ptr;</div><div>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 union {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 long _lo=
ng;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 byte[] _bytes;</div=
<div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 t=
l;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 type =3D Type.Long;=
</div>
<div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ptr =3D &_long;</div><di=
v>=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 this(=
byte[] bytes) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 _bytes =
=3D bytes;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 type =3D Typ=
e.Bytes;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ptr =3D &_=
long;</div><div>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =
=C2=A0=C2=A0</div><div>=C2=A0 =C2=A0 auto s =3D S(99);</div><div>=C2=A0 =C2=
=A0 assert(s.ptr =3D=3D &(s._long));</div><div>=C2=A0 =C2=A0 assert(s.p=
tr =3D=3D &(s._bytes));</div><div><br></div>Pedro Lacerda<br><br>
<br><br><div class=3D"gmail_quote">2012/2/7 Jesse Phillips <span dir=3D"ltr=
"><<a href=3D"mailto:jessekphillips%2BD gmail.com">jessekphillips+D gmai=
l.com</a>></span><br><blockquote class=3D"gmail_quote" style=3D"margin:0=
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class=3D"im">On Tuesday, 7 February 2012 at 00:39:00 UTC, Era Scarecro=
w wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
Unfortunately I'd need to reference a buffer for the known structured t=
ypes. Variant seems far more useful for making an interpreted language, tha=
n for my purposes.<br>
</blockquote>
<br></div>
I've been using Variant with LuaD for some time. Sorry it isn't wha=
t you need but hopefully you'll know when it will be useful.<br>
</blockquote></div><br></div>
--0015175df040cc46ac04b861fc7f--
Feb 07 2012
On Tuesday, 7 February 2012 at 17:51:42 UTC, Pedro Lacerda wrote:You can roll your own tagged union instead. The S struct can store long and byte[], S.ptr is a pointer to the data.
Yep, a bit like my code, except with switch cases covering all major types; That and trying to do comparison and setting functions, which seems a bit much. Testing it using templates and testing all the types seems like a nightmare. I've decided I need to pass it a ubyte array so I could do bounds checking before binding the memory to the union. One fewer things to worry about. Let's see... not that I expect you to use this, but I sorta have this as my enum set for types. enum ValueType { raw = 0x00000000, ///default upon unknown mask_types = 0xfff00000, ///Upper 4k defines general types, or 12 flag types mask_size = 0x000fffff, ///lower gives 1Million for size. i_types = 0x00100000, ///integars types i_8 = i_types + byte.sizeof, i_16 = i_types + short.sizeof, i_32 = i_types + int.sizeof, i_64 = i_types + long.sizeof, u_types = 0x00200000, ///unsigned numbers u_8 = u_types + ubyte.sizeof, u_16 = u_types + ushort.sizeof, u_32 = u_types + uint.sizeof, u_64 = u_types + ulong.sizeof, floating_types = 0x00400000, float_32 = floating_types + float.sizeof, fl = float_32, double_64 = floating_types + double.sizeof, doub = double_64, flags_types = 0x00800000, flags_8 = flags_types + ubyte.sizeof, flags_16 = flags_types + ushort.sizeof, flags_32 = flags_types + uint.sizeof, flags_64 = flags_types + ulong.sizeof, ranged_types = 0x01000000, ranged_8 = ranged_types + ubyte.sizeof, ranged_16 = ranged_types + ushort.sizeof, ranged_32 = ranged_types + uint.sizeof, ranged_64 = ranged_types + ulong.sizeof, voidp = 0x02000000, pointer_types = voidp, ///pointers i_8p, u_8p, i_16p, u_16p, i_32p, u_32p, i_64p, u_64p, float_32p, double_64p, var_str = 0x04000000, fixed_str = 0x08000000, var_ustr = 0x10000000, fixed_ustr = 0x20000000 }
Feb 08 2012
--0015175cd3b46d6b3804b8729a4e
Content-Type: text/plain; charset=UTF-8
Umm, sounds nice. If you want to store a long into buffer, you can cast the
desired position as long* and assign the value. The following is adapted
from std.outbuffer, that is another option.
ubyte buffer[];
size_t offset;
ulong a = 1;
byte b = 2;
// allocate space for ulong e byte
buffer.length = a.sizeof + b.sizeof;
*cast(ulong *)&buffer[offset] = a; // store value
offset += a.sizeof; // increment offset
*cast(byte *)&buffer[offset] = b;
offset += b.sizeof;
Pedro Lacerda
2012/2/8 Era Scarecrow <rtcvb32 yahoo.com>
On Tuesday, 7 February 2012 at 17:51:42 UTC, Pedro Lacerda wrote:
You can roll your own tagged union instead. The S struct can store long
and
byte[], S.ptr is a pointer to the data.
Yep, a bit like my code, except with switch cases covering all major
types; That and trying to do comparison and setting functions, which seems
a bit much. Testing it using templates and testing all the types seems like
a nightmare. I've decided I need to pass it a ubyte array so I could do
bounds checking before binding the memory to the union. One fewer things to
worry about.
Let's see... not that I expect you to use this, but I sorta have this as
my enum set for types.
enum ValueType {
raw = 0x00000000, ///default upon unknown
mask_types = 0xfff00000, ///Upper 4k defines general
types, or 12 flag types
mask_size = 0x000fffff, ///lower gives 1Million for
size.
i_types = 0x00100000, ///integars types
i_8 = i_types + byte.sizeof,
i_16 = i_types + short.sizeof,
i_32 = i_types + int.sizeof,
i_64 = i_types + long.sizeof,
u_types = 0x00200000, ///unsigned numbers
u_8 = u_types + ubyte.sizeof,
u_16 = u_types + ushort.sizeof,
u_32 = u_types + uint.sizeof,
u_64 = u_types + ulong.sizeof,
floating_types = 0x00400000,
float_32 = floating_types + float.sizeof, fl = float_32,
double_64 = floating_types + double.sizeof, doub = double_64,
flags_types = 0x00800000,
flags_8 = flags_types + ubyte.sizeof,
flags_16 = flags_types + ushort.sizeof,
flags_32 = flags_types + uint.sizeof,
flags_64 = flags_types + ulong.sizeof,
ranged_types = 0x01000000,
ranged_8 = ranged_types + ubyte.sizeof,
ranged_16 = ranged_types + ushort.sizeof,
ranged_32 = ranged_types + uint.sizeof,
ranged_64 = ranged_types + ulong.sizeof,
voidp = 0x02000000, pointer_types = voidp, ///pointers
i_8p, u_8p,
i_16p, u_16p,
i_32p, u_32p,
i_64p, u_64p,
float_32p, double_64p,
var_str = 0x04000000,
fixed_str = 0x08000000,
var_ustr = 0x10000000,
fixed_ustr = 0x20000000
}
--0015175cd3b46d6b3804b8729a4e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Umm, sounds nice. If you want to store a long into buffer, you can cast the=
desired position as long* and assign the value. The following is adapted f=
rom std.outbuffer, that is another option.<div><div><br></div><div><div>
<font face=3D"'courier new', monospace">=C2=A0 =C2=A0 ubyte buffer[=
];</font></div><div><font face=3D"'courier new', monospace">=C2=A0 =
=C2=A0 size_t offset;</font></div><div><font face=3D"'courier new',=
monospace">=C2=A0 =C2=A0=C2=A0</font></div>
<div><font face=3D"'courier new', monospace">=C2=A0 =C2=A0 ulong a =
=3D 1;</font></div><div><font face=3D"'courier new', monospace">=C2=
=A0 =C2=A0 byte b =3D 2;</font></div><div><font face=3D"'courier new=
9;, monospace">=C2=A0 =C2=A0=C2=A0</font></div>
<div><font face=3D"'courier new', monospace">=C2=A0 =C2=A0 // alloc=
ate space for ulong e byte</font></div><div><font face=3D"'courier new&=
#39;, monospace">=C2=A0 =C2=A0 buffer.length =3D a.sizeof + b.sizeof;</font=
</div><div><font face=3D"'courier new', monospace">=C2=A0 =C2=A0=
<div><span style=3D"font-family:'courier new',monospace">=C2=A0 =C2=
=A0 *cast(ulong *)&buffer[offset] =3D a; // store value</span></div><di=
v><font face=3D"'courier new', monospace">=C2=A0 =C2=A0 offset +=3D=
a.sizeof; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0// increm=
ent offset</font></div>
<div><font face=3D"'courier new', monospace">=C2=A0 =C2=A0=C2=A0</f=
ont></div><div><font face=3D"'courier new', monospace">=C2=A0 =C2=
=A0 *cast(byte *)&buffer[offset] =3D b;</font></div><div><font face=3D"=
'courier new', monospace">=C2=A0 =C2=A0 offset +=3D b.sizeof;</font=
</div>
<div><br></div><div><br></div>Pedro Lacerda<br><br>
<br><br><div class=3D"gmail_quote">2012/2/8 Era Scarecrow <span dir=3D"ltr"=
<<a href=3D"mailto:rtcvb32 yahoo.com">rtcvb32 yahoo.com</a>></span><=
:1px #ccc solid;padding-left:1ex">
<div class=3D"im">On Tuesday, 7 February 2012 at 17:51:42 UTC, Pedro Lacerd=
a wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
You can roll your own tagged union instead. The S struct can store long and=
<br>
byte[], S.ptr is a pointer to the data.<br>
</blockquote>
<br>
<br></div>
Yep, a bit like my code, except with switch cases covering all major types;=
That and trying to do comparison and setting functions, which seems a bit =
much. Testing it using templates and testing all the types seems like a nig=
htmare. I've decided I need to pass it a ubyte array so I could do boun=
ds checking before binding the memory to the union. One fewer things to wor=
ry about.<br>
<br>
Let's see... not that I expect you to use this, but I sorta have this a=
s my enum set for types.<br>
<br>
<br>
enum ValueType {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0raw =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=3D 0x00000000, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ///default upon unknown<=
br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0mask_types =C2=A0 =C2=A0 =C2=A0=3D 0xfff00000, =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ///Upper 4k defines general types, or 12=
flag types<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0mask_size =C2=A0 =C2=A0 =C2=A0 =3D 0x000fffff, =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ///lower gives 1Million for size.<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_types =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0x00100=
000, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ///integars types<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_8 =3D i_types + byte.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_16 =3D i_types + short.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_32 =3D i_types + int.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_64 =3D i_types + long.sizeof,<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0u_types =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0x00200=
000, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ///unsigned numbers<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0u_8 =3D u_types + ubyte.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0u_16 =3D u_types + ushort.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0u_32 =3D u_types + uint.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0u_64 =3D u_types + ulong.sizeof,<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0floating_types =C2=A0=3D 0x00400000,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0float_32 =3D floating_types + float.sizeof, fl =
=3D float_32,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0double_64 =3D floating_types + double.sizeof, d=
oub =3D double_64, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0flags_types =C2=A0 =C2=A0 =3D 0x00800000,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0flags_8 =3D flags_types + ubyte.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0flags_16 =3D flags_types + ushort.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0flags_32 =3D flags_types + uint.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0flags_64 =3D flags_types + ulong.sizeof,<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0ranged_types =3D 0x01000000,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0ranged_8 =3D ranged_types + ubyte.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0ranged_16 =3D ranged_types + ushort.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0ranged_32 =3D ranged_types + uint.sizeof,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0ranged_64 =3D ranged_types + ulong.sizeof,<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0voidp =3D 0x02000000, pointer_types =3D voidp, =
=C2=A0 =C2=A0 =C2=A0///pointers<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_8p, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 u_8p,<=
br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_16p, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0u_16p,=
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_32p, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0u_32p,=
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0i_64p, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0u_64p,=
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0float_32p, =C2=A0 =C2=A0 =C2=A0double_64p,<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0var_str =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0x04000=
000,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0fixed_str =C2=A0 =C2=A0 =C2=A0 =3D 0x08000000,<=
br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0var_ustr =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D 0x10000=
000,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0fixed_ustr =C2=A0 =C2=A0 =C2=A0=3D 0x20000000<b=
r>
}<br>
</blockquote></div><br></div></div>
--0015175cd3b46d6b3804b8729a4e--
Feb 08 2012









=?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> 