#pragma once

#include <cstddef>
#include <cstdint>
#include <limits>

using uint8  = uint8_t;
using uint16 = uint16_t;
using uint32 = uint32_t;
using uint64 = uint64_t;

using int8  = int8_t;
using int16 = int16_t;
using int32 = int32_t;
using int64 = int64_t;

using Byte = std::byte;

using size_t  = std::size_t;
using index_t = size_t;

struct ByteBuffer
{
    Byte*  Data;
    size_t Size;
};

using ptrdiff_t = decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr));

using FunctionPtr = auto (*)(void) -> void;

// Limits
template <typename Type>
consteval Type MaxValueOf()
{
    return std::numeric_limits<Type>::max();
}
constexpr uint8  uint8Max  = MaxValueOf<uint8>();
constexpr uint16 uint16Max = MaxValueOf<uint16>();
constexpr uint32 uint32Max = MaxValueOf<uint32>();
constexpr uint64 uint64Max = MaxValueOf<uint64>();

constexpr int8  int8Max  = MaxValueOf<int8>();
constexpr int16 int16Max = MaxValueOf<int16>();
constexpr int32 int32Max = MaxValueOf<int32>();
constexpr int64 int64Max = MaxValueOf<int64>();

#define Kilobytes(value) value * 1024
#define Megabytes(value) Kilobytes(value) * 1024
