2020-06-22 18:35:42 +03:00
|
|
|
import
|
|
|
|
macros
|
|
|
|
|
2019-03-12 04:32:08 +02:00
|
|
|
template init*(lvalue: var auto) =
|
2018-12-18 17:39:39 +02:00
|
|
|
mixin init
|
2019-03-12 04:32:08 +02:00
|
|
|
lvalue = init(type(lvalue))
|
|
|
|
|
|
|
|
template init*(lvalue: var auto, a1: auto)=
|
|
|
|
mixin init
|
|
|
|
lvalue = init(type(lvalue), a1)
|
|
|
|
|
|
|
|
template init*(lvalue: var auto, a1, a2: auto) =
|
|
|
|
mixin init
|
|
|
|
lvalue = init(type(lvalue), a1, a2)
|
|
|
|
|
|
|
|
template init*(lvalue: var auto, a1, a2, a3: auto) =
|
|
|
|
mixin init
|
|
|
|
lvalue = init(type(lvalue), a1, a2, a3)
|
2018-12-18 17:39:39 +02:00
|
|
|
|
2019-07-03 02:30:49 +03:00
|
|
|
when not declared(default):
|
|
|
|
proc default*(T: type): T = discard
|
|
|
|
|
2019-07-24 13:39:34 +03:00
|
|
|
proc toArray*[T](N: static int, data: openarray[T]): array[N, T] =
|
|
|
|
doAssert data.len == N
|
|
|
|
copyMem(addr result[0], unsafeAddr data[0], N)
|
|
|
|
|
2019-08-02 11:51:04 +03:00
|
|
|
template anonConst*(val: untyped): untyped =
|
|
|
|
const c = val
|
|
|
|
c
|
2019-10-02 16:24:59 +03:00
|
|
|
|
2020-04-22 15:41:42 +03:00
|
|
|
func declval*(T: type): T {.compileTime.} =
|
|
|
|
## `declval` denotes an anonymous expression of a particular
|
|
|
|
## type. It can be used in situations where you want to determine
|
|
|
|
## the type of an overloaded call in `typeof` expressions.
|
|
|
|
##
|
|
|
|
## Example:
|
|
|
|
## ```
|
|
|
|
## type T = typeof foo(declval(string), declval(var int))
|
|
|
|
## ```
|
|
|
|
##
|
|
|
|
## Please note that `declval` has two advantages over `default`:
|
2020-06-22 18:35:42 +03:00
|
|
|
##
|
2020-04-22 15:41:42 +03:00
|
|
|
## 1. It can return expressions with proper `var` or `lent` types.
|
2020-06-22 18:35:42 +03:00
|
|
|
##
|
2020-04-22 15:41:42 +03:00
|
|
|
## 2. It will work for types that lack a valid default value due
|
|
|
|
## to `not nil` or `requiresInit` requirements.
|
|
|
|
##
|
2020-04-22 16:34:11 +03:00
|
|
|
doAssert false,
|
2020-04-22 16:39:37 +03:00
|
|
|
"declval should be used only in `typeof` expressions and concepts"
|
2020-04-22 15:41:42 +03:00
|
|
|
default(ptr T)[]
|
|
|
|
|
2019-10-02 16:24:59 +03:00
|
|
|
when not compiles(len((1, 2))):
|
|
|
|
import typetraits
|
|
|
|
|
|
|
|
func len*(x: tuple): int =
|
|
|
|
arity(type(x))
|
|
|
|
|
2020-03-29 17:34:45 +02:00
|
|
|
# Get an object's base type, as a cstring. Ref objects will have an ":ObjectType"
|
|
|
|
# suffix.
|
|
|
|
# From: https://gist.github.com/stefantalpalaru/82dc71bb547d6f9178b916e3ed5b527d
|
|
|
|
proc baseType*(obj: RootObj): cstring =
|
|
|
|
when not defined(nimTypeNames):
|
|
|
|
raiseAssert("you need to compile this with '-d:nimTypeNames'")
|
|
|
|
else:
|
|
|
|
{.emit: "result = `obj`->m_type->name;".}
|
|
|
|
|
|
|
|
proc baseType*(obj: ref RootObj): cstring =
|
|
|
|
obj[].baseType
|
|
|
|
|
2020-06-22 18:35:42 +03:00
|
|
|
when false:
|
|
|
|
# TODO: Implementing this doesn't seem possible at the moment.
|
|
|
|
#
|
|
|
|
# When given enum like:
|
|
|
|
#
|
|
|
|
# type WithoutHoles2 = enum
|
|
|
|
# A2 = 2, B2 = 3, C2 = 4
|
|
|
|
#
|
|
|
|
# ...the code below will print:
|
|
|
|
#
|
|
|
|
# EnumTy
|
|
|
|
# Empty
|
|
|
|
# Sym "A2"
|
|
|
|
# Sym "B2"
|
|
|
|
# Sym "C2"
|
|
|
|
#
|
|
|
|
macro hasHoles*(T: type[enum]): bool =
|
|
|
|
let t = getType(T)[1]
|
|
|
|
echo t.treeRepr
|
|
|
|
return newLit(true)
|
|
|
|
|
|
|
|
func checkedEnumAssign*[E: enum, I: SomeInteger](res: var E, value: I): bool =
|
|
|
|
## This function can be used to safely assign a tainted integer value (coming
|
|
|
|
## from untrusted source) to an enum variable. The function will return `true`
|
|
|
|
## if the integer value is within the acceped values of the enum and `false`
|
|
|
|
## otherwise.
|
|
|
|
|
|
|
|
# TODO: Enums with holes are not supported yet
|
|
|
|
# static: doAssert(not hasHoles(E))
|
|
|
|
|
|
|
|
when I is SomeSignedInt or low(E).int > 0:
|
|
|
|
if value < I(low(E)):
|
|
|
|
return false
|
|
|
|
|
|
|
|
if value > I(high(E)):
|
|
|
|
return false
|
|
|
|
|
|
|
|
res = E value
|
|
|
|
return true
|
|
|
|
|