www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - `examplevalues` property

reply "HaraldZealot" <harald_zealot tut.by> writes:
I found myself in situation that were good that all types support 
`.examplevalues` property in unittest version. This property will 
return array of predefined values for specified type (we can even 
have some convention like `examplevalues[0]` is `init`, 
`examplevalues[1]` is `min` (for numerical type) an so on). If 
custom types doesn't redefine this property the array consist 
only from `init`.

The use case for this: templated struct or class with 
container-like semantics and internal unittest for method of such 
class.

Thoughts?
Aug 03 2015
parent reply "Andrea Fontana" <nospam example.com> writes:
On Monday, 3 August 2015 at 12:13:15 UTC, HaraldZealot wrote:
 I found myself in situation that were good that all types 
 support `.examplevalues` property in unittest version. This 
 property will return array of predefined values for specified 
 type (we can even have some convention like `examplevalues[0]` 
 is `init`, `examplevalues[1]` is `min` (for numerical type) an 
 so on). If custom types doesn't redefine this property the 
 array consist only from `init`.

 The use case for this: templated struct or class with 
 container-like semantics and internal unittest for method of 
 such class.

 Thoughts?
Why don't you use templates? Something like: enum ValueType { Init, Min, Max } auto exampleValues(T)() { T[ValueType] retVal; retVal[ValueType.Init] = T.init; static if (__traits(compiles, T.min)) retVal[ValueType.Min] = T.min; static if (__traits(compiles, T.max)) retVal[ValueType.Max] = T.max; return retVal; } exampleValues!int.writeln; exampleValues!string.writeln;
Aug 03 2015
parent reply "HaraldZealot" <harald_zealot tut.by> writes:
On Monday, 3 August 2015 at 13:13:55 UTC, Andrea Fontana wrote:
 Why don't you use templates? Something like:

 enum ValueType
 {
 	Init,
 	Min,
 	Max
 }

 auto exampleValues(T)()
 {
 	T[ValueType] retVal;

 	retVal[ValueType.Init] = T.init;
 	static if (__traits(compiles, T.min)) retVal[ValueType.Min] = 
 T.min;
 	static if (__traits(compiles, T.max)) retVal[ValueType.Max] = 
 T.max;

 	return retVal;
 }

 exampleValues!int.writeln;
 exampleValues!string.writeln;
Good solution! But there is something that not perfect: it can be customizable only with template specialization as I see. I want not only standard values like `init` `max` or `min` but also some example value like 1, 2, 3, 4, 5 for `int`. In last case your template solution not so convenient as desired (introduction in language feature like `.testValue1` seems ridiculous, and without that only template specialization can provide customization, as I have said). But this seems interesting direction, and easy to implement in object.d (without library implementation, this feature have little benefit).
Aug 03 2015
parent reply "Andrea Fontana" <nospam example.com> writes:
On Monday, 3 August 2015 at 13:54:51 UTC, HaraldZealot wrote:
 On Monday, 3 August 2015 at 13:13:55 UTC, Andrea Fontana wrote:
 Why don't you use templates? Something like:

 enum ValueType
 {
 	Init,
 	Min,
 	Max
 }

 auto exampleValues(T)()
 {
 	T[ValueType] retVal;

 	retVal[ValueType.Init] = T.init;
 	static if (__traits(compiles, T.min)) retVal[ValueType.Min] = 
 T.min;
 	static if (__traits(compiles, T.max)) retVal[ValueType.Max] = 
 T.max;

 	return retVal;
 }

 exampleValues!int.writeln;
 exampleValues!string.writeln;
Good solution! But there is something that not perfect: it can be customizable only with template specialization as I see. I want not only standard values like `init` `max` or `min` but also some example value like 1, 2, 3, 4, 5 for `int`. In last case your template solution not so convenient as desired (introduction in language feature like `.testValue1` seems ridiculous, and without that only template specialization can provide customization, as I have said). But this seems interesting direction, and easy to implement in object.d (without library implementation, this feature have little benefit).
You have to write the same amount of code. It's just one line for each type... Something like: import std.traits; enum ValueType { Init, Min, Max } auto exampleValues(T)() { T[ValueType] retVal; retVal[ValueType.Init] = T.init; static if (__traits(compiles, T.min)) retVal[ValueType.Min] = T.min; static if (__traits(compiles, T.max)) retVal[ValueType.Max] = T.max; static if(isIntegral!T) return tuple!("defaults", "customs")(retVal, [1,2,3,4,5]); else static if(isFloatingPoint!T) return tuple!("defaults", "customs")(retVal, [1.0,2.0,T.nan]); else static if(isSomeString!T) return tuple!("defaults", "customs")(retVal, ["hello", "world"]); else return tuple!("defaults", "customs")(retVal, T[].init); }
Aug 03 2015
parent "HaraldZealot" <harald_zealot tut.by> writes:
On Monday, 3 August 2015 at 14:30:43 UTC, Andrea Fontana wrote:
 On Monday, 3 August 2015 at 13:54:51 UTC, HaraldZealot wrote:

 You have to write the same amount of code.
 It's just one line for each type... Something like:

 [...]
Many thanks, it seems like good workaround for my personal use case. But have something like that in Phobos were great from my POV.
Aug 03 2015