digitalmars.D.learn - How to obtain Variant underlying type?
- anonymouse (13/13) Jul 09 2022 std.variant;
- Adam D Ruppe (3/6) Jul 09 2022 Impossible; Variant's type is only known at runtime, and this
- anonymouse (13/15) Jul 09 2022 Hmmm. Okay, thanks. What I really need to know is how many
- jfondren (28/44) Jul 09 2022 ```d
- anonymouse (2/18) Jul 10 2022 Thank you very much.
- drug007 (4/26) Jul 10 2022 I'd like to say that using of exception to break loop is really bad.
- Paul Backus (12/39) Jul 10 2022 For reference, this is the more correct way:
- anonymouse (6/17) Jul 10 2022 I honestly cannot say why but I was having a problem using this
- anonymouse (3/7) Jul 10 2022 Thanks for the advice. Lesson learned.
- jfondren (43/51) Jul 10 2022 Oh, sorry. I didn't defend the code in any way because I assumed
- anonymouse (27/32) Jul 10 2022 And you were right. I did search for a better solution and came
- Salih Dincer (37/39) Jul 11 2022 I like it!
std.variant; Variant v = [[1], [2], [3]]; writeln(v.type); // int[][] typeof(v.type); // TypeInfo assert(v.type == typeid(int[][]); As demonstrated by the assert statement, .type returns the typeid of the underlying type. How would I obtain the actual type such that: auto vb = v.base; // what should I put here to achieve the following: typeof(vb); // int[][] assert(vb == [[1], [2], [3]]); --anonymouse
Jul 09 2022
On Saturday, 9 July 2022 at 14:36:44 UTC, anonymouse wrote:auto vb = v.base; // what should I put here to achieve the following: typeof(vb); // int[][]Impossible; Variant's type is only known at runtime, and this would require compile time knowledge.
Jul 09 2022
On Saturday, 9 July 2022 at 14:46:36 UTC, Adam D Ruppe wrote:Impossible; Variant's type is only known at runtime, and this would require compile time knowledge.Hmmm. Okay, thanks. What I really need to know is how many dimensions an array has and the total elements per dimension so that I can create temporary storage for it later. this(T)(T a) in(imported!"std.traits".isDynamic!T) { data = a; // data is of type Variant shape = [a.length, {?, ...}]; // what's the best way to deterine? } Thanks, --anonymouse
Jul 09 2022
On Saturday, 9 July 2022 at 23:04:20 UTC, anonymouse wrote:On Saturday, 9 July 2022 at 14:46:36 UTC, Adam D Ruppe wrote:```d import std.variant : Variant; size_t[] shape(Variant v) { import std.variant : VariantException; size_t[] s; try { while (true) { Variant elem = v[0]; s ~= v.length; v = elem; } } catch (VariantException e) { return s; } } unittest { assert([3, 1] == [[1], [2], [3]].Variant.shape); assert([2, 1] == [[1], [2]].Variant.shape); assert([2, 2] == [[1, 0], [2, 0]].Variant.shape); assert([2] == [1, 2].Variant.shape); assert([] == 2.Variant.shape); // irregularity not checked assert([2, 2] == [[1, 0], [2]].Variant.shape); // arguably should be [2, 0] assert([2] == [[], []].Variant.shape); } ```Impossible; Variant's type is only known at runtime, and this would require compile time knowledge.Hmmm. Okay, thanks. What I really need to know is how many dimensions an array has and the total elements per dimension so that I can create temporary storage for it later. this(T)(T a) in(imported!"std.traits".isDynamic!T) { data = a; // data is of type Variant shape = [a.length, {?, ...}]; // what's the best way to deterine? } Thanks, --anonymouse
Jul 09 2022
On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote:```d import std.variant : Variant; size_t[] shape(Variant v) { import std.variant : VariantException; size_t[] s; try { while (true) { Variant elem = v[0]; s ~= v.length; v = elem; } } catch (VariantException e) { return s; } } ```Thank you very much.
Jul 10 2022
On 7/10/22 20:26, anonymouse wrote:On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote:I'd like to say that using of exception to break loop is really bad. Exception is exceptional thing but in the case above the exception is ordinary completion of the loop happens on regular basis. Don't do that.```d import std.variant : Variant; size_t[] shape(Variant v) { import std.variant : VariantException; size_t[] s; try { while (true) { Variant elem = v[0]; s ~= v.length; v = elem; } } catch (VariantException e) { return s; } } ```Thank you very much.
Jul 10 2022
On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote:On 7/10/22 20:26, anonymouse wrote:For reference, this is the more correct way: ```d while (cast(TypeInfo_Array) v.type !is null) { Variant elem = v[0]; // etc. } ``` Hard to blame anyone for not coming up with that on their first try, especially since `TypeInfo_Array` is not even documented--you have to read the source of `object.d` to find out about it.On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote:I'd like to say that using of exception to break loop is really bad. Exception is exceptional thing but in the case above the exception is ordinary completion of the loop happens on regular basis. Don't do that.```d import std.variant : Variant; size_t[] shape(Variant v) { import std.variant : VariantException; size_t[] s; try { while (true) { Variant elem = v[0]; s ~= v.length; v = elem; } } catch (VariantException e) { return s; } } ```Thank you very much.
Jul 10 2022
On Sunday, 10 July 2022 at 19:14:34 UTC, Paul Backus wrote:For reference, this is the more correct way: ```d while (cast(TypeInfo_Array) v.type !is null) { Variant elem = v[0]; // etc. } ``` Hard to blame anyone for not coming up with that on their first try, especially since `TypeInfo_Array` is not even documented--you have to read the source of `object.d` to find out about it.I honestly cannot say why but I was having a problem using this earlier. After several hours of frustration, I rebooted the computer, went for a run, came back, and tried again. It works!!! Thank you very much. --anonymouse
Jul 10 2022
On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote:I'd like to say that using of exception to break loop is really bad. Exception is exceptional thing but in the case above the exception is ordinary completion of the loop happens on regular basis. Don't do that.Thanks for the advice. Lesson learned. --anonymouse
Jul 10 2022
On Monday, 11 July 2022 at 03:17:33 UTC, anonymouse wrote:On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote:Oh, sorry. I didn't defend the code in any way because I assumed that the exceptional design would be seen as obviously bad (and that someone else would dig harder in order to find a better solution). The TypeInfo_Array fix breaks the last assertion of those unit tests, though. This works: ```d import std.variant : Variant; size_t[] shape(Variant v) { size_t[] s; while (cast(TypeInfo_Array) v.type !is null && v.length > 0) { Variant elem = v[0]; s ~= v.length; v = elem; } return s; } ``` Although, that last assertion really is debatable. Languages like APL would read it as having a shape of [2, 0]: ```d import std.variant : Variant; size_t[] shape(Variant v) { size_t[] s; while (cast(TypeInfo_Array) v.type !is null) { s ~= v.length; if (!v.length) break; v = v[0]; } return s; } unittest { assert([3, 1] == [[1], [2], [3]].Variant.shape); assert([2, 1] == [[1], [2]].Variant.shape); assert([2, 2] == [[1, 0], [2, 0]].Variant.shape); assert([2] == [1, 2].Variant.shape); assert([] == 2.Variant.shape); assert([2, 0] == [[], []].Variant.shape); // irregularity not checked assert([2, 2] == [[1, 0], [2]].Variant.shape); } ```I'd like to say that using of exception to break loop is really bad. Exception is exceptional thing but in the case above the exception is ordinary completion of the loop happens on regular basis. Don't do that.Thanks for the advice. Lesson learned. --anonymouse
Jul 10 2022
On Monday, 11 July 2022 at 05:41:40 UTC, jfondren wrote:Oh, sorry. I didn't defend the code in any way because I assumed that the exceptional design would be seen as obviously bad (and that someone else would dig harder in order to find a better solution).And you were right. I did search for a better solution and came across [1]. Although I was having some issues adapting it for my use case, Paul Backus' follow-up clarified the issue. This is what my naive brain led to before reading this response. ```d size_t[] shape(Variant v) { typeof(return) dims; while(cast(TypeInfo_Array) v.type !is null) { dims ~= v.length; v = v[0]; } if(!dims.length && v.length) { dims ~= v.length; dims ~= 0; } return dims; } ``` Didn't see the bugs that would occur when a scalar or empty array was passed because I hadn't tested for them.if (!v.length) break;Pure gold! Bugs are eliminated, and the code is shorter. Thank you. --anonymouse [1] https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html
Jul 10 2022
On Monday, 11 July 2022 at 06:59:32 UTC, anonymouse wrote:I did search for a better solution and came across... https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.htmlI like it! It's been a good collaboration... ```d import std.variant; auto generate(T)(size_t x, size_t y) { T[][] result; ubyte[] arr = new ubyte[x * y * T.sizeof]; size_t m = y * T.sizeof; foreach (i; 0 .. x) { size_t n = i * m; result ~= cast(T[])arr[n .. n + m]; } return result; } size_t[] shape(Variant v) { typeof(return) dims; while (cast(TypeInfo_Array) v.type !is null) { dims ~= v.length; v = v[0]; } if (!dims.length && v.length) { dims ~= v.length; dims ~= 0; } return dims; } void main() { foreach(x; 1..100) { foreach(y; 1..100) { auto test = Variant(generate!int(x, y)); assert(shape(test) == [x, y]); } } } ``` SDB 79
Jul 11 2022