diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 79c87ca95..6e36fcc57 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -7,7 +7,7 @@ #ifndef NAZARA_SPARSEPTR_HPP #define NAZARA_SPARSEPTR_HPP -///FIXME: Est-ce que SparsePtr est vraiment le meilleur nom pour cette classe ? +///FIXME: Is SparsePtr a really good name for this class ? #include #include diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index d6b227226..31e83addd 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -7,24 +7,52 @@ namespace Nz { + /*! + * \class Nz::SparsePtr + * \brief Core class that represents a pointer and the step between two elements + */ + + /*! + * \brief Constructs a SparsePtr object by default + */ + template SparsePtr::SparsePtr() { Reset(); } + /*! + * \brief Constructs a SparsePtr object with a pointer + * + * \param ptr Pointer to data + */ + template SparsePtr::SparsePtr(T* ptr) { Reset(ptr); } + /*! + * \brief Constructs a SparsePtr object with a pointer and a step + * + * \param ptr Pointer to data + * \param stride Step between two elements + */ + template SparsePtr::SparsePtr(VoidPtr ptr, int stride) { Reset(ptr, stride); } + /*! + * \brief Constructs a SparsePtr object from another type of SparsePtr + * + * \param ptr Pointer to data of type U to convert to type T + */ + template template SparsePtr::SparsePtr(const SparsePtr& ptr) @@ -32,18 +60,32 @@ namespace Nz Reset(ptr); } + /*! + * \brief Gets the original pointer + * \return Pointer to the first data + */ + template typename SparsePtr::VoidPtr SparsePtr::GetPtr() const { return m_ptr; } + /*! + * \brief Gets the stride + * \return Step between two elements + */ + template int SparsePtr::GetStride() const { return m_stride; } + /*! + * \brief Resets the SparsePtr + */ + template void SparsePtr::Reset() { @@ -51,6 +93,14 @@ namespace Nz SetStride(0); } + /*! + * \brief Resets the SparsePtr with a pointer + * + * \param ptr Pointer to data + * + * \remark stride is set to sizeof(T) + */ + template void SparsePtr::Reset(T* ptr) { @@ -58,6 +108,13 @@ namespace Nz SetStride(sizeof(T)); } + /*! + * \brief Resets the SparsePtr with a pointer and its stride + * + * \param ptr Pointer to data + * \param stride Step between two elements + */ + template void SparsePtr::Reset(VoidPtr ptr, int stride) { @@ -65,6 +122,12 @@ namespace Nz SetStride(stride); } + /*! + * \brief Resets the SparsePtr with another SparsePtr + * + * \param ptr Another sparsePtr + */ + template void SparsePtr::Reset(const SparsePtr& ptr) { @@ -72,6 +135,12 @@ namespace Nz SetStride(ptr.GetStride()); } + /*! + * \brief Resets the SparsePtr with another type of SparsePtr + * + * \param ptr Another sparsePtr + */ + template template void SparsePtr::Reset(const SparsePtr& ptr) @@ -82,94 +151,187 @@ namespace Nz SetStride(ptr.GetStride()); } + /*! + * \brief Sets the pointer + * + * \param ptr Pointer to data + */ + template void SparsePtr::SetPtr(VoidPtr ptr) { m_ptr = reinterpret_cast(ptr); } + /*! + * \brief Sets the stride + * + * \param stride Step between two elements + */ + template void SparsePtr::SetStride(int stride) { m_stride = stride; } + /*! + * \brief Converts the pointer to bool + * \return true if pointer is not nullptr + */ + template SparsePtr::operator bool() const { return m_ptr != nullptr; } + /*! + * \brief Converts the pointer to a pointer to the value + * \return The value of the pointer + */ + template SparsePtr::operator T*() const { return reinterpret_cast(m_ptr); } + /*! + * \brief Dereferences the pointer + * \return The dereferencing of the pointer + */ + template T& SparsePtr::operator*() const { return *reinterpret_cast(m_ptr); } + /*! + * \brief Dereferences the pointer + * \return The dereferencing of the pointer + */ + template T* SparsePtr::operator->() const { return reinterpret_cast(m_ptr); } + /*! + * \brief Gets the ith element of the stride pointer + * \return A reference to the ith value + * + * \param index Number of stride to do + */ + template T& SparsePtr::operator[](int index) const { - return *reinterpret_cast(m_ptr + index*m_stride); + return *reinterpret_cast(m_ptr + index * m_stride); } + /*! + * \brief Gets the SparsePtr with an offset + * \return A SparsePtr with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr SparsePtr::operator+(int count) const { - return SparsePtr(m_ptr + count*m_stride, m_stride); + return SparsePtr(m_ptr + count * m_stride, m_stride); } + /*! + * \brief Gets the SparsePtr with an offset + * \return A SparsePtr with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr SparsePtr::operator+(unsigned int count) const { - return SparsePtr(m_ptr + count*m_stride, m_stride); + return SparsePtr(m_ptr + count * m_stride, m_stride); } + /*! + * \brief Gets the SparsePtr with an offset + * \return A SparsePtr with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr SparsePtr::operator-(int count) const { - return SparsePtr(m_ptr - count*m_stride, m_stride); + return SparsePtr(m_ptr - count * m_stride, m_stride); } + /*! + * \brief Gets the SparsePtr with an offset + * \return A SparsePtr with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr SparsePtr::operator-(unsigned int count) const { - return SparsePtr(m_ptr - count*m_stride, m_stride); + return SparsePtr(m_ptr - count * m_stride, m_stride); } + /*! + * \brief Gets the difference between the two SparsePtr + * \return The difference of elements: ptr - this->ptr + * + * \param ptr Other ptr + */ + template std::ptrdiff_t SparsePtr::operator-(const SparsePtr& ptr) const { - return (m_ptr - ptr.m_ptr)/m_stride; + return (m_ptr - ptr.m_ptr) / m_stride; } + /*! + * \brief Gets the SparsePtr with an offset + * \return A reference to this pointer with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr& SparsePtr::operator+=(int count) { - m_ptr += count*m_stride; + m_ptr += count * m_stride; return *this; } + /*! + * \brief Gets the SparsePtr with an offset + * \return A reference to this pointer with the new stride + * + * \param count Number of stride to do + */ + template SparsePtr& SparsePtr::operator-=(int count) { - m_ptr -= count*m_stride; + m_ptr -= count * m_stride; return *this; } + /*! + * \brief Gets the SparsePtr with the next element + * \return A reference to this pointer updated + */ + template SparsePtr& SparsePtr::operator++() { @@ -178,19 +340,29 @@ namespace Nz return *this; } + /*! + * \brief Gets the SparsePtr with the next element + * \return A SparsePtr not updated + */ + template SparsePtr SparsePtr::operator++(int) { - // On fait une copie de l'objet + // We copy the object SparsePtr tmp(*this); - // On modifie l'objet + // We modify it operator++(); - // On retourne la copie + // We return the copy return tmp; } + /*! + * \brief Gets the SparsePtr with the previous element + * \return A reference to this pointer updated + */ + template SparsePtr& SparsePtr::operator--() { @@ -198,49 +370,96 @@ namespace Nz return *this; } + /*! + * \brief Gets the SparsePtr with the previous element + * \return A SparsePtr not updated + */ + template SparsePtr SparsePtr::operator--(int) { - // On fait une copie de l'objet + // We copy the object SparsePtr tmp(*this); - // On modifie l'objet + // We modify it operator--(); - // On retourne la copie + // We return the copy return tmp; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the two SparsePtr are pointing to the same memory + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator==(const SparsePtr& ptr) const { return m_ptr == ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return false if the two SparsePtr are pointing to the same memory + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator!=(const SparsePtr& ptr) const { return m_ptr != ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the first SparsePtr is pointing to memory inferior to the second one + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator<(const SparsePtr& ptr) const { return m_ptr < ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the first SparsePtr is pointing to memory superior to the second one + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator>(const SparsePtr& ptr) const { return m_ptr > ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the first SparsePtr is pointing to memory inferior or equal to the second one + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator<=(const SparsePtr& ptr) const { return m_ptr <= ptr.m_ptr; } + /*! + * \brief Compares the SparsePtr to another one + * \return true if the first SparsePtr is pointing to memory superior or equal to the second one + * + * \param ptr Other SparsePtr to compare with + */ + template bool SparsePtr::operator>=(const SparsePtr& ptr) const { diff --git a/tests/Engine/Core/SparsePtr.cpp b/tests/Engine/Core/SparsePtr.cpp new file mode 100644 index 000000000..6979549a3 --- /dev/null +++ b/tests/Engine/Core/SparsePtr.cpp @@ -0,0 +1,47 @@ +#include +#include + +#include + +SCENARIO("SparsePtr", "[CORE][SPARSEPTR]") +{ + GIVEN("A sparse pointer pointing to an array with a stride of 2") + { + std::array arrays{0, 1, 2, 3, 4}; + Nz::SparsePtr sparsePtr(arrays.begin(), 2 * sizeof(int)); + + WHEN("We use operators") + { + THEN("Operator[] with 2 should be 4") + { + REQUIRE(4 == sparsePtr[2]); + } + + THEN("Operator++ and Operator-- should be opposite") + { + ++sparsePtr; + REQUIRE(2 == *sparsePtr); + auto old = sparsePtr++; + REQUIRE(2 == *old); + REQUIRE(4 == *sparsePtr); + + --sparsePtr; + REQUIRE(2 == *sparsePtr); + auto oldMinus = sparsePtr--; + REQUIRE(2 == *oldMinus); + REQUIRE(0 == *sparsePtr); + } + + THEN("Operator+ and operator-") + { + auto offsetTwo = sparsePtr + 2; + REQUIRE(4 == *offsetTwo); + + auto offsetZero = offsetTwo - 2; + REQUIRE(0 == *offsetZero); + + REQUIRE((offsetTwo - offsetZero) == 2); + } + } + } +}