StormByte 2.0.0
C++26 foundation of the StormByte suite
 
Loading...
Searching...
No Matches
size.hxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024-2026 David C. Manuelda (StormBytePP)
3 *
4 * This file is part of StormByte.
5 *
6 * StormByte original source is dual-licensed:
7 *
8 * 1. GNU Lesser General Public License v3.0 (or later)
9 * You may redistribute and/or modify this file under the terms of the
10 * GNU Lesser General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * 2. Commercial license
15 * Alternatively, this file may be used under the terms of a commercial
16 * license agreement with the copyright holder
17 * (David C. Manuelda <StormByte@gmail.com>).
18 *
19 * Both licenses apply only to original StormByte source in this repository.
20 * They do not cover other StormByte modules or any third-party material
21 * shipped with this repository (including everything under thirdparty/),
22 * which remains under its own license.
23 *
24 * Neither license grants any patent rights. Any patent licenses required
25 * to use this software or third-party components must be obtained separately
26 * from the patent holders.
27 *
28 * StormByte is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU Lesser General Public License for more details.
32 *
33 * You should have received a copy of the GNU Lesser General Public License
34 * version 3 along with StormByte. If not, see
35 * <https://www.gnu.org/licenses/lgpl-3.0.html>.
36 *
37 * SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-StormByte-Commercial
38 */
39
40#pragma once
41
42#include <StormByte/cstring.hxx>
45
46#include <cassert>
47#include <compare>
48#include <cstddef>
49#include <cstdint>
50#include <limits>
51#include <ostream>
52#include <string>
53
58namespace StormByte {
96 public:
105 constexpr Size() noexcept: m_value(0) {}
106
113 template<Type::Integral T>
114 constexpr Size(T value) noexcept: m_value(0) {
115 if constexpr (Type::Signed<T>)
116 assert(value >= static_cast<T>(0));
117 m_value = static_cast<std::uint64_t>(value);
118 }
119
124 constexpr Size(const Size& other) noexcept = default;
125
130 constexpr Size(Size&& other) noexcept = default;
131
135 constexpr ~Size() noexcept = default;
136
142 constexpr Size& operator=(const Size& other) noexcept = default;
143
149 constexpr Size& operator=(Size&& other) noexcept = default;
150
158 template<Type::Integral T>
159 constexpr Size& operator=(T value) noexcept {
160 *this = Size(value);
161 return *this;
162 }
163
175 constexpr std::uint64_t Value() const noexcept {
176 return m_value;
177 }
178
190 constexpr explicit operator std::uint64_t() const noexcept {
191 return m_value;
192 }
193
202 template<typename T>
204 constexpr explicit operator T() const noexcept {
205 assert(m_value <= static_cast<std::uint64_t>(std::numeric_limits<std::size_t>::max()));
206 return static_cast<std::size_t>(m_value);
207 }
208
214 constexpr explicit operator std::ptrdiff_t() const noexcept {
215 assert(m_value <= static_cast<std::uint64_t>(std::numeric_limits<std::ptrdiff_t>::max()));
216 return static_cast<std::ptrdiff_t>(m_value);
217 }
218
223 explicit operator CString() const noexcept;
224
229 inline operator std::string() const {
230 return static_cast<std::string>(static_cast<CString>(*this));
231 }
232
246 friend constexpr bool operator==(Size lhs, Size rhs) noexcept {
247 return lhs.m_value == rhs.m_value;
248 }
249
256 friend constexpr std::strong_ordering operator<=>(Size lhs, Size rhs) noexcept {
257 return lhs.m_value <=> rhs.m_value;
258 }
259
274 friend constexpr Size operator+(Size lhs, Size rhs) noexcept {
275 assert(lhs.m_value <= std::numeric_limits<std::uint64_t>::max() - rhs.m_value);
276 return Size(static_cast<std::uint64_t>(lhs.m_value + rhs.m_value));
277 }
278
286 friend constexpr Size operator-(Size lhs, Size rhs) noexcept {
287 assert(lhs.m_value >= rhs.m_value);
288 return Size(static_cast<std::uint64_t>(lhs.m_value - rhs.m_value));
289 }
290
297 constexpr Size& operator+=(Size other) noexcept {
298 *this = *this + other;
299 return *this;
300 }
301
308 constexpr Size& operator-=(Size other) noexcept {
309 *this = *this - other;
310 return *this;
311 }
312
315 private:
316 std::uint64_t m_value;
317 };
318
323 struct Unit {
324 std::uint64_t factor;
325 };
326
331 inline constexpr Unit B{1};
332 inline constexpr Unit KiB{1024};
333 inline constexpr Unit MiB{1024ull * 1024};
334 inline constexpr Unit GiB{1024ull * 1024 * 1024};
335 inline constexpr Unit TiB{1024ull * 1024 * 1024 * 1024};
336 inline constexpr Unit PiB{1024ull * 1024 * 1024 * 1024 * 1024};
337 inline constexpr Unit EiB{1024ull * 1024 * 1024 * 1024 * 1024 * 1024};
344 inline constexpr Unit KB{1000};
345 inline constexpr Unit MB{1000ull * 1000};
346 inline constexpr Unit GB{1000ull * 1000 * 1000};
347 inline constexpr Unit TB{1000ull * 1000 * 1000 * 1000};
348 inline constexpr Unit PB{1000ull * 1000 * 1000 * 1000 * 1000};
349 inline constexpr Unit EB{1000ull * 1000 * 1000 * 1000 * 1000 * 1000};
360 template<Type::Integral T>
361 constexpr Size operator*(T count, Unit unit) noexcept {
362 if constexpr (Type::Signed<T>)
363 assert(count >= T{0});
364 const std::uint64_t factor = static_cast<std::uint64_t>(count);
365 assert(unit.factor == 0 || factor <= std::numeric_limits<std::uint64_t>::max() / unit.factor);
366 return Size(factor * unit.factor);
367 }
368
376 template<Type::Integral T>
377 constexpr Size operator*(Unit unit, T count) noexcept {
378 return count * unit;
379 }
380
389 template<Type::FloatingPoint T>
390 constexpr Size operator*(T count, Unit unit) noexcept {
391 assert(count >= T{0});
392 const long double product = static_cast<long double>(count) * static_cast<long double>(unit.factor);
393 assert(product <= static_cast<long double>(std::numeric_limits<std::uint64_t>::max()));
394 return Size(static_cast<std::uint64_t>(product + 0.5L));
395 }
396
404 template<Type::FloatingPoint T>
405 constexpr Size operator*(Unit unit, T count) noexcept {
406 return count * unit;
407 }
408
417 template<Type::Integral T>
418 constexpr Size operator*(T count, const Size& size) noexcept {
419 if constexpr (Type::Signed<T>)
420 assert(count > T{0});
421 else
422 assert(count != T{0});
423 const std::uint64_t factor = static_cast<std::uint64_t>(count);
424 assert(size.Value() == 0 || factor <= std::numeric_limits<std::uint64_t>::max() / size.Value());
425 return Size(factor * size.Value());
426 }
427
435 template<Type::Integral T>
436 constexpr Size operator*(const Size& size, T count) noexcept {
437 return count * size;
438 }
439
448 template<Type::Integral T>
449 constexpr std::uint64_t operator/(const Size& size, T count) noexcept {
450 if constexpr (Type::Signed<T>)
451 assert(count > T{0});
452 else
453 assert(count != T{0});
454 return size.Value() / static_cast<std::uint64_t>(count);
455 }
456
465 template<Type::Integral T>
466 constexpr std::uint64_t operator%(const Size& size, T count) noexcept {
467 if constexpr (Type::Signed<T>)
468 assert(count > T{0});
469 else
470 assert(count != T{0});
471 return size.Value() % static_cast<std::uint64_t>(count);
472 }
473
480 inline std::ostream& operator<<(std::ostream& stream, const Size& size) {
481 return stream << static_cast<std::string>(size);
482 }
483}
Owned NUL-terminated buffer, safe to use across a DLL boundary.
Definition cstring.hxx:89
Byte count that is the same width on every host.
Definition size.hxx:95
friend constexpr Size operator-(Size lhs, Size rhs) noexcept
Difference.
Definition size.hxx:286
friend constexpr std::strong_ordering operator<=>(Size lhs, Size rhs) noexcept
Numeric order.
Definition size.hxx:256
constexpr std::uint64_t Value() const noexcept
Stored count.
Definition size.hxx:175
constexpr Size(T value) noexcept
From an integer count.
Definition size.hxx:114
constexpr Size(Size &&other) noexcept=default
Move constructor.
constexpr ~Size() noexcept=default
Destructor.
constexpr Size & operator+=(Size other) noexcept
Adds other to this size.
Definition size.hxx:297
constexpr Size(const Size &other) noexcept=default
Copy constructor.
constexpr Size() noexcept
Zero.
Definition size.hxx:105
constexpr Size & operator-=(Size other) noexcept
Subtracts other from this size.
Definition size.hxx:308
friend constexpr bool operator==(Size lhs, Size rhs) noexcept
Numeric equality.
Definition size.hxx:246
friend constexpr Size operator+(Size lhs, Size rhs) noexcept
Sum.
Definition size.hxx:274
Same type after stripping cv and references from both sides.
Definition relations.hxx:94
Signed arithmetic type (std::is_signed).
Definition categories.hxx:219
Root namespace of the StormByte suite.
constexpr Size operator*(T count, Unit unit) noexcept
Scale unit by an integer count.
Definition size.hxx:361
constexpr Unit EiB
2^60 bytes
Definition size.hxx:337
constexpr Unit B
2^0 bytes
Definition size.hxx:331
constexpr Unit KB
10^3 bytes
Definition size.hxx:344
constexpr Unit GB
10^9 bytes
Definition size.hxx:346
constexpr Unit TiB
2^40 bytes
Definition size.hxx:335
constexpr Unit MB
10^6 bytes
Definition size.hxx:345
constexpr Unit EB
10^18 bytes
Definition size.hxx:349
constexpr Unit PB
10^15 bytes
Definition size.hxx:348
std::ostream & operator<<(std::ostream &stream, const CString &text)
Writes text to stream.
Definition cstring.hxx:304
constexpr Unit KiB
2^10 bytes
Definition size.hxx:332
constexpr Unit PiB
2^50 bytes
Definition size.hxx:336
constexpr Unit TB
10^12 bytes
Definition size.hxx:347
constexpr std::uint64_t operator%(const Size &size, T count) noexcept
Leftover bytes after splitting size into pieces of count bytes.
Definition size.hxx:466
constexpr std::uint64_t operator/(const Size &size, T count) noexcept
How many pieces of count bytes fit in size.
Definition size.hxx:449
constexpr Unit MiB
2^20 bytes
Definition size.hxx:333
constexpr Unit GiB
2^30 bytes
Definition size.hxx:334
Named concepts and small type utilities used across the suite.
STL namespace.
Scale factor for Size (KiB, KB, …).
Definition size.hxx:323
std::uint64_t factor
Bytes in one unit.
Definition size.hxx:324
#define STORMBYTE_PUBLIC
Definition visibility.h:52