Jump to page: 1 2
Thread overview
How to obtain Variant underlying type?
Jul 10
jfondren
Jul 10
drug007
Jul 11
jfondren
July 09

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

July 09
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.
July 09
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
July 10

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:

>

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

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);
}
July 10

On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote:

>
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.

July 10
On 7/10/22 20:26, anonymouse wrote:
> 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.
> 

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.
July 10

On Sunday, 10 July 2022 at 18:31:46 UTC, drug007 wrote:

>

On 7/10/22 20:26, anonymouse wrote:

>

On Sunday, 10 July 2022 at 06:26:37 UTC, jfondren wrote:

>
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.

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.

For reference, this is the more correct way:

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.

July 11
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
July 11

On Monday, 11 July 2022 at 03:17:33 UTC, anonymouse wrote:

>

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

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:

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]:

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);
}
July 11

On Sunday, 10 July 2022 at 19:14:34 UTC, Paul Backus wrote:

>

For reference, this is the more correct way:

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

« First   ‹ Prev
1 2