"""
Template for maps

WARNING: DO NOT edit .pxi FILE directly, .pxi is generated from .pxi.in
"""


include "map_init.pxi"

{{py:

# map_name, name, key_type, val_type
map_types       = [('Int64toInt64', 'int64toint64', 'int64_t', 'int64_t'),
                   ('Int64toFloat64', 'int64tofloat64', 'int64_t', 'float64_t'),
                   ('Float64toInt64', 'float64toint64', 'float64_t', 'int64_t'),
                   ('Float64toFloat64', 'float64tofloat64', 'float64_t', 'float64_t'),
                   ('Int32toInt32', 'int32toint32', 'int32_t', 'int32_t'),
                   ('Int32toFloat32', 'int32tofloat32', 'int32_t', 'float32_t'),
                   ('Float32toInt32', 'float32toint32', 'float32_t', 'int32_t'),
                   ('Float32toFloat32', 'float32tofloat32', 'float32_t', 'float32_t'),
                  ]
}}


{{for map_name, name, key_type, val_type in map_types}}

cdef extern from *:

    ctypedef struct kh_{{name}}map_t:
        khint_t n_buckets, size, n_occupied, upper_bound
        uint32_t *flags
        {{key_type}} *keys
        {{val_type}} *vals  

    kh_{{name}}map_t* kh_init_{{name}}map() nogil
    void kh_destroy_{{name}}map(kh_{{name}}map_t*) nogil
    void kh_clear_{{name}}map(kh_{{name}}map_t*) nogil
    khint_t kh_get_{{name}}map(kh_{{name}}map_t*, {{key_type}}) nogil
    void kh_resize_{{name}}map(kh_{{name}}map_t*, khint_t) nogil
    khint_t kh_put_{{name}}map(kh_{{name}}map_t*, {{key_type}}, int* result) nogil
    void kh_del_{{name}}map(kh_{{name}}map_t*, khint_t) nogil

    #specializing "kh_exist"-macro 
    bint kh_exist_{{name}}map "kh_exist" (kh_{{name}}map_t*, khint_t) nogil

cdef class {{map_name}}Map:
    cdef kh_{{name}}map_t *table
    cdef bint for_int

    cdef bint contains(self, {{key_type}} key) except *
    cdef {{map_name}}MapIterator get_iter(self, int view_type)
    cdef khint_t size(self) 
    cpdef void cput(self, {{key_type}} key, {{val_type}} value) except *
    cpdef {{val_type}} cget(self, {{key_type}} key) except *
    cpdef void discard(self, {{key_type}} key) except *
    

cdef struct {{name}}_key_val_pair:
    {{key_type}} key
    {{val_type}} val


cdef class {{map_name}}MapIterator:
    cdef khint_t   it
    cdef int       view_type
    cdef {{map_name}}Map  parent

    cdef bint has_next(self) except *
    cdef {{name}}_key_val_pair next(self) except *
    cdef void __move(self) except *


cdef class {{map_name}}MapView:
    cdef {{map_name}}Map  parent
    cdef int       view_type

    cdef {{map_name}}MapIterator get_iter(self)


cpdef {{map_name}}Map {{map_name}}Map_from_buffers({{key_type}}[:] keys, {{val_type}}[:] vals, double size_hint=*)

cpdef size_t {{map_name}}Map_to({{map_name}}Map map, {{key_type}}[:] keys, {{val_type}}[:] vals, bint stop_at_unknown=*, {{val_type}} default_value=*) except *



# other help functions:
cpdef void swap_{{name}}map({{map_name}}Map a, {{map_name}}Map b) except *
cpdef {{map_name}}Map copy_{{name}}map({{map_name}}Map s)
cpdef bint are_equal_{{name}}map({{map_name}}Map a, {{map_name}}Map b) except *
cpdef void update_{{name}}map({{map_name}}Map a, {{map_name}}Map b) except *

{{endfor}}


##TODO: unify with others


cdef extern from *:

    ctypedef struct kh_pyobjectmap_t:
        khint_t n_buckets, size, n_occupied, upper_bound
        uint32_t *flags
        pyobject_t *keys
        pyobject_t *vals  

    kh_pyobjectmap_t* kh_init_pyobjectmap() nogil
    void kh_destroy_pyobjectmap(kh_pyobjectmap_t*) nogil
    void kh_clear_pyobjectmap(kh_pyobjectmap_t*) nogil
    khint_t kh_get_pyobjectmap(kh_pyobjectmap_t*, pyobject_t) nogil
    void kh_resize_pyobjectmap(kh_pyobjectmap_t*, khint_t) nogil
    khint_t kh_put_pyobjectmap(kh_pyobjectmap_t*, pyobject_t, int* result) nogil
    void kh_del_pyobjectmap(kh_pyobjectmap_t*, khint_t) nogil

    #specializing "kh_exist"-macro 
    bint kh_exist_pyobjectmap "kh_exist" (kh_pyobjectmap_t*, khint_t) nogil


cdef class PyObjectMap:
    cdef kh_pyobjectmap_t *table

    cdef bint contains(self, pyobject_t key) except *
    cdef PyObjectMapIterator get_iter(self, int view_type)
    cdef khint_t size(self) 
    cpdef void cput(self, object key, object value) except *
    cpdef object cget(self, object key)
    cpdef void discard(self, object key) except *
    

cdef struct pyobject_key_val_pair:
    pyobject_t key
    pyobject_t val


cdef class PyObjectMapIterator:
    cdef khint_t   it
    cdef int       view_type
    cdef PyObjectMap  parent

    cdef bint has_next(self) except *
    cdef pyobject_key_val_pair next(self) except *
    cdef void __move(self) except *

cdef class PyObjectMapView:
    cdef PyObjectMap  parent
    cdef int       view_type

    cdef PyObjectMapIterator get_iter(self)

cpdef PyObjectMap PyObjectMap_from_buffers(object[:] keys, object[:] vals, double size_hint=*)

cpdef size_t PyObjectMap_to(PyObjectMap map, object[:] keys, object[:] vals, bint stop_at_unknown=*, object default_value=*) except *

# other help functions:
cpdef void swap_pyobjectmap(PyObjectMap a, PyObjectMap b) except *
cpdef PyObjectMap copy_pyobjectmap(PyObjectMap s)
cpdef bint are_equal_pyobjectmap(PyObjectMap a, PyObjectMap b) except *
cpdef void update_pyobjectmap(PyObjectMap a, PyObjectMap b) except *





