#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "tools.h"

#ifndef NDEBUG
	static void* const CANARY_VALUE = (void*)0xCAFEBABACAFEBABA;
#endif

struct gcpointer_t;
struct gc_object_header;

struct gc_object_header
{
	#ifndef NDEBUG
		void* canary_start;
	#endif

	size_t		size;
	gcpointer_t* 	root_chain;
	gcpointer_t*	type_chain;
	gc_object_header*	forward;
	bool			is_forwarded;

	#ifndef NDEBUG
		void* canary_end;
	#endif
};

void ctor(gc_object_header* const this, size_t size);
void copy_ctor(gc_object_header* const this, const gc_object_header* const other);

static inline gc_object_header* placement_ctor(void* address, size_t size)
{
	gc_object_header* const this = (gc_object_header* const) address;
	ctor(this, size);
	return this;
}

static inline gc_object_header* placement_copy_ctor(void* address, const gc_object_header* const other)
{
	gc_object_header* const this = (gc_object_header* const) address;
	copy_ctor(this, other);
	return this;
}

#ifndef NDEBUG
	bool is_valid(const gc_object_header* const this);
#endif
