#ifndef A18E3E17_2A80_4DBD_96CD_1CE0120A164E
#define A18E3E17_2A80_4DBD_96CD_1CE0120A164E

#include <gh_datasegment.h>
#include <stdexcept>

extern unsigned char gh_static_mem[GH_DATA_SIZE];

template <size_t addr> inline constexpr void checkMappedMemory() {
  static_assert(addr >= GH_DATA_START, "Address outside lower bound");
  static_assert(addr < GH_DATA_END, "Address outside upper bound");
}
inline uint8_t *memoryMapSafe(size_t addr) {
  if (addr < GH_DATA_START || addr > GH_DATA_END) {
    throw std::runtime_error("Address out of bounds");
  }
  return (uint8_t *)(gh_static_mem + (addr - GH_DATA_START));
}

void gh_init_data_segment();
void gh_static_mem_check();

#define GH_MEM(addr) (checkMappedMemory<addr>(), *memoryMapSafe(addr))

#endif /* A18E3E17_2A80_4DBD_96CD_1CE0120A164E */
