add typetraits.OrdinalEnum, enumutils.symbolName (#17281)
This commit is contained in:
parent
3dc1bd0d09
commit
eb07a5a75b
4 changed files with 57 additions and 9 deletions
|
|
@ -47,8 +47,9 @@
|
||||||
|
|
||||||
- Added `std/enumutils` module. Added `genEnumCaseStmt` macro that generates case statement to parse string to enum.
|
- Added `std/enumutils` module. Added `genEnumCaseStmt` macro that generates case statement to parse string to enum.
|
||||||
Added `items` for enums with holes.
|
Added `items` for enums with holes.
|
||||||
|
Added `symbolName` to return the enum symbol name ignoring the human readable name.
|
||||||
|
|
||||||
- Added `typetraits.SomeEnumWithHoles` for enums with holes.
|
- Added `typetraits.HoleyEnum` for enums with holes, `OrdinalEnum` for enums without holes.
|
||||||
|
|
||||||
- Removed deprecated `iup` module from stdlib, it has already moved to
|
- Removed deprecated `iup` module from stdlib, it has already moved to
|
||||||
[nimble](https://github.com/nim-lang/iup).
|
[nimble](https://github.com/nim-lang/iup).
|
||||||
|
|
|
||||||
|
|
@ -15,16 +15,20 @@
|
||||||
import std/private/since
|
import std/private/since
|
||||||
export system.`$` # for backward compatibility
|
export system.`$` # for backward compatibility
|
||||||
|
|
||||||
type SomeEnumWithHoles* = (not Ordinal) and enum ## Enum with holes.
|
type HoleyEnum* = (not Ordinal) and enum ## Enum with holes.
|
||||||
|
type OrdinalEnum* = Ordinal and enum ## Enum without holes.
|
||||||
|
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
type A = enum a0 = 2, a1 = 4, a2
|
type A = enum a0 = 2, a1 = 4, a2
|
||||||
type B = enum b0 = 2, b1, b2
|
type B = enum b0 = 2, b1, b2
|
||||||
assert A is SomeEnumWithHoles
|
assert A is enum
|
||||||
assert B isnot SomeEnumWithHoles
|
assert A is HoleyEnum
|
||||||
assert int isnot SomeEnumWithHoles
|
assert A isnot OrdinalEnum
|
||||||
|
assert B isnot HoleyEnum
|
||||||
|
assert B is OrdinalEnum
|
||||||
|
assert int isnot HoleyEnum
|
||||||
type C[T] = enum h0 = 2, h1 = 4
|
type C[T] = enum h0 = 2, h1 = 4
|
||||||
assert C[float] is SomeEnumWithHoles
|
assert C[float] is HoleyEnum
|
||||||
|
|
||||||
proc name*(t: typedesc): string {.magic: "TypeTrait".} =
|
proc name*(t: typedesc): string {.magic: "TypeTrait".} =
|
||||||
## Returns the name of the given type.
|
## Returns the name of the given type.
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import std/macros
|
import std/macros
|
||||||
|
from std/typetraits import OrdinalEnum, HoleyEnum
|
||||||
|
|
||||||
# xxx `genEnumCaseStmt` needs tests and runnableExamples
|
# xxx `genEnumCaseStmt` needs tests and runnableExamples
|
||||||
|
|
||||||
|
|
@ -65,10 +66,17 @@ macro genEnumCaseStmt*(typ: typedesc, argSym: typed, default: typed,
|
||||||
expectKind(default, nnkSym)
|
expectKind(default, nnkSym)
|
||||||
result.add nnkElse.newTree(default)
|
result.add nnkElse.newTree(default)
|
||||||
|
|
||||||
macro enumWithHolesFullRange(a: typed): untyped =
|
macro enumFullRange(a: typed): untyped =
|
||||||
newNimNode(nnkCurly).add(a.getType[1][1..^1])
|
newNimNode(nnkCurly).add(a.getType[1][1..^1])
|
||||||
|
|
||||||
iterator items*[T: enum and not Ordinal](E: typedesc[T]): T =
|
macro enumNames(a: typed): untyped =
|
||||||
|
# this could be exported too; in particular this could be useful for enum with holes.
|
||||||
|
result = newNimNode(nnkBracket)
|
||||||
|
for ai in a.getType[1][1..^1]:
|
||||||
|
assert ai.kind == nnkSym
|
||||||
|
result.add newLit ai.strVal
|
||||||
|
|
||||||
|
iterator items*[T: HoleyEnum](E: typedesc[T]): T =
|
||||||
## Iterates over an enum with holes.
|
## Iterates over an enum with holes.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
type A = enum a0 = 2, a1 = 4, a2
|
type A = enum a0 = 2, a1 = 4, a2
|
||||||
|
|
@ -76,4 +84,18 @@ iterator items*[T: enum and not Ordinal](E: typedesc[T]): T =
|
||||||
from std/sequtils import toSeq
|
from std/sequtils import toSeq
|
||||||
assert A.toSeq == [a0, a1, a2]
|
assert A.toSeq == [a0, a1, a2]
|
||||||
assert B[float].toSeq == [B[float].b0, B[float].b1]
|
assert B[float].toSeq == [B[float].b0, B[float].b1]
|
||||||
for a in enumWithHolesFullRange(E): yield a
|
for a in enumFullRange(E): yield a
|
||||||
|
|
||||||
|
func symbolName*[T: OrdinalEnum](a: T): string =
|
||||||
|
## Returns the symbol name of an enum.
|
||||||
|
runnableExamples:
|
||||||
|
type B = enum
|
||||||
|
b0 = (10, "kb0")
|
||||||
|
b1 = "kb1"
|
||||||
|
b2
|
||||||
|
let b = B.low
|
||||||
|
assert b.symbolName == "b0"
|
||||||
|
assert $b == "kb0"
|
||||||
|
static: assert B.high.symbolName == "b2"
|
||||||
|
const names = enumNames(T)
|
||||||
|
names[a.ord - T.low.ord]
|
||||||
|
|
|
||||||
|
|
@ -12,5 +12,26 @@ template main =
|
||||||
doAssert A.toSeq == [a0, a1, a2]
|
doAssert A.toSeq == [a0, a1, a2]
|
||||||
doAssert B[float].toSeq == [B[float].b0, B[float].b1]
|
doAssert B[float].toSeq == [B[float].b0, B[float].b1]
|
||||||
|
|
||||||
|
block: # symbolName
|
||||||
|
block:
|
||||||
|
type A2 = enum a20, a21, a22
|
||||||
|
doAssert $a21 == "a21"
|
||||||
|
doAssert a21.symbolName == "a21"
|
||||||
|
proc `$`(a: A2): string = "foo"
|
||||||
|
doAssert $a21 == "foo"
|
||||||
|
doAssert a21.symbolName == "a21"
|
||||||
|
var a = a22
|
||||||
|
doAssert $a == "foo"
|
||||||
|
doAssert a.symbolName == "a22"
|
||||||
|
|
||||||
|
type B = enum
|
||||||
|
b0 = (10, "kb0")
|
||||||
|
b1 = "kb1"
|
||||||
|
b2
|
||||||
|
let b = B.low
|
||||||
|
doAssert b.symbolName == "b0"
|
||||||
|
doAssert $b == "kb0"
|
||||||
|
static: doAssert B.high.symbolName == "b2"
|
||||||
|
|
||||||
static: main()
|
static: main()
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue