X Tutup
namespace Python.Runtime { using System; using System.Diagnostics.Contracts; /// /// Represents a reference to a Python object, that is tracked by Python's reference counting. /// [NonCopyable] ref struct NewReference { IntPtr pointer; [Pure] public static implicit operator BorrowedReference(in NewReference reference) => new BorrowedReference(reference.pointer); /// /// Returns wrapper around this reference, which now owns /// the pointer. Sets the original reference to null, as it no longer owns it. /// public PyObject MoveToPyObject() { if (this.IsNull()) throw new NullReferenceException(); var result = new PyObject(this.pointer); this.pointer = IntPtr.Zero; return result; } /// Moves ownership of this instance to unmanged pointer public IntPtr DangerousMoveToPointerOrNull() { var result = this.pointer; this.pointer = IntPtr.Zero; return result; } /// /// Removes this reference to a Python object, and sets it to null. /// public void Dispose() { if (this.IsNull()) { return; } Runtime.XDecref(pointer); pointer = IntPtr.Zero; } /// /// Creates from a raw pointer /// [Pure] public static NewReference DangerousFromPointer(IntPtr pointer) => new NewReference {pointer = pointer}; [Pure] internal static IntPtr DangerousGetAddress(in NewReference reference) => IsNull(reference) ? throw new NullReferenceException() : reference.pointer; [Pure] internal static bool IsNull(in NewReference reference) => reference.pointer == IntPtr.Zero; } /// /// These members can not be directly in type, /// because this is always passed by value, which we need to avoid. /// (note this in NewReference vs the usual this NewReference) /// static class NewReferenceExtensions { /// Gets a raw pointer to the Python object [Pure] public static IntPtr DangerousGetAddress(this in NewReference reference) => NewReference.DangerousGetAddress(reference); [Pure] public static bool IsNull(this in NewReference reference) => NewReference.IsNull(reference); } }
X Tutup