#pragma once #include "deimos/core/std.h" #include "deimos/core/gsl.h" #define deimos_StaticAssert(...) static_assert(__VA_ARGS__, #__VA_ARGS__) #define deimos_NO_COPY(TYPE) \ TYPE(const TYPE&) = delete; \ TYPE& operator=(const TYPE&) = delete; #define deimos_NO_MOVE(TYPE) \ TYPE(TYPE&&) = delete; \ TYPE& operator=(TYPE&&) = delete; #define deimos_NO_COPY_MOVE(TYPE) \ deimos_NO_COPY(TYPE); \ deimos_NO_MOVE(TYPE); #define deimos_DEFAULT_COPY(TYPE) \ TYPE(const TYPE&) = default; \ TYPE& operator=(const TYPE&) = default; #define deimos_DEFAULT_MOVE(TYPE) \ TYPE(TYPE&&) = default; \ TYPE& operator=(TYPE&&) = default; #define deimos_DEFAULT_COPY_MOVE(TYPE) \ deimos_DEFAULT_COPY(TYPE); \ deimos_DEFAULT_MOVE(TYPE); namespace deimos { struct uint128_t { uint64_t high; uint64_t low; constexpr bool operator==(const uint128_t& other) const = default; }; struct SourceLocation { gsl::czstring file; int32_t line; constexpr SourceLocation( // NOLINT gsl::czstring file_ = __builtin_FILE(), int32_t line_ = __builtin_LINE()) : file{file_}, line{line_} {} }; template class Span { T* m_begin = nullptr; int64_t m_size = 0; public: constexpr Span() = default; ~Span() = default; deimos_DEFAULT_COPY_MOVE(Span); template requires std::convertible_to constexpr Span(const Span& other) : // NOLINT m_begin{other.begin()}, m_size{other.size()} {} constexpr T* begin() const { return m_begin; } constexpr T* end() const { return m_begin + m_size; } constexpr int64_t size() const { return m_size; } }; } // namespace deimos