## Function: tp_dict_t
## Creates a new dictionary object.
## *Note* If you use <tp_setmeta> on the dictionary, you have to use <tp_getraw> to
## access the "raw" dictionary again.
## Returns:
## The newly created dictionary.

def tp_dict_nt(TP) ->tp_obj:
	tp_obj r = {TP_DICT};
	r.dict.val = tpd_dict_new(tp)
	r.type.magic = 0
	r.obj.info->meta = tp->_dict_meta
	return r

def tp_dict_t(TP) ->tp_obj:
	return tp_track(tp, tp_dict_nt(tp))


def tp_dict(TP) ->tp_obj:
	return tp_track(tp, tp_dict_nt(tp))

def tp_extern_interface(TP) ->tp_obj:
	tp_obj r = {TP_INTERFACE};
	r.dict.val = tpd_dict_new(tp)
	r.obj.info->meta = tp_None
	r.type.magic = TP_MODULE_EXTERNAL_MAGIC
	return r

def tp_extern_interface() ->tp_obj:
	tp_obj r = {TP_INTERFACE};
	r.dict.val = tpd_dict_new()
	r.obj.info->meta = tp_None
	r.type.magic = TP_MODULE_EXTERNAL_MAGIC
	return r


def tp_interface_nt(TP) ->tp_obj:
	tp_obj r = {TP_INTERFACE};
	r.dict.val = tpd_dict_new(tp)
	r.obj.info->meta = tp_None
	return r


def tp_interface_t(TP) ->tp_obj:
	return tp_track(tp, tp_interface_nt(tp))


def tp_object_nt(TP) ->tp_obj:
	tp_obj r = {TP_OBJECT};
	r.dict.val = tpd_dict_new(tp)
	r.obj.info->meta = tp_None
	return r


def tp_object_t(TP) ->tp_obj:
	return tp_track(tp, tp_object_nt(tp))


def tp_dict_from_items(TP, int n, tp_obj * argv) ->tp_obj:
	tp_obj r = tp_dict_t(tp)
	for (int i=0; i<n; i++):
		tp_set(tp, r, argv[i*2], argv[i*2+1])
	return r

def tp_dict_from_items_nt(TP, int n, tp_obj * argv) ->tp_obj:
	tp_obj r = tp_dict_nt(tp)
	r.type.magic = TP_SKIP_GC_MAGIC
	for (int i=0; i<n; i++):
		tp_set(tp, r, argv[i*2], argv[i*2+1])
	return r


def tp_interface_from_items(TP, int n, tp_obj * argv) ->tp_obj:
	tp_obj r = tp_interface_t(tp)
	for (int i=0; i<n; i++):
		tp_set(tp, r, argv[i*2], argv[i*2+1])
	return r

def tp_interface_with_name(TP, tp_obj name) ->tp_obj:
	tp_obj r = tp_interface_t(tp)
	if defined(DEBUG):
		tp_set(tp, r, tp_string_tiny_atom("__name__"), name)
	return r

def tp_interface_with_name_and_base(TP, tp_obj name, tp_obj base) ->tp_obj:
	tp_obj r = tp_interface_t(tp)
	if defined(DEBUG):
		tp_set(tp, r, tp_string_tiny_atom("__name__"), name)
		tp_set(tp, r, tp_string_tiny_atom("__base__"), base)
	r.dict.val->meta = base
	return r


def tp_dict_get(TP, tp_obj self, tp_obj k) ->tp_obj:
	int hash = tp_hash(tp, k)
	int n = tpd_dict_hashfind(tp, self.dict.val, hash, k)
	if n < 0:
		print(self)
		print("key not found: ")
		print(k)
		print(" hash: ")
		print(hash)
		//tp_raise(tp_None, message);
		throw "ERROR in tp_dict.cpp:tp_dict_get KeyError"
	return tpd_dict_get(tp, self.dict.val, n)


def tp_dict_del(TP, tp_obj self, tp_obj k):
	int n = tpd_dict_hashfind(tp, self.dict.val, tp_hash(tp, k), k)
	if n < 0:
		##char * str = tp_cstr(tp, k)
		##tp_obj message = tp_printf(tp, "tpd_dict_del KeyError: %s", str)
		print(k)
		##tp_free(tp, str)
		##tp_raise(, message);
		throw "ERROR in tp_dict.cpp:tp_dict_del KeyError"
	tpd_dict_del(tp, self.dict.val, n)


def tp_dict_set(TP, tp_obj self, tp_obj k, tp_obj v):
	tpd_dict_hashsetx(tp, self.dict.val, tp_hash(tp, k), k, v)
	tp_grey(tp, k)
	tp_grey(tp, v)


def tp_dict_copy(TP, tp_obj rr) ->tp_obj:
	tp_obj obj = {rr.type.type_id};
	tpd_dict *o = rr.dict.val
	tpd_dict *r = tpd_dict_new(tp)
	*r = *o
	r->gci = 0
	r->items = (tpd_item*) tp_malloc(tp, sizeof(tpd_item)*o->alloc)
	memcpy(r->items, o->items, sizeof(tpd_item)*o->alloc)
	obj.dict.val = r
	obj.type.magic = rr.type.magic
	obj.type.type_id = rr.type.type_id
	return obj

