From 04b0285d8329e45cea426aa1a8e69203685a4467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 28 Oct 2024 10:15:18 +0000 Subject: Move iterator and container into generic template classes. Use algorithms instead of raw pointer for loops --- .../arch/memory/multiboot/elf_symbols_section.hpp | 7 +- .../include/arch/memory/multiboot/memory_map.hpp | 178 +-------------------- .../include/arch/memory/multiboot/reader.hpp | 9 +- arch/x86_64/include/arch/shared/container.hpp | 73 +++++++++ .../include/arch/shared/random_access_iterator.hpp | 167 +++++++++++++++++++ 5 files changed, 256 insertions(+), 178 deletions(-) create mode 100644 arch/x86_64/include/arch/shared/container.hpp create mode 100644 arch/x86_64/include/arch/shared/random_access_iterator.hpp (limited to 'arch/x86_64/include') diff --git a/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp b/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp index fc8cb15..c9989ae 100644 --- a/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp @@ -1,7 +1,10 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP -#include "info.hpp" +#include "arch/memory/multiboot/info.hpp" +#include "arch/shared/container.hpp" +#include "arch/shared/random_access_iterator.hpp" + #include #include @@ -158,6 +161,8 @@ namespace teachos::arch::memory::multiboot std::byte end; ///< Marks the end of the tag, used to mark the beginning of any additional data. ///< contained in the section, to ensure byte alignment is actually 4 byte. }; + + typedef shared::container> elf_section_header_container; } // namespace teachos::arch::memory::multiboot #endif // TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP diff --git a/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp b/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp index f9c902a..910eecb 100644 --- a/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp @@ -1,9 +1,11 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP -#include "info.hpp" +#include "arch/memory/multiboot/info.hpp" +#include "arch/shared/container.hpp" +#include "arch/shared/random_access_iterator.hpp" + #include -#include namespace teachos::arch::memory::multiboot { @@ -44,177 +46,7 @@ namespace teachos::arch::memory::multiboot struct memory_area entries; ///< Specific memory regions. }; - /** - * @brief Random access iterator for memory areas. - */ - struct memory_area_iterator - { - using iterator_category = std::random_access_iterator_tag; ///< Iterator category of this type. - using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. - using value_type = memory_area; ///< Underlying value pointed to by this iterator. - - /** - * @brief Defaulted constructor. - */ - memory_area_iterator() = default; - - /** - * @brief Constructor. - * - * @param p Underlying address the iterator should point too, ensure to not pass an invalid pointer or the - * constructor will halt execution. - */ - explicit memory_area_iterator(value_type * p); - - /** - * @brief Dereferences the initally given pointer to its value. - * - * @return Reference to the value. - */ - auto operator*() const -> value_type &; - - /** - * @brief Get underlying value, which is the intially passed pointer. - * - * @return Underlying value passed intially. - */ - auto operator->() const -> value_type *; - - /** - * @brief Post increment operator. Returns a copy of the value. - * - * @return Copy of the incremented underlying address. - */ - auto operator++(int) -> memory_area_iterator; - - /** - * @brief Pre increment operator. Returns a reference to the changed value. - * - * @return Reference to the incremented underlying address. - */ - auto operator++() -> memory_area_iterator &; - - /** - * @brief Addition assignment operator. Returns a reference to the changed value. - * - * @param value Value we want to add to the underlying address. - * @return Reference to the changed underlying address. - */ - auto operator+=(difference_type value) -> memory_area_iterator &; - - /** - * @brief Subtraction assignment operator. Returns a reference to the changed value. - * - * @param value Value we want to subtract from the underlying address. - * @return Reference to the changed underlying address. - */ - auto operator-=(difference_type value) -> memory_area_iterator &; - - /** - * @brief Addition operator. Returns the changed value. - * - * @param value Value we want to add to a copy of the underlying address. - * @return Copy of underlying address incremented by the given value. - */ - auto operator+(difference_type value) const -> memory_area_iterator; - - /** - * @brief Subtraction operator. Returns the changed value. - * - * @param value Value we want to subtrcat from a copy of the underlying address. - * @return Copy of underlying address decremented by the given value. - */ - auto operator-(difference_type value) const -> memory_area_iterator; - - /** - * @brief Subtraction operator. Returns the size difference between two iterators. - * - * @param other Other iterator we want to substract the underlying address with ours. - * @return Size difference between the underlying address of this instance and the given iterator. - */ - auto operator-(const memory_area_iterator & other) const -> difference_type; - - /** - * @brief Index operator overload. Returns a reference to the value at the given index. Simply returns the - * dereferenced underlying pointer incremented by the given index. - * - * @param index Index we want to access and get the value from. - * @return Reference to the value at the given index. - */ - auto operator[](difference_type index) const -> value_type &; - - /** - * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. - * - * @param other Other iterator to compare to. - * @return Whether both iterators point to the same underlying address in memory. - */ - auto operator==(memory_area_iterator const & other) const -> bool = default; - - /** - * @brief Defaulted threeway comparsion operator. Simply compares the memory address of both iterators. - * - * @param other Other iterator to compare to. - * @return Whether the given iterator is smaller or larger than this iterator. - */ - auto operator<=>(memory_area_iterator const & other) const -> std::strong_ordering = default; - - private: - value_type * ptr; ///< Underlying address the iterator is currently pointing too. - }; - - /** - * @brief Read-only container for memory areas, that allow to easily use the memory_area_iterator in C++20 ranges - * calls. - */ - struct memory_area_container - { - using iterator = memory_area_iterator; ///< Iterators used by this container. - using size_type = std::size_t; ///< Maximum size of this container. - - /** - * @brief Constructor. - * - * @param begin Pointer to the first memory area, will be used to construct the begin iterator. - * @param size Amount of entries in the container we want to construct. - */ - memory_area_container(memory_area_iterator::value_type * begin, size_type size); - - /** - * @brief Returns the iterator pointing to the first element of the memory area. - * Allows using this class in the for each loop, because it follows the InputIterator template scheme. - * - * @return Iterator pointing to first element of the memory area. - */ - auto begin() const -> iterator; - - /** - * @brief Returns the iterator pointing to one past the last element of the memory area. - * Allows using this class in the for each loop, because it follows the InputIterator template scheme. - * - * @return Iterator pointing to one past the last element of the memory area. - */ - auto end() const -> iterator; - - /** - * @brief Calculates the size of this container, simply subtracts the iterator pointing to the first element by the - * last. - * - * @return Actual size of this container. - */ - auto size() const -> size_type; - - /** - * @brief Calcualtes the size and returns true if the size is 0 and the container therefore emtpy. - * - * @return Whether the container is empty, size being 0 or not - */ - auto empty() const -> bool; - - private: - iterator area_begin; ///< Pointer to the first element of all memory areas. - iterator area_end; ///< Pointer to one pas the last element of all memory areas. - }; + typedef shared::container> memory_area_container; } // namespace teachos::arch::memory::multiboot #endif // TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP diff --git a/arch/x86_64/include/arch/memory/multiboot/reader.hpp b/arch/x86_64/include/arch/memory/multiboot/reader.hpp index 393db8b..baa49c9 100644 --- a/arch/x86_64/include/arch/memory/multiboot/reader.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/reader.hpp @@ -1,8 +1,8 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP -#include "elf_symbols_section.hpp" -#include "memory_map.hpp" +#include "arch/memory/multiboot/memory_map.hpp" + #include namespace teachos::arch::memory::multiboot @@ -17,8 +17,9 @@ namespace teachos::arch::memory::multiboot std::size_t kernel_end; ///< End address of the kernel code in memory. std::size_t multiboot_start; ///< Start address of the multiboot code in memory. std::size_t multiboot_end; ///< End address of the multiboot code in memory. - memory_area * memory_areas; ///< Non-owning pointer to the first element of all memory areas. - uint8_t area_count; ///< Amount of total entries in the memory_areas array. + memory_area_container::iterator + begin_area; ///< Iterator containing non-owning pointer to the first element of all memory areas. + memory_area_container::iterator end_area; ///< Iterator pointing to one past the last element of all memory areas. }; /** diff --git a/arch/x86_64/include/arch/shared/container.hpp b/arch/x86_64/include/arch/shared/container.hpp new file mode 100644 index 0000000..8ea0d08 --- /dev/null +++ b/arch/x86_64/include/arch/shared/container.hpp @@ -0,0 +1,73 @@ +#ifndef TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP +#define TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP + +#include "arch/exception_handling/assert.hpp" + +#include + +namespace teachos::arch::shared +{ + /** + * @brief Read-only container for given template type, that allow to easily use this container instance in C++20 + * ranges calls. + * + * @tparam T Iterator the container uses to signal the start and end of it's data. + */ + template + struct container + { + using iterator = T; ///< Iterators used by this container. + using size_type = std::size_t; ///< Maximum size of this container. + + /** + * @brief Constructor. + * + * @param begin Iterator containing non-owning pointer to the first element of all memory areas. + * @param end Iterator pointing to one past the last element of all memory areas. + */ + container(iterator begin, iterator end) + : begin_itr(begin) + , end_itr(end) + { + exception_handling::assert(begin != iterator{}, "[Memory Area] Attempted to pass nullptr as begin iterator"); + exception_handling::assert(end != iterator{}, "[Memory Area] Attempted to pass nullptr as end iterator"); + } + + /** + * @brief Returns the iterator pointing to the first element of the memory area. + * Allows using this class in the for each loop, because it follows the InputIterator template scheme. + * + * @return Iterator pointing to first element of the memory area. + */ + auto begin() const -> iterator { return begin_itr; } + + /** + * @brief Returns the iterator pointing to one past the last element of the memory area. + * Allows using this class in the for each loop, because it follows the InputIterator template scheme. + * + * @return Iterator pointing to one past the last element of the memory area. + */ + auto end() const -> iterator { return end_itr; } + + /** + * @brief Calculates the size of this container, simply subtracts the iterator pointing to the first element by the + * last. + * + * @return Actual size of this container. + */ + auto size() const -> size_type { return std::distance(begin(), end()); } + + /** + * @brief Calcualtes the size and returns true if the size is 0 and the container therefore emtpy. + * + * @return Whether the container is empty, size being 0 or not + */ + auto empty() const -> bool { return size() == 0; } + + private: + iterator begin_itr; ///< Pointer to the first element of the given template type. + iterator end_itr; ///< Pointer to one pas the last element of the given template type. + }; +} // namespace teachos::arch::shared + +#endif // TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP diff --git a/arch/x86_64/include/arch/shared/random_access_iterator.hpp b/arch/x86_64/include/arch/shared/random_access_iterator.hpp new file mode 100644 index 0000000..392b925 --- /dev/null +++ b/arch/x86_64/include/arch/shared/random_access_iterator.hpp @@ -0,0 +1,167 @@ +#ifndef TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP +#define TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP + +#include + +namespace teachos::arch::shared +{ + /** + * @brief Generic random access iterator for given template type. Can be a nullptr, ensure to check when using this + * iterator. Allows to easily use this iterator instance in algorithm calls. + * + * @tparam T Value the iterator points too. + */ + template + struct random_access_iterator + { + using iterator_category = std::random_access_iterator_tag; ///< Iterator category of this type. + using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. + using value_type = T; ///< Underlying value pointed to by this iterator. + + /** + * @brief Defaulted constructor. + */ + random_access_iterator() = default; + + /** + * @brief Constructor. + * + * @param p Underlying address the iterator should point too, ensure to not pass an invalid pointer or the + * constructor will halt execution. + */ + explicit random_access_iterator(value_type * p) + : ptr(p) + { + // Nothing to do + } + + /** + * @brief Dereferences the initally given pointer to its value. + * + * @return Reference to the value. + */ + auto operator*() const -> value_type & { return *ptr; } + + /** + * @brief Get underlying value, which is the intially passed pointer. + * + * @return Underlying value passed intially. + */ + auto operator->() const -> value_type * { return ptr; } + + /** + * @brief Post increment operator. Returns a copy of the value. + * + * @return Copy of the incremented underlying address. + */ + auto operator++(int) -> random_access_iterator + { + random_access_iterator old_value = *this; + ++ptr; + return old_value; + } + + /** + * @brief Pre increment operator. Returns a reference to the changed value. + * + * @return Reference to the incremented underlying address. + */ + auto operator++() -> random_access_iterator & + { + ++ptr; + return *this; + } + + /** + * @brief Addition assignment operator. Returns a reference to the changed value. + * + * @param value Value we want to add to the underlying address. + * @return Reference to the changed underlying address. + */ + auto operator+=(difference_type value) -> random_access_iterator & + { + ptr += value; + return *this; + } + + /** + * @brief Subtraction assignment operator. Returns a reference to the changed value. + * + * @param value Value we want to subtract from the underlying address. + * @return Reference to the changed underlying address. + */ + auto operator-=(difference_type value) -> random_access_iterator & + { + ptr -= value; + return *this; + } + + /** + * @brief Addition operator. Returns the changed value. + * + * @param value Value we want to add to a copy of the underlying address. + * @return Copy of underlying address incremented by the given value. + */ + auto operator+(difference_type value) const -> random_access_iterator + { + return random_access_iterator{ptr + value}; + } + + /** + * @brief Subtraction operator. Returns the changed value. + * + * @param value Value we want to subtrcat from a copy of the underlying address. + * @return Copy of underlying address decremented by the given value. + */ + auto operator-(difference_type value) const -> random_access_iterator + { + return random_access_iterator{ptr - value}; + } + + /** + * @brief Subtraction operator. Returns the size difference between two iterators. + * + * @param other Other iterator we want to substract the underlying address with ours. + * @return Size difference between the underlying address of this instance and the given iterator. + */ + auto operator-(const random_access_iterator & other) const -> difference_type { return ptr - other.ptr; } + + /** + * @brief Index operator overload. Returns a reference to the value at the given index. Simply returns the + * dereferenced underlying pointer incremented by the given index. + * + * @param index Index we want to access and get the value from. + * @return Reference to the value at the given index. + */ + auto operator[](difference_type index) const -> value_type & { return *(ptr + index); } + + /** + * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether both iterators point to the same underlying address in memory. + */ + auto operator==(random_access_iterator const & other) const -> bool = default; + + /** + * @brief Defaulted negated comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether both iterators don't point to the same underlying address in memory. + */ + auto operator!=(random_access_iterator const & other) const -> bool = default; + + /** + * @brief Defaulted threeway comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether the given iterator is smaller or larger than this iterator. + */ + auto operator<=>(random_access_iterator const & other) const -> std::strong_ordering = default; + + private: + value_type * ptr = {}; ///< Underlying address the iterator is currently pointing too. + }; +} // namespace teachos::arch::shared + +#endif // TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP -- cgit v1.2.3