Menu
Home
Create new Paste
Log in
Code
Theme: cobalt
Theme: eclipse
Theme: elegant
Theme: monokai
Theme: neat
Theme: night
Theme: rubyblue
import std.traits; import std.conv : ConvException, assertThrown; import std.string; import std.math; import std.stdio; import std.range; template RootElementType(T) { static if (isInputRange!(ElementType!T)) alias RootElementType!(ElementType!T) RootElementType; else alias ElementType!T RootElementType; } /** Convert a value that is implicitly convertible to the enum base type into an Enum value. If the value does not match any enum member values, or if it matches more than one member value throw a ConvException. */ T toImpl(T, S)(S value) if (is(T == enum) && is(S : OriginalType!T) && !isFloatingPoint!(OriginalType!T)) { T result; size_t matches; foreach (Member; EnumMembers!T) { if (Member == value) { result = Member; if (++matches > 1) throw new ConvException(format("Value (%s) matches more than one member value of enum '%s'", value, T.stringof)); } } if (!matches) throw new ConvException(format("Value (%s) does not match any member value of enum '%s'", value, T.stringof)); return result; } /** Ditto: Specialization for Enums that have a floating point base type. @equal must be a function which takes the enum base type as its first parameter, the type of @value as its second parameter, and return true if the two compare equal. */ T toImpl(T, alias equal, S)(S value) if (is(T == enum) && is(S : OriginalType!T) && isFloatingPoint!(OriginalType!T)) { T result; size_t matches; foreach (Member; EnumMembers!T) { if (equal(Member, value)) { result = Member; if (++matches > 1) throw new ConvException(format("Value (%s) matches more than one member value of enum '%s'", value, fullyQualifiedName!T)); } } if (!matches) throw new ConvException(format("Value (%s) does not match any member value of enum '%s'", value, fullyQualifiedName!T)); return result; } /** ditto for arrays */ T toImpl(T, S)(S arr) if (isArray!T && is(RootElementType!T == enum) && isArray!S && !isFloatingPoint!(OriginalType!(RootElementType!T))) { T result; foreach (val; arr) result ~= to!(ElementType!T)(val); return result; } /** ditto for float arrays */ T toImpl(T, alias equal, S)(S arr) if (isArray!T && is(RootElementType!T == enum) && isArray!S && isFloatingPoint!(OriginalType!(RootElementType!T))) { T result; foreach (val; arr) result ~= to!(ElementType!T, equal)(val); return result; } alias toImpl to; enum En : int { A = 10, B = 20, C = 30, D = 20 } enum EF : float { C = 4.9 } enum EF2 : float { A = 4.9, B = 1.0, C = 4.9 } enum EF3 : float { A = 1.0, B = 2.0, C = 3.0, D = 4.0 } void test() { En en1 = to!En(10); assert(en1 == En.A); assertThrown!ConvException(to!En(5)); // matches more than one assertThrown!ConvException(to!En(20)); static bool equal(float a, float b) { return feqrel(a, b) >= 24; } float f = 4.9; EF enf = to!(EF, equal)(f); float f2 = 4.9; // matches more than one assertThrown!ConvException(to!(EF2, equal)(f2)); // arrays En[][] m1 = to!(En[][])([[10, 30], [30, 10]]); assert(m1 == [[En.A, En.C], [En.C, En.A]]); // float array EF3[][] f1 = to!(EF3[][], equal)([[1.0, 2.0], [3.0, 4.0]]); assert(f1 == [[EF3.A, EF3.B], [EF3.C, EF3.D]]); } void main() { test(); }
Result:
Success
/
Return code: 0
/
Compilation time:
0.315
seconds
/
Run time:
0.001
seconds
Disassembly
Username
Message
Add comment
Paste info
Author:
Guest
Views:
109
Private:
no
Expires:
Never
Uploaded:
24.10.12 19:47
Parent:
#ee99ce99
Votes
:
0
Tweet
Compilation
Compiler:
DMD 2.060
Pointer size:
m32
Actions
Download
Fork
Raw
×
Confirm
Are you sure you want to delete this paste?
There's no way back!
×
Confirm
Reason