diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-03-18 17:18:37 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-03-18 17:18:37 +0100 |
| commit | e7ccb96aecae7b231fb05818d7e45a767aebc31d (patch) | |
| tree | 68f7a623018d025b3fb6d10ce49d022242cc14f2 /libs | |
| parent | 12c0586ee15cadfa178e6982dc0f76b047cb2df9 (diff) | |
| download | teachos-e7ccb96aecae7b231fb05818d7e45a767aebc31d.tar.xz teachos-e7ccb96aecae7b231fb05818d7e45a767aebc31d.zip | |
kstd: introduce strong type for memory amounts
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/kstd/include/kstd/units | 145 | ||||
| -rw-r--r-- | libs/multiboot2/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | libs/multiboot2/include/multiboot2/information.hpp | 16 | ||||
| -rw-r--r-- | libs/multiboot2/include/multiboot2/information/data.hpp | 31 |
4 files changed, 186 insertions, 7 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 diff --git a/libs/multiboot2/CMakeLists.txt b/libs/multiboot2/CMakeLists.txt index 350a996..b306b66 100644 --- a/libs/multiboot2/CMakeLists.txt +++ b/libs/multiboot2/CMakeLists.txt @@ -20,6 +20,7 @@ target_include_directories("multiboot2" INTERFACE target_link_libraries("multiboot2" INTERFACE "libs::elf" + "libs::kstd" ) set_target_properties("multiboot2" PROPERTIES diff --git a/libs/multiboot2/include/multiboot2/information.hpp b/libs/multiboot2/include/multiboot2/information.hpp index fbd534c..d2fac2e 100644 --- a/libs/multiboot2/include/multiboot2/information.hpp +++ b/libs/multiboot2/include/multiboot2/information.hpp @@ -5,11 +5,12 @@ #include "information/iterator.hpp" // IWYU pragma: export #include "information/tag.hpp" // IWYU pragma: export +#include <kstd/units> + #include <elf/format.hpp> #include <elf/section_header.hpp> #include <algorithm> -#include <cstddef> #include <cstdint> #include <cstdlib> #include <optional> @@ -119,7 +120,12 @@ namespace multiboot2 */ [[nodiscard]] auto string() const noexcept -> std::string_view { - return {data(), size()}; + return {data(), vla_tag::size()}; + } + + [[nodiscard]] constexpr auto size() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{end_address - start_address}; } }; @@ -130,9 +136,9 @@ namespace multiboot2 using pointer = iterator::pointer; using reference = iterator::reference; - [[nodiscard]] auto size_bytes() const noexcept -> std::size_t + [[nodiscard]] auto size() const noexcept -> kstd::units::bytes { - return m_size; + return kstd::units::bytes{m_size}; } // Range access @@ -190,7 +196,7 @@ namespace multiboot2 { return get<multiboot2::elf_symbols<Format>>().and_then( [](auto x) -> std::optional<multiboot2::elf_symbols<Format>> { - if (x.entry_size == elf::section_header_size<Format>) + if (x.entry_size_in_B == elf::section_header_size<Format>) { return std::optional{x}; } diff --git a/libs/multiboot2/include/multiboot2/information/data.hpp b/libs/multiboot2/include/multiboot2/information/data.hpp index 9fa6d5b..3b07d20 100644 --- a/libs/multiboot2/include/multiboot2/information/data.hpp +++ b/libs/multiboot2/include/multiboot2/information/data.hpp @@ -6,6 +6,8 @@ #include "multiboot2/constants/information_id.hpp" #include "multiboot2/constants/memory_type.hpp" +#include <kstd/units> + #include <cstdint> namespace multiboot2 @@ -27,6 +29,16 @@ namespace multiboot2 //! loader. struct basic_memory : tag_data<information_id::basic_memory_information> { + [[nodiscard]] constexpr auto lower() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{lower_KiB * 1024}; + } + + [[nodiscard]] constexpr auto upper() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{upper_KiB * 1024}; + } + //! The amount of lower memory available to the system. //! //! Any memory below the 1 MiB address boundary is considered to be lower memory. The maximum possible value for @@ -72,11 +84,16 @@ namespace multiboot2 //! time. The array begins after the last member of this structure. struct elf_symbols : tag_data<information_id::elf_sections> { + [[nodiscard]] constexpr auto entry_size() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{entry_size_in_B}; + } + //! The number of section header table entries. std::uint32_t count; //! The size of each section header table entry. - std::uint32_t entry_size; + std::uint32_t entry_size_in_B; //! The section number of the string table containing the section names. std::uint32_t string_table_index; @@ -102,6 +119,11 @@ namespace multiboot2 return type == memory_type::available; } + [[nodiscard]] constexpr auto size() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{size_in_B}; + } + //! The physical start address of this region std::uint64_t base; @@ -117,11 +139,16 @@ namespace multiboot2 std::uint32_t : 0; }; + [[nodiscard]] constexpr auto entry_size() const noexcept -> kstd::units::bytes + { + return kstd::units::bytes{entry_size_in_B}; + } + //! The size of each entry present in the map. //! //! This field is present to allow for future extension of the entry format. Each entry's size is guaranteed to //! always be an integer multiple of 8. - std::uint32_t entry_size; + std::uint32_t entry_size_in_B; //! The version of each entry present in the map std::uint32_t entry_version; |
