SSX3LobbyServer/lib/base/types.hpp

146 lines
3.2 KiB
C++

//! Core types and includes
#pragma once
#include <cstdint>
#include <memory>
// these are in the global namespace since most libraries
// won't try defining anything like this in the global namespace
// (and I'd like these types to be used globally a lot more anyways)
using u8 = std::uint8_t;
using i8 = std::int8_t;
using u16 = std::uint16_t;
using i16 = std::int16_t;
using u32 = std::uint32_t;
using i32 = std::int32_t;
using u64 = std::uint64_t;
using i64 = std::int64_t;
using usize = std::size_t;
using isize = std::intptr_t;
// Include the impl library's ASIO config, since we pull it in
#include <impl/asio_config.hpp>
namespace boost::json {}
namespace boost::urls {}
namespace burl = boost::urls;
// Namespace aliases, these are used throughout the project
namespace bsys = boost::system;
namespace json = boost::json;
namespace std::filesystem {}
namespace fs = std::filesystem;
namespace base {
namespace detail {
template <class T>
struct Point {
T x;
T y;
};
template <class T>
struct Size {
T width;
T height;
constexpr usize Linear() const { return width * height; }
};
template <class T>
struct Rect {
T x;
T y;
T width;
T height;
// constexpr Rect(T x, T y, T w, T h) : x(x), y(y), width(w), height(h) {}
// constexpr Rect() = default;
// constexpr explicit Rect(Size<T> size) : x(0), y(0), width(size.width), height(size.height) {}
/**
* Get the origin coordinate as a point.
* \return a Point<T> with the origin.
*/
constexpr auto GetOrigin() const { return Point<T> { .x = x, .y = y }; }
/**
* Get the size of this rect.
* \return a Point<T> which contains the calculated size of the rect
*/
constexpr auto GetSize() const { return Size<T> { .width = width, .height = height }; }
constexpr bool InBounds(const Rect& other) {
if(x < other.x || x + other.width > other.x + other.width)
return false;
if(y < other.y || x + other.height > other.y + other.height)
return false;
return true;
}
// more methods.
};
} // namespace detail
union Pixel {
u32 raw;
/// color accessors
struct {
u8 r;
u8 g;
u8 b;
u8 a;
};
constexpr static Pixel FromRgb565(u16 pixel) {
return Pixel { .r = static_cast<u8>(((pixel & 0xF800) >> 11) << 3),
.g = static_cast<u8>(((pixel & 0x7E0) >> 5) << 2),
.b = static_cast<u8>((pixel & 0x1F) << 3),
.a = 255 };
}
};
using detail::Point;
using detail::Rect;
using detail::Size;
template <class T>
using Ref = std::shared_ptr<T>;
template <class T, class Deleter = std::default_delete<T>>
using Unique = std::unique_ptr<T, Deleter>;
template <typename... Ts>
struct OverloadVisitor : Ts... {
using Ts::operator()...;
};
template <class... Ts>
OverloadVisitor(Ts...) -> OverloadVisitor<Ts...>;
template <class T, auto* Free>
struct UniqueCDeleter {
constexpr void operator()(T* ptr) {
if(ptr)
Free(reinterpret_cast<void*>(ptr));
}
};
/// Use this for wrapping a C-allocated memory block. The defaults here assume
/// you're wrapping data allocated by malloc(), however, any deallocator pattern
/// is basically supported.
template <class T, auto Free = std::free>
using CUnique = base::Unique<T, UniqueCDeleter<T, Free>>;
} // namespace base