diff options
Diffstat (limited to 'libs/kstd')
| -rw-r--r-- | libs/kstd/kstd/units.hpp | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/libs/kstd/kstd/units.hpp b/libs/kstd/kstd/units.hpp index e3868aa7..61224336 100644 --- a/libs/kstd/kstd/units.hpp +++ b/libs/kstd/kstd/units.hpp @@ -2,6 +2,8 @@ #define KSTD_UNITS_HPP #include <kstd/bits/basic_unit.hpp> +#include <kstd/result.hpp> +#include <kstd/system_error.hpp> #include <concepts> #include <cstddef> @@ -11,6 +13,8 @@ namespace kstd using bytes = basic_unit<std::size_t, struct bytes_tag>; + using offset = basic_unit<std::ptrdiff_t, struct byte_offset_tag>; + // NOLINTNEXTLINE(readability-identifier-naming) constexpr auto KiB(std::unsigned_integral auto value) noexcept -> bytes { @@ -30,11 +34,31 @@ namespace kstd } template<typename ValueType> - constexpr auto operator+(ValueType * pointer, bytes offset) -> ValueType * + constexpr auto operator+(ValueType * pointer, bytes offset) noexcept -> ValueType * { return pointer + offset.value; } + constexpr auto operator+(bytes value, offset offset) noexcept -> result<bytes> + { + if (offset.value < 0 && value.value < static_cast<bytes::value_type>(-offset.value)) + { + return failure(make_error_code(errc::argument_out_of_domain)); + } + value.value += offset.value; + return value; + } + + constexpr auto operator-(bytes value, offset offset) noexcept -> result<bytes> + { + if (offset.value > 0 && value.value < static_cast<bytes::value_type>(offset.value)) + { + return failure(make_error_code(errc::argument_out_of_domain)); + } + value.value -= offset.value; + return value; + } + inline namespace literals { inline namespace units_literals @@ -59,6 +83,26 @@ namespace kstd return GiB(value); } + constexpr auto operator""_B_off(unsigned long long value) noexcept -> offset + { + return offset{static_cast<offset::value_type>(value)}; + } + + constexpr auto operator""_KiB_off(unsigned long long value) noexcept -> offset + { + return offset{static_cast<offset::value_type>(value * 1024)}; + } + + constexpr auto operator""_MiB_off(unsigned long long value) noexcept -> offset + { + return offset{static_cast<offset::value_type>(value * 1024 * 1024)}; + } + + constexpr auto operator""_GiB_off(unsigned long long value) noexcept -> offset + { + return offset{static_cast<offset::value_type>(value * 1024 * 1024 * 1024)}; + } + } // namespace units_literals } // namespace literals |
