include "sage/ext/interrupt.pxi"  # ctrl-c interrupt block support
include "sage/ext/stdsage.pxi"
include "sage/ext/python.pxi"
from cpython.list cimport *
from cpython.number cimport *
from cpython.int cimport *
include "sage/ext/python_rich_object.pxi"

#def time_alloc_list(n):
    #"""
    #Allocate n a list of n Sage integers using PY_NEW.
    #(Used for timing purposes.)

    #EXAMPLES:
       #sage: from sage.rings.integer import time_alloc_list
       #sage: v = time_alloc_list(100)
    #"""
    #cdef int i
    #l = []
    #for i from 0 <= i < n:
        #l.append(PY_NEW(Integer))

    #return l

#def time_alloc(n):
    #"""
    #Time allocating n integers using PY_NEW.
    #Used for timing purposes.

    #EXAMPLES:
       #sage: from sage.rings.integer import time_alloc
       #sage: time_alloc(100)
    #"""
    #cdef int i
    #for i from 0 <= i < n:
        #z = PY_NEW(Integer)

#def pool_stats():
    #"""
    #Returns information about the Integer object pool.

    #EXAMPLES:
        #sage: from sage.rings.integer import pool_stats
        #sage: pool_stats()            # random-ish output
        #Used pool 0 / 0 times
        #Pool contains 3 / 100 items
    #"""
    #return ["Used pool %s / %s times" % (use_pool, total_alloc),
            #"Pool contains %s / %s items" % (integer_pool_count, integer_pool_size)]

cdef hook_tp_functions(object global_dummy, allocfunc tp_alloc, newfunc tp_new, freefunc tp_free, destructor tp_dealloc, bint useGC):
    """
    Initialize the fast integer creation functions.
    """

    cdef long flag

    cdef PyObject* o = <PyObject*>global_dummy
    cdef RichPyTypeObject* t = <RichPyTypeObject*>o.ob_type

    # Make sure this never, ever gets collected.
    # This is not necessary for cdef'ed variables as the global
    # dummy integer, as such objects do not get automatically collected.
    # In fact there is no obvious reason to prevent collection when Sage quits
    # and we are certain no further call to the allocation function will be
    # made; so this could be removed when the code is clean enough.
    Py_INCREF(global_dummy)

    # By default every object created in Pyrex is garbage
    # collected. This means it may have references to other objects
    # the Garbage collector has to look out for. We remove this flag
    # as the only reference an Integer has is to the global Integer
    # ring. As this object is unique we don't need to garbage collect
    # it as we always have a module level reference to it. If another
    # attribute is added to the Integer class this flag removal so as
    # the alloc and free functions may not be used anymore.
    # This object will still be reference counted.
    if not useGC:
        flag = Py_TPFLAGS_HAVE_GC
        t.tp_flags = <long>(t.tp_flags & (~flag))

    # Finally replace the functions called when an Integer needs
    # to be constructed/destructed.
    t.tp_new = tp_new
    t.tp_dealloc = tp_dealloc
