#ifndef KImem
#define KImem
#include <k/type.h>
#include <k/internal.egroup.h>
#ifndef KFclean
#	define Kmsz(e) ( sizeof (e) / sizeof (e) [0] )
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef enum kmcond {
	kmcond_ok = kmcond_id,
	kmcond_unnecessary,
	kmcond_fail,
	kmcond_unhandled,
	kmcond_mismatch,
	kmcond_bad_address,
	kmcond_bad_lock,
	kmcond_bad_size,
	kmcond_no_room,
	kmcond_too_many,
	/* when something truly should
	 * never happen: */
	kmcond_fail_assert,
} kmcond;
typedef enum kmkind {
	kmkind_none,
	kmkind_broken,
	kmkind_linear,
	kmkind_heap,
	kmkind_pool,
	kmkind_ref,
	kmkind_tree
} kmkind;
typedef enum kmshred {
	kmshred_yes,
	kmshred_no
} kmshred;
typedef struct kmbox {
	kmkind kind;
	sz size;
	kmshred shred;
} kmbox;
typedef struct kmcell {
	kmbox header;
	sz refs;
	struct kmcell* src;
} kmcell;
typedef struct kmnode {
	kmbox header;
	struct kmnode* origin,
		         * branch,
				 * next,
				 * prev;
} kmnode;
typedef struct kmptr {
	kmkind kind;
	kmshred shred;
	void* ref;
} kmptr;
/* this struct is used to return both a pointer
 * and an error value at the same time. */
typedef struct kmres {
	kmcond cond;
	union {
		void* raw;
		kmptr ptr;
	};
} kmres;
/* heap functions */
kmres  kmheapa (sz);
kmres  kmheapo (sz);
kmcond kmheapf (void*);
kmres  kmlina  (sz);
void*  kmlini  (void);
/* generic functions */
kmcond kmfree(kmptr);
void kmzero(void*,sz);
void kmozero(kmptr);
#ifdef __cplusplus
}
#endif
#endif