-
-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rename newSeqUninit
in order to avoid conflicts with upstream
#591
Conversation
I'm confused as to why we cannot keep the |
It seems that
newSeqUninit .
But |
Ohh, now I see. My confusion was that I assumed this PR here nim-lang/Nim#22586 was merged already and based on Mamy's PR #591 I further assumed it was a drop in replacement for our custom one. And yes, the What is the reason though for the restriction of the stdlib version to types that can be memcopied? The code currently doesn't do anything that seems to rely on that, no? I don't have a strong opinion on the name, |
I think type bounding operations requires types to be initialized preemptively. For instance, destructors or other type bounding operations might not work properly since var x = newSeqUninit[Ref](10) |
But then what does our current code do? Or in other words, if I currently write: type
Foo = ref object
x: float
var x = newSeqOfCap[Foo](10)
x.setLen(10) wouldn't that be undefined behavior if I understand you correctly? |
var x = newSeqOfCap[Foo](10)
x.setLen(10) so it is just another way of writing proc setLen[T](s: var seq[T], newlen: Natural) {.nodestroy.} =
{.noSideEffect.}:
if newlen < s.len:
shrink(s, newlen)
else:
let oldLen = s.len
if newlen <= oldLen: return
var xu = cast[ptr NimSeqV2[T]](addr s)
if xu.p == nil or (xu.p.cap and not strlitFlag) < newlen:
xu.p = cast[typeof(xu.p)](prepareSeqAddUninit(oldLen, xu.p, newlen - oldLen, sizeof(T), alignof(T)))
xu.len = newlen
for i in oldLen..<newlen:
xu.p.data[i] = default(T) |
Ah, I see. But then that implies our implementation, So we need to merge the logic for func newSeqUninit2*[T](len: Natural): seq[T] {.inline.} =
## Creates an uninitialzed seq if the type is plain old data. Falls back
## to a normal `newSeq` call for any non trivial data type.
when supportsCopyMem(T):
result = newSeqUninit[T](len)
else:
result = newSeq[T](len) so that at least we get the desired behavior for mem copyable types. |
Indeed, I agree. It also needs to be combined with |
Cool! Will you make the change or should I do it? |
Feel free to take over this PR, or do it in the following PRs. Thank you in advance! |
Sorry for the delay. Will take care of this soon. Yesterday was a bit stressful. :) |
I think we can just delete newSeqUninit in Arraymancer actually, with the Laser PR, the storage for POD datatypes changed to ptr UncheckedArray: so CPU storage is only used for ref types and strings but the current impl will likely cause issues with destructors and we aren't optimizing for strings/ref types. In fact, CpuStorage uses Arraymancer/src/arraymancer/laser/tensor/datatypes.nim Lines 86 to 101 in 875ee6b
and newSeqUninit only for intermediate sequences when interfaces with C libraries like Lapack for which the stdlib would be a drop-in replacement. https://github.com/search?q=repo%3Amratsim%2FArraymancer%20newSequninit&type=code |
Good point actually. |
ref nim-lang/Nim#22739
It's a private function so it shouldn't affect backwards compatibility.