#pragma once

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

#include "tools.h"
#include "globals.h"

static inline bool gc_is_aligned(void* address)
{
	return (((intptr_t)address) & (~OBJECT_PTR_MASK)) == 0;
}

static inline void* gc_get_aligned_ptr(void* address)
{
	return (void*)(((intptr_t)address) & (OBJECT_PTR_MASK));
}

static inline void* gc_write_aligned_ptr(void** reference, void* address)
{
	size_t ref_last_bits = ((intptr_t)*reference) & (~OBJECT_PTR_MASK);

      size_t new_val = ((intptr_t)address) & OBJECT_PTR_MASK;

      (*reference) = (void*)(new_val | ref_last_bits);

	return *reference;
}

static inline size_t gc_compute_size(size_t size)
{
	size_t word_size = ((size - 1) / OBJECT_ALLIGNMENT) + 1;
	size_t ret = word_size * OBJECT_ALLIGNMENT;

	check(ret >= size);
	check((ret % OBJECT_ALLIGNMENT) == 0);
	check( ((size % OBJECT_ALLIGNMENT) != 0) || (ret == size) );

	return ret;
}
