Add a macro returning enum items count (#15824)

Add a macro `enumLen` which is used to determine the number of items in
an enumeration type to the `typetraits.nim` module. Also, add unit tests
for it in the `ttypetraits.nim` module.

Related to nimlang/Nim#15824
This commit is contained in:
Ivan Bobev
2020-11-09 11:02:01 +02:00
committed by GitHub
parent 5db181f377
commit d03f24147a
3 changed files with 55 additions and 0 deletions

View File

@@ -6,6 +6,8 @@
- Make `{.requiresInit.}` pragma to work for `distinct` types.
- Added a macros `enumLen` for returning the number of items in an enum to the `typetraits.nim` module.
- `prelude` now works with the JavaScript target.
- Added `ioutils` module containing `duplicate` and `duplicateTo` to duplicate `FileHandle` using C function `dup` and `dup2`.

View File

@@ -107,6 +107,19 @@ since (1, 3, 5):
import std/macros
macro enumLen*(T: typedesc[enum]): int =
## Returns the number of items in the enum `T`.
runnableExamples:
type Foo = enum fooItem1 fooItem2
doAssert Foo.enumLen == 2
let bracketExpr = getType(T)
expectKind(bracketExpr, nnkBracketExpr)
let enumTy = bracketExpr[1]
expectKind(enumTy, nnkEnumTy)
result = newLit(enumTy.len - 1)
macro genericParamsImpl(T: typedesc): untyped =
# auxiliary macro needed, can't do it directly in `genericParams`
result = newNimNode(nnkTupleConstr)

View File

@@ -303,3 +303,43 @@ block: # elementType
var a: seq[int]
doAssert elementType(a) is int
doAssert elementType(seq[char].default) is char
block: # enum.len
type
Direction = enum
north, east, south, west
Direction2 = Direction
Direction3 = Direction2
TokenType = enum
a = 2, b = 4, c = 89
MyEnum = enum
##[This is test of enum with a doc comment.
Which is also a multi line one.]##
valueA = (0, "my value A"),
## The items are also commented. This has both integer and string
## values.
valueB = "value B",
## This item has only a string value,
valueC = 2,
## and this one only an integer.
valueD = (3, "abc")
## Both, integer and string values again.
OtherEnum {.pure.} = enum
valueX, valueY, valueZ
MyFlag {.size: sizeof(cint).} = enum
A, B, C, D
static:
doAssert Direction.enumLen == 4
doAssert Direction2.enumLen == 4
doAssert Direction3.enumLen == 4
doAssert TokenType.enumLen == 3
doAssert MyEnum.enumLen == 4
doAssert OtherEnum.enumLen == 3
doAssert MyFlag.enumLen == 4