# mode: run
# tag: cpp, cpp11, pthread
# cython: experimental_cpp_class_def=True, language_level=2


cdef cypclass Refcounted:
    __dealloc__(self) with gil:
        print("Refcounted destroyed")


def test_consume_name():
    """
    >>> test_consume_name()
    Refcounted destroyed
    0
    """
    r0 = Refcounted()
    if Cy_GETREF(r0) != 2:
        return -1

    cdef Refcounted r1 = consume r0
    if r0 is not NULL:
        return -2
    if Cy_GETREF(r1) != 2:
        return -3

    return 0

def test_consume_iso_name():
    """
    >>> test_consume_iso_name()
    Refcounted destroyed
    0
    """
    cdef iso Refcounted r0 = recover Refcounted()

    cdef Refcounted r1 = consume r0
    if r0 is not NULL:
        return -2
    if Cy_GETREF(r1) != 2:
        return -3

    return 0

def test_consume_and_drop_name():
    """
    >>> test_consume_and_drop_name()
    Refcounted destroyed
    consumed
    0
    """
    r = Refcounted()
    if Cy_GETREF(r) != 2:
        return -1

    consume r
    print("consumed")

    if r is not NULL:
        return -2

    return 0

cdef cypclass Origin:
    Refcounted field

    __init__(self):
        self.field = Refcounted()

cdef cypclass OriginIso:
    iso Refcounted field

    __init__(self):
        self.field = recover Refcounted()

def test_consume_field():
    """
    >>> test_consume_field()
    Refcounted destroyed
    0
    """
    cdef Origin o = Origin()
    cdef Refcounted r = consume o.field
    if Cy_GETREF(r) != 2:
        return -1
    if o.field is not NULL:
        return -2

    return 0

def test_consume_and_drop_field():
    """
    >>> test_consume_and_drop_field()
    Refcounted destroyed
    consumed
    0
    """
    cdef Origin o = Origin()
    consume o.field
    print("consumed")
    if o.field is not NULL:
        return -2

    return 0

def test_consume_iso_field():
    """
    >>> test_consume_iso_field()
    consumed
    Refcounted destroyed
    0
    """
    cdef OriginIso o = OriginIso()
    cdef iso Refcounted r = consume o.field
    print("consumed")
    if o.field is not NULL:
        return -1
    return 0

def test_consume_and_drop_iso_field():
    """
    >>> test_consume_and_drop_iso_field()
    Refcounted destroyed
    consumed
    0
    """
    cdef OriginIso o = OriginIso()
    consume o.field
    print("consumed")
    if o.field is not NULL:
        return -1
    return 0

