#pragma once #ifdef BUILD_TESTING #include #endif namespace devilution { template struct SizeOf { SizeT width; SizeT height; SizeOf() = default; constexpr SizeOf(SizeT width, SizeT height) : width(width) , height(height) { } explicit constexpr SizeOf(SizeT size) : width(size) , height(size) { } bool operator==(const SizeOf &other) const { return width == other.width && height == other.height; } bool operator!=(const SizeOf &other) const { return !(*this == other); } constexpr SizeOf &operator+=(SizeT factor) { width += factor; height += factor; return *this; } constexpr SizeOf &operator-=(SizeT factor) { return *this += -factor; } constexpr SizeOf &operator*=(SizeT factor) { width *= factor; height *= factor; return *this; } constexpr SizeOf &operator*=(float factor) { width = static_cast(width * factor); height = static_cast(height * factor); return *this; } constexpr SizeOf &operator/=(SizeT factor) { width /= factor; height /= factor; return *this; } constexpr friend SizeOf operator+(SizeOf a, SizeT factor) { a += factor; return a; } constexpr friend SizeOf operator-(SizeOf a, SizeT factor) { a -= factor; return a; } constexpr friend SizeOf operator*(SizeOf a, SizeT factor) { a *= factor; return a; } constexpr friend SizeOf operator/(SizeOf a, SizeT factor) { a /= factor; return a; } #ifdef BUILD_TESTING /** * @brief Format sizes nicely in test failure messages * @param stream output stream, expected to have overloads for int and char* * @param size Object to display * @return the stream, to allow chaining */ friend std::ostream &operator<<(std::ostream &stream, const SizeOf &size) { return stream << "(width: " << size.width << ", height: " << size.height << ")"; } #endif }; using Size = SizeOf; } // namespace devilution