#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include inline constexpr std::nullopt_t None{std::nullopt}; template using Option = std::optional; template using Variant = std::variant; template using UniquePtr = std::unique_ptr; struct Error : public std::runtime_error { using std::runtime_error::runtime_error; }; struct EnumError : public Error {using Error::Error;}; struct FileFormatError : public Error {using Error::Error;}; struct FileSystemError : public Error {using Error::Error;}; struct UnimplementedError : public Error {using Error::Error;}; struct MemoryStreamBuf : public std::streambuf { MemoryStreamBuf(char *base, std::size_t size) { setg(base, base, base + size); } }; struct IMemoryStream : public virtual MemoryStreamBuf, public std::istream { IMemoryStream(char *base, std::size_t size) : MemoryStreamBuf{base, size}, std::istream(static_cast(this)) { } IMemoryStream(char const *base, std::size_t size) : IMemoryStream{const_cast(base), size} { } IMemoryStream(QByteArray &bytes) : IMemoryStream{bytes.data(), std::size_t(bytes.size())} { } IMemoryStream(QByteArray const &bytes) : IMemoryStream{bytes.data(), std::size_t(bytes.size())} { } }; static inline QString trMain(char const *sourceText, char const *disambiguation = nullptr, int n = -1) { return QCoreApplication::translate("main", sourceText, disambiguation, n); } static inline quint8 readByte(std::istream &st) { char b; st.read(&b, 1); return quint8(b); } template static inline T readLE(std::istream &st) { std::array b; st.read(b.data(), b.size()); return qFromLittleEndian(b.data()); } template static inline T readBE(std::istream &st) { std::array b; st.read(b.data(), b.size()); return qFromBigEndian(b.data()); } template static inline std::array readBytes(std::istream &st) { std::array b; st.read(b.data(), b.size()); return std::move(b); } static inline std::ifstream openReadBin(std::filesystem::path path) { return std::ifstream{path, std::ios_base::in | std::ios_base::binary}; } template static inline std::string ntbsToString(std::array const &ntbs) { std::string str; auto zero = std::find(ntbs.cbegin(), ntbs.cend(), '\0'); std::copy(ntbs.cbegin(), zero, std::back_inserter(str)); return str; } template static inline char const *enumToString(T const t) { return QMetaEnum::fromType().valueToKey(int(t)); } template static inline int enumMax() { return QMetaEnum::fromType().keyCount(); } template static inline T orThrow(Option opt, Error err) { if(opt) { return *opt; } else { throw err; } } static inline QDebug operator<<(QDebug debug, std::string const &t) { debug << QString::fromStdString(t); return debug; } template static inline QDebug operator<<(QDebug debug, Variant const &t) { std::visit([&](auto &&arg) {debug << arg;}, t); return debug; } template static inline QDebug operator<<(QDebug debug, Option const &t) { if(t) { debug << *t; } else { debug << "None"; } return debug; } template static inline QDebug operator<<(QDebug debug, UniquePtr const &t) { if(t) { debug << *t; } else { debug << "nullptr"; } return debug; } // EOF