2024-09-15 22:31:54 +02:00

95 lines
2.6 KiB
C++

#pragma once
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED)
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED 1
#include <cstdint>
#include <optional>
#include <span>
#include <stdexcept>
#include <utility>
#include <vector>
#include <mijin/debug/assert.hpp>
#include <mijin/util/bitflags.hpp>
#include <SDL3/SDL.h>
#include <mijin/util/winundef.hpp>
namespace sdlpp
{
template<typename THandle, typename TConcrete>
class Base
{
protected:
THandle* mHandle = nullptr;
protected:
Base() noexcept = default;
explicit Base(THandle* handle) noexcept : mHandle(handle) {}
Base(const Base&) noexcept = default;
Base(Base&& other) noexcept : mHandle(std::exchange(other.mHandle, nullptr)) {}
Base& operator=(const Base&) noexcept = default;
Base& operator=(Base&& other) noexcept
{
if (this != &other)
{
static_cast<TConcrete&>(*this).destroy();
mHandle = std::exchange(other.mHandle, nullptr);
}
return *this;
}
public:
~Base() noexcept
{
static_cast<TConcrete&>(*this).destroy();
}
auto operator<=>(const Base& other) const noexcept = default;
operator THandle*() const noexcept { return mHandle; }
explicit operator bool() const noexcept
{
return mHandle != nullptr;
}
bool operator!() const noexcept
{
return mHandle == nullptr;
}
};
template<typename THandle, typename TConcrete>
class BaseWithDevice : public Base<THandle, TConcrete>
{
protected:
SDL_GPUDevice* mDevice = nullptr;
protected:
BaseWithDevice() noexcept = default;
BaseWithDevice(THandle* handle, SDL_GPUDevice* device) noexcept : Base<THandle, TConcrete>(handle), mDevice(device) {}
BaseWithDevice(BaseWithDevice&& other) noexcept : Base<THandle, TConcrete>(std::exchange(other.mHandle, nullptr)),
mDevice(std::exchange(other.mDevice, nullptr)){}
BaseWithDevice& operator=(BaseWithDevice&& other) noexcept
{
if (this != &other)
{
mDevice = std::exchange(other.mDevice, nullptr);
Base<THandle, TConcrete>::operator=(std::move(other));
}
return *this;
}
public:
BaseWithDevice(const BaseWithDevice&) = delete;
BaseWithDevice& operator=(const BaseWithDevice&) = delete;
auto operator<=>(const BaseWithDevice& other) const noexcept = default;
};
class SDLError : public std::runtime_error
{
public:
SDLError() : std::runtime_error(SDL_GetError()) {}
};
} // namespace sdlpp
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED)