parent
8c1083d3b7
commit
c5c4da4f3c
4 changed files with 118 additions and 2 deletions
|
|
@ -138,6 +138,7 @@ proc effectProblem(f, a: PType; result: var string) =
|
||||||
|
|
||||||
proc renderNotLValue(n: PNode): string =
|
proc renderNotLValue(n: PNode): string =
|
||||||
result = $n
|
result = $n
|
||||||
|
let n = if n.kind == nkHiddenDeref: n[0] else: n
|
||||||
if n.kind == nkHiddenCallConv and n.len > 1:
|
if n.kind == nkHiddenCallConv and n.len > 1:
|
||||||
result = $n[0] & "(" & result & ")"
|
result = $n[0] & "(" & result & ")"
|
||||||
elif n.kind in {nkHiddenStdConv, nkHiddenSubConv} and n.len == 2:
|
elif n.kind in {nkHiddenStdConv, nkHiddenSubConv} and n.len == 2:
|
||||||
|
|
@ -394,6 +395,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
args])
|
args])
|
||||||
|
|
||||||
proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
|
proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
|
||||||
|
let a = if a.kind == nkHiddenDeref: a[0] else: a
|
||||||
if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym:
|
if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym:
|
||||||
let s = a.sons[0].sym
|
let s = a.sons[0].sym
|
||||||
if s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty:
|
if s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty:
|
||||||
|
|
|
||||||
|
|
@ -640,6 +640,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
|
||||||
|
|
||||||
return
|
return
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
|
let n = if n.kind == nkHiddenDeref: n[0] else: n
|
||||||
if n.sons[i].kind == nkHiddenCallConv:
|
if n.sons[i].kind == nkHiddenCallConv:
|
||||||
# we need to recurse explicitly here as converters can create nested
|
# we need to recurse explicitly here as converters can create nested
|
||||||
# calls and then they wouldn't be analysed otherwise
|
# calls and then they wouldn't be analysed otherwise
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
|
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
|
||||||
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
|
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
|
||||||
linter, lineinfos, modulegraphs
|
linter, lineinfos, lowerings, modulegraphs
|
||||||
|
|
||||||
when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler):
|
when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler):
|
||||||
import docgen
|
import docgen
|
||||||
|
|
@ -1855,7 +1855,13 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
else:
|
else:
|
||||||
param = copyTree(arg)
|
param = copyTree(arg)
|
||||||
addSon(result, param)
|
addSon(result, param)
|
||||||
|
|
||||||
|
if dest.kind in {tyVar, tyLent}:
|
||||||
|
dest.flags.incl tfVarIsPtr
|
||||||
|
result = newDeref(result)
|
||||||
|
|
||||||
inc(m.convMatches)
|
inc(m.convMatches)
|
||||||
|
if m.genericConverter == false:
|
||||||
m.genericConverter = srca == isGeneric or destIsGeneric
|
m.genericConverter = srca == isGeneric or destIsGeneric
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
||||||
107
tests/converter/tconverter_unique_ptr.nim
Normal file
107
tests/converter/tconverter_unique_ptr.nim
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
|
||||||
|
discard """
|
||||||
|
file: "tconverter_unique_ptr.nim"
|
||||||
|
targets: "c cpp"
|
||||||
|
output: '''5
|
||||||
|
2.0 5
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
## Bugs 9698 and 9699
|
||||||
|
|
||||||
|
type
|
||||||
|
UniquePtr*[T] = object
|
||||||
|
## non copyable pointer to object T, exclusive ownership of the object is assumed
|
||||||
|
val: ptr T
|
||||||
|
|
||||||
|
MyLen* = distinct int
|
||||||
|
|
||||||
|
MySeq* = object
|
||||||
|
## Vectorized matrix
|
||||||
|
len: MyLen # scalar size
|
||||||
|
data: ptr UncheckedArray[float]
|
||||||
|
|
||||||
|
proc `$`(x: MyLen): string {.borrow.}
|
||||||
|
|
||||||
|
proc `=destroy`*(m: var MySeq) {.inline.} =
|
||||||
|
if m.data != nil:
|
||||||
|
deallocShared(m.data)
|
||||||
|
m.data = nil
|
||||||
|
|
||||||
|
proc `=`*(m: var MySeq, m2: MySeq) =
|
||||||
|
if m.data == m2.data: return
|
||||||
|
if m.data != nil:
|
||||||
|
`=destroy`(m)
|
||||||
|
|
||||||
|
m.len = m2.len
|
||||||
|
let bytes = m.len.int * sizeof(float)
|
||||||
|
if bytes > 0:
|
||||||
|
m.data = cast[ptr UncheckedArray[float]](allocShared(bytes))
|
||||||
|
copyMem(m.data, m2.data, bytes)
|
||||||
|
|
||||||
|
proc `=sink`*(m: var MySeq, m2: MySeq) {.inline.} =
|
||||||
|
if m.data != m2.data:
|
||||||
|
if m.data != nil:
|
||||||
|
`=destroy`(m)
|
||||||
|
m.len = m2.len
|
||||||
|
m.data = m2.data
|
||||||
|
|
||||||
|
proc len*(m: MySeq): MyLen {.inline.} = m.len
|
||||||
|
|
||||||
|
proc lenx*(m: var MySeq): MyLen {.inline.} = m.len
|
||||||
|
|
||||||
|
|
||||||
|
proc `[]`*(m: MySeq; i: MyLen): float {.inline.} =
|
||||||
|
m.data[i.int]
|
||||||
|
|
||||||
|
proc `[]=`*(m: var MySeq; i: MyLen, val: float) {.inline.} =
|
||||||
|
m.data[i.int] = val
|
||||||
|
|
||||||
|
proc setTo(s: var MySeq, val: float) =
|
||||||
|
for i in 0..<s.len.int:
|
||||||
|
s.data[i] = val
|
||||||
|
|
||||||
|
proc newMySeq*(size: int, initial_value = 0.0): MySeq =
|
||||||
|
result.len = size.MyLen
|
||||||
|
if size > 0:
|
||||||
|
result.data = cast[ptr UncheckedArray[float]](createShared(float, size))
|
||||||
|
|
||||||
|
result.setTo(initial_value)
|
||||||
|
|
||||||
|
converter literalToLen*(x: int{lit}): MyLen =
|
||||||
|
x.MyLen
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
# Unique pointer implementation
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
|
||||||
|
proc `=destroy`*[T](p: var UniquePtr[T]) =
|
||||||
|
if p.val != nil:
|
||||||
|
`=destroy`(p.val[])
|
||||||
|
dealloc(p.val)
|
||||||
|
p.val = nil
|
||||||
|
|
||||||
|
proc `=`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.error.}
|
||||||
|
|
||||||
|
proc `=sink`*[T](dest: var UniquePtr[T], src: UniquePtr[T]) {.inline.} =
|
||||||
|
if dest.val != nil and dest.val != src.val:
|
||||||
|
`=destroy`(dest)
|
||||||
|
dest.val = src.val
|
||||||
|
|
||||||
|
proc newUniquePtr*[T](val: sink T): UniquePtr[T] =
|
||||||
|
result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
|
||||||
|
reset(result.val[])
|
||||||
|
result.val[] = val
|
||||||
|
|
||||||
|
converter convertPtrToObj*[T](p: UniquePtr[T]): var T =
|
||||||
|
result = p.val[]
|
||||||
|
|
||||||
|
|
||||||
|
var pu = newUniquePtr(newMySeq(5, 1.0))
|
||||||
|
echo pu.len
|
||||||
|
|
||||||
|
pu[0] = 2.0
|
||||||
|
echo pu[0], " ", pu.lenx
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue