diff options
Diffstat (limited to 'libs/kstd')
| -rw-r--r-- | libs/kstd/include/kstd/units | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/libs/kstd/include/kstd/units b/libs/kstd/include/kstd/units new file mode 100644 index 0000000..f6dcdb1 --- /dev/null +++ b/libs/kstd/include/kstd/units @@ -0,0 +1,145 @@ +#ifndef KSTD_UNITS_HPP +#define KSTD_UNITS_HPP + +#include <compare> +#include <concepts> +#include <cstddef> + +namespace kstd +{ + + //! A basic template for strongly typed units. + template<typename ValueType, typename Tag> + struct basic_unit + { + using value_type = ValueType; + + explicit constexpr basic_unit(value_type value) noexcept + : value{value} + {} + + explicit constexpr operator value_type() const noexcept + { + return value; + } + + constexpr auto operator+(basic_unit const & other) const noexcept -> basic_unit + { + return basic_unit{value + other.value}; + } + + constexpr auto operator+=(basic_unit const & other) noexcept -> basic_unit & + { + return *this = *this + other; + } + + constexpr auto operator-(basic_unit const & other) const noexcept -> basic_unit + { + return basic_unit{value - other.value}; + } + + constexpr auto operator-=(basic_unit const & other) noexcept -> basic_unit & + { + return *this = *this - other; + } + + constexpr auto operator*(std::integral auto factor) noexcept -> basic_unit + { + return basic_unit{value * factor}; + } + + constexpr auto operator*=(std::integral auto factor) noexcept -> basic_unit + { + return *this = *this * factor; + } + + constexpr auto operator/(std::integral auto divisor) noexcept -> basic_unit + { + return basic_unit{value / divisor}; + } + + constexpr auto operator/=(std::integral auto divisor) noexcept -> basic_unit + { + return *this = *this / divisor; + } + + constexpr auto operator/(basic_unit const & other) const noexcept + { + return value / other.value; + } + + constexpr auto operator<=>(basic_unit const & other) const noexcept -> std::strong_ordering = default; + + value_type value; + }; + + template<std::integral Factor, typename ValueType, typename Tag> + constexpr auto operator*(Factor factor, basic_unit<ValueType, Tag> const & unit) noexcept + -> basic_unit<ValueType, Tag> + { + return basic_unit<ValueType, Tag>{unit.value * factor}; + } + + namespace units + { + using bytes = basic_unit<std::size_t, struct bytes_tag>; + + constexpr auto KiB(std::size_t value) noexcept -> bytes + { + return bytes{value * 1024}; + } + + constexpr auto MiB(std::size_t value) noexcept -> bytes + { + return bytes{value * 1024 * 1024}; + } + + constexpr auto GiB(std::size_t value) noexcept -> bytes + { + return bytes{value * 1024 * 1024 * 1024}; + } + + template<typename ValueType> + constexpr auto operator+(ValueType * pointer, bytes offset) -> ValueType * + { + return pointer + offset.value; + } + + } // namespace units + + namespace units_literals + { + constexpr auto operator""_B(unsigned long long value) noexcept -> units::bytes + { + return units::bytes{value}; + } + + constexpr auto operator""_KiB(unsigned long long value) noexcept -> units::bytes + { + return units::KiB(value); + } + + constexpr auto operator""_MiB(unsigned long long value) noexcept -> units::bytes + { + return units::MiB(value); + } + + constexpr auto operator""_GiB(unsigned long long value) noexcept -> units::bytes + { + return units::GiB(value); + } + + } // namespace units_literals + + template<typename ValueType> + constexpr auto object_size(ValueType const &) -> units::bytes + { + return units::bytes{sizeof(ValueType)}; + } + + template<typename T> + constexpr auto type_size = units::bytes{sizeof(T)}; + +} // namespace kstd + +#endif
\ No newline at end of file |
