| // Copyright 2025 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef BASE_BYTE_COUNT_H_ |
| #define BASE_BYTE_COUNT_H_ |
| |
| #include <cstdint> |
| #include <type_traits> |
| |
| #include "base/numerics/checked_math.h" |
| #include "base/numerics/safe_conversions.h" |
| |
| namespace base { |
| |
| // Represents an integral number of bytes. Supports arithmetic operations and |
| // conversions to/from KiB, MiB and GiB. Any operation that overflows will |
| // result in a crash and thus this should only be used for trusted inputs. |
| // |
| // Sample usage: |
| // |
| // // Share unit conversion code. |
| // constexpr ByteCount kBufferSize = MiB(1); |
| // std::vector<char> buffer(kBufferSize.InBytesUnsigned()); |
| // |
| // // Enforce that correct units are used across APIs at compile time. |
| // ByteCount quota = GetQuota(); |
| // SetMetadataSize(base::KiB(10)); |
| // SetDatabaseSize(quota - base::KiB(10)); |
| class ByteCount { |
| public: |
| constexpr ByteCount() = default; |
| |
| constexpr explicit ByteCount(int64_t bytes) : bytes_(bytes) {} |
| ~ByteCount() = default; |
| |
| ByteCount(const ByteCount&) = default; |
| ByteCount& operator=(const ByteCount&) = default; |
| |
| static constexpr ByteCount FromUnsigned(uint64_t bytes) { |
| return ByteCount(checked_cast<int64_t>(bytes)); |
| } |
| |
| constexpr bool is_zero() const { return bytes_ == 0; } |
| |
| // Conversion to integral values. |
| constexpr int64_t InBytes() const { return bytes_; } |
| constexpr int64_t InKiB() const { return bytes_ / 1024; } |
| constexpr int64_t InMiB() const { return bytes_ / 1024 / 1024; } |
| constexpr int64_t InGiB() const { return bytes_ / 1024 / 1024 / 1024; } |
| |
| // Conversion to floating point values. |
| constexpr double InKiBF() const { return bytes_ / 1024.0; } |
| constexpr double InMiBF() const { return bytes_ / 1024.0 / 1024.0; } |
| constexpr double InGiBF() const { return bytes_ / 1024.0 / 1024.0 / 1024.0; } |
| |
| // Conversion to an unsigned amount of bytes. Only use when it is guaranteed |
| // that the value is positive. Fails if the value is negative. |
| constexpr uint64_t InBytesUnsigned() const { |
| return checked_cast<uint64_t>(bytes_); |
| } |
| |
| constexpr ByteCount operator+(ByteCount other) const { |
| return ByteCount( |
| (CheckedNumeric<int64_t>(bytes_) + other.bytes_).ValueOrDie()); |
| } |
| constexpr ByteCount operator-(ByteCount other) const { |
| return ByteCount( |
| (CheckedNumeric<int64_t>(bytes_) - other.bytes_).ValueOrDie()); |
| } |
| |
| template <typename T> |
| constexpr ByteCount operator*(T value) const { |
| return ByteCount((CheckedNumeric<int64_t>(bytes_) * value).ValueOrDie()); |
| } |
| |
| template <typename T> |
| constexpr ByteCount operator/(T value) const { |
| return ByteCount((CheckedNumeric<int64_t>(bytes_) / value).ValueOrDie()); |
| } |
| |
| constexpr auto operator<=>(const ByteCount& other) const = default; |
| |
| private: |
| int64_t bytes_ = 0; |
| }; |
| |
| template <typename T> |
| requires std::is_arithmetic_v<T> |
| constexpr ByteCount KiB(T kib) { |
| return ByteCount((CheckedNumeric<int64_t>(kib) * 1024).ValueOrDie()); |
| } |
| |
| template <typename T> |
| requires std::is_arithmetic_v<T> |
| constexpr ByteCount MiB(T mib) { |
| return ByteCount((CheckedNumeric<int64_t>(mib) * 1024 * 1024).ValueOrDie()); |
| } |
| |
| template <typename T> |
| requires std::is_arithmetic_v<T> |
| constexpr ByteCount GiB(T gib) { |
| return ByteCount( |
| (CheckedNumeric<int64_t>(gib) * 1024 * 1024 * 1024).ValueOrDie()); |
| } |
| |
| } // namespace base |
| |
| #endif // BASE_BYTE_COUNT_H_ |