Why is OwnedPointer not Copyable?
It doesn’t make sense because it’s impossible to use OwnedPointer with List, which requires Copyable.
Why is OwnedPointer not Copyable?
It doesn’t make sense because it’s impossible to use OwnedPointer with List, which requires Copyable.
Copyable should be a conditional trait on List here, so you should be able to do this on the latest version of mojo. What version of mojo are you on? This is a very recent change. I haven’t personally tested this behavior since its in a very recent mojo version. However if I understand this correctly, OwnedPointer should work with List in the latest versions. I think you need to make sure you move the pointer into/out of the list though (use list.append(ptr^)). This also should work with Move-only types btw now.
With regard to OwnedPointer. Lets say you have object Foo and OwnedPointer A that owns Foo. If you copy A as OwnedPointer B, you would have 2 pointers saying they own Foo which isn’t good since now they’re both lying. Foo in this case it not actually owned, but shared. Thus the reason OwnedPointer isn’t copyable.
Note: If you can’t move an ownedpointer into/out of List, while on the latest mojo version that has the above change, id consider that a bug in the stdlib.
I see that conditional conformance for lists works now, although there are still some ergonomic issues. To be said, I am not asking for OwnedPointer to be a shared pointer in the form of ArcPointer, but rather for it to have a copy constructor similar to List backed by a new allocation.
- init(OwnedPointer[T], *, other: OwnedPointer[T])
+ init(OwnedPointer[T], *, copy: OwnedPointer[T])
This would require the size of the allocated memory to be stored in pointer, right? I am not sure if this aligns with what a pointer typically is. After all, this is just a pointer to memory and not the instance responsible for is management.
The size of the OwnedPointer allocation is size_of(T/Pointee) . It is known, because otherwise it would not be possible to call the constructor or destructor, i.e. allocate or deallocate size_of(T) bytes on the heap.
You don’t know what a smart pointer is, don’t you?
Technically, List is also a smart pointer, but because it has some metadata attached to it, it’s called a collection.
List is a smart pointer of size_of(T) * capacity bytes.
I could use List with a capacity and length of 1, the problem is just that it would increase the stack size of BinaryExpression from 17 bytes to 49 bytes without padding.
The problem is not that the copy constructor does not exist, but rather that it does not conform to Copyable.
I would rather just rename the constructor.
def __init__[_T: Copyable](out self: OwnedPointer[_T]) *, other: OwnedPointer[_T]) ...
def __init__(out self, *, copy: Self) where conforms_to(Self.T, Copyable): ...
# now conforms to Copyable and generic code works
# does not conform to Copyable unfortunately
struct BinaryExpression(Movable):
var lhs: OwnedPointer[Expression]
var rhs: OwnedPointer[Expression]
var op: TokenType
´´´