Scoped enumerations with added features
Posted: Thu Jul 19, 2018 8:52 pm
This is similar to features provided by the Enum class in Java. It allows enumerations to hold additional information and for their type to be queried for validity.
Demonstration:
Output:
Code: Select all
DeclareModule ENUM_CARDINAL_DIRECTION
Structure Class
*vTable
name.s
ordinal.i
EndStructure
; --
Macro POINTER
i
EndMacro
Interface Public
name.s()
ordinal.i()
EndInterface
;/ Static
Declare new(ordinal.i, name.s)
Declare.POINTER fromOrdinal(ordinal.i)
Declare.POINTER valueOf(name.s)
NewMap values.Public()
NONE.Public=new(1,"NONE")
NORTH.Public=new(2,"NORTH")
EAST.Public=new(3,"EAST")
SOUTH.Public=new(4,"SOUTH")
WEST.Public=new(5,"WEST")
EndDeclareModule
Module ENUM_CARDINAL_DIRECTION
Structure VTable
*name
*ordinal
EndStructure
Declare setVTable(*vTable.Class)
;/ Static
Global vTable.VTable
setVTable(@vTable)
Procedure new(ordinal.i, name.s)
Protected *instance.Class
*instance=AllocateStructure(Class)
*instance\vTable=@vTable
*instance\name.s=name.s
*instance\ordinal=ordinal
ENUM_CARDINAL_DIRECTION::values(Str(ordinal))=*instance
ProcedureReturn *instance
EndProcedure
Procedure.POINTER fromOrdinal(ordinal.i)
ProcedureReturn ENUM_CARDINAL_DIRECTION::values(Str(ordinal))
EndProcedure
Procedure.POINTER valueOf(name.s)
ForEach ENUM_CARDINAL_DIRECTION::values()
If ENUM_CARDINAL_DIRECTION::values()\name()=name.s
ProcedureReturn ENUM_CARDINAL_DIRECTION::values()
EndIf
Next
ProcedureReturn #Null
EndProcedure
;/ Public
Procedure.s name(*this.Class)
ProcedureReturn *this\name.s
EndProcedure
Procedure.i ordinal(*this.Class)
ProcedureReturn *this\ordinal
EndProcedure
;/ Private
Procedure setVTable(*vTable.VTable)
*vTable\name=@name()
*vTable\ordinal=@ordinal()
EndProcedure
EndModule
Interface ENUM_CARDINAL_DIRECTION Extends ENUM_CARDINAL_DIRECTION::Public
EndInterface
Code: Select all
;/ Enums can have names (for debug and serialization)
Debug ENUM_CARDINAL_DIRECTION::NONE\name()
Debug "--"
;/ Query the enum for all values
ForEach ENUM_CARDINAL_DIRECTION::values()
With ENUM_CARDINAL_DIRECTION::values()
Debug Str(\ordinal())+" "+\name()
EndWith
Next
Debug "--"
;/ Deserialize and validation
If Not ENUM_CARDINAL_DIRECTION::valueOf("UNKNOWN")
Debug "No enum by that name"
EndIf
Debug "--"
;/ From ordinal
Define result.ENUM_CARDINAL_DIRECTION
reuslt=ENUM_CARDINAL_DIRECTION::fromOrdinal(3)
Debug result\name()
Code: Select all
NONE
--
1 NONE
2 NORTH
3 EAST
4 SOUTH
5 WEST
--
No enum by that name
--
EAST