Re: Getting enum from value

2017-08-05 Thread Matthew Remmel via Digitalmars-d-learn

On Saturday, 5 August 2017 at 18:26:10 UTC, Kreikey wrote:
On Saturday, 5 August 2017 at 15:33:57 UTC, Matthew Remmel 
wrote:
I feel like I'm missing something, but there has to be an 
easier way to convert a value into an enum than switching over 
every possible value: i.e


[...]


Capitals c = cast(Capitals)"Chicago";
writeln(c);// Illinois


I'm annoyed that I didn't think of trying to cast it. That works 
great if the value exists in the enum. It does something weird if 
the value doesn't though. This is my test.d file:


import std.stdio;

enum Foo {
A = "AV",
B = "BV"
}

void main() {
Foo k = cast(Foo)"BV"; // Works and prints correctly

k = cast(Foo)"CV";
writeln("Type: ", typeid(k));  // Type: test.Foo
writeln("Value: ", k);   // Value: cast(Foo)CV
}

The output shows the type being the Foo enum but the value is 
'cast(Foo)CV'. I would of expected an error or exception to be 
thrown if it wasn't able to cast into an actual enum member. Is 
this something with how the enums are implemented under the hood?


Re: Getting enum from value

2017-08-05 Thread Matthew Remmel via Digitalmars-d-learn

On Saturday, 5 August 2017 at 15:42:53 UTC, Rene Zwanenburg wrote:
On Saturday, 5 August 2017 at 15:33:57 UTC, Matthew Remmel 
wrote:

Any ideas?


You can use to! in std.conv:


import std.stdio;
import std.conv;

enum Foo
{
A = "A",
B = "B"
}

void main()
{
writeln("A".to!Foo);  
}


This only works because the enum name and the value are the same. 
Its actually converting on the enum name, which happens to be the 
same as the value. This doesn't work if the values is different:


enum Foo {
A = "AV",
B = "BV"
}

int main() {
writeln("AV".to!Foo); // Throws exceptions
return 0;
}

It looks like Temtaime's solution works:


enum Foo
{
A = "AV",
B = "BV",
C = "CV",
}



Foo K = [ EnumMembers!Foo ].find!(a => a == `BV`)[0];


I can probably make a template or something out of this to make 
the syntax simpler.


Getting enum from value

2017-08-05 Thread Matthew Remmel via Digitalmars-d-learn
I feel like I'm missing something, but there has to be an easier 
way to convert a value into an enum than switching over every 
possible value: i.e


enum Capitals {
Indiana = "Indianapolis",
Illinois = "Chicago",
Ohio = "Columbus"
}

Capitals enumFromValue(string s) {
switch (s) {
case Capitals.Indiana:
return Capitals.Indiana;
 case Capitals.Illinois:
return Capitals.Illinois;
 case Capitals.Ohio:
return Capitals.Ohio;
 default:
 throw new Exception(format("No Capitals enum member 
with value %s", s));

}
}

int main() {
Capitals c = enumFromValue("Chicago"); // works

// I tried using std.conv, but it matches on the enum member 
name

c = to!Capitals("Chicago") // fails, no member named Chicago
}

With how redundant the enumFromValue(string) implementation is, I 
would think there would be an easier way to do it. I'm sure you 
could use a mixin, a template, or std.traits. I was hoping there 
was a more 'builtin' way to do it though. Something along the 
simplicity of:


int main() {
Capitals c = Capitals("Chicago");
}

Any ideas?


Re: Get UDA of unit tests during Runtime.moduleUnitTester

2017-07-26 Thread Matthew Remmel via Digitalmars-d-learn

On Wednesday, 26 July 2017 at 06:47:20 UTC, Jacob Carlborg wrote:

On 2017-07-26 05:27, Matthew Remmel wrote:


[...]


Unless you want to go with the approach Seb suggested, using 
unit-threaded, you need to recursively iterate the module to 
get all aggregates using __traits(allMembers) then use 
__traits(getUnitTests) for each aggregate to get all unit tests.



[...]


That's not possible, the UDAs are lost after compile time. 
Also, all the unit tests block are combined into one function 
per module, which is what Runtime.moduleUnitTester is running. 
The separate unit test blocks are gone at runtime so there's 
nothing to connect the UDAs to.


Thanks for the info, I'll look into the threaded unit test 
library and see what they are doing, and how.


-Matt


Get UDA of unit tests during Runtime.moduleUnitTester

2017-07-25 Thread Matthew Remmel via Digitalmars-d-learn
I'd like to print out the name given to a unit test via a UDA, as 
the tests are being ran by the Runtime.moduleUnitTester. I'm 
working on writing a custom unit test runner. It would seem that 
the ModuleInfo.unitTest property is an aggregated function of all 
the individual unit test blocks in a module, and therefore the 
UDA value is lost.


I've been attempting to use the __traits(getUnitTests, m) 
function, but that doesn't seem to work with ModuleInfo because 
it is a variable and not a symbol. Additionally, if you run 
__traits(getUnitTests, m) against a module, that doesn't retrieve 
any unit tests that are nested inside classes or structs. So even 
if it did work with ModuleInfo, there may still be problems.


What I would like is to have a module like:
___
module app;

int square(int x) { return x*x; }

@name("square test 1")
unittest {
assert(square(10) == 100);
}

@name("square test 2")
unittest {
assert(square(5) == 25);
}

class Foo {
void someFunc() { return; }

@name("Foo test")
unittest {
assert(someFunc() == something);
}
}
___

So as mentioned above, the first problem is that using 
ModuleInfo.unitTest returns an aggregated function of all 3 unit 
tests for that module, instead of each one individually, so the 
UDA information is lost. The second problem is that running 
__traits(getUnitTests, app) only returns the 2 tests at module 
scope, and not the one nested inside Foo. Even then, I haven't 
been able to figure out how to dynamically get the module symbol 
to pass to __traits inside of the Runtime.moduleUnitTester 
function.


Its possible that I've got some of this backwards and there is an 
easy solution. Its also possible that what i'm trying to do isn't 
currently possible.


Thanks in advance for any help.
--Matt