diff --git a/include/doorkeeper/components/tileiterator.hpp b/include/doorkeeper/components/tileiterator.hpp index cc61c6e..efd7980 100644 --- a/include/doorkeeper/components/tileiterator.hpp +++ b/include/doorkeeper/components/tileiterator.hpp @@ -3,20 +3,19 @@ #include "doorkeeper/primitivetypes.hpp" #include "doorkeeper/implem/helpers.hpp" +#include "doorkeeper/components/tilecoords.hpp" #include #include #include #include #include +#include namespace dk { template class TileIterator; namespace implem { - template - size_t get_index_from_pos ( const Vector& parPos, const Vector& parSize ) a_pure; - template struct TypeWithQualifiers { typedef typename std::conditional::value && std::is_const::value, @@ -30,37 +29,26 @@ namespace dk { >::type >::type result; }; - -#if defined(NDEBUG) - template <> - size_t get_index_from_pos<2> ( const Vector<2>& parPos, const Vector<2>& parSize ) a_pure; -#endif - - template - Vector buildPastEndCoordinate ( const Vector& parFrom, const Vector& parTo ) a_pure; - - template - const Vector& get_from_from_iterator ( const TileIterator& parIterator ); } //namespace implem template ::type> class TileIterator : public boost::iterator_facade, T, boost::bidirectional_traversal_tag> { friend class boost::iterator_core_access; - friend const Vector& implem::get_from_from_iterator<> ( const TileIterator& parIterator ); typedef std::vector vector_type; typedef typename implem::TypeWithQualifiers::result qualif_vector_type; public: - typedef Vector coords; + typedef TileCoords TileCoordsType; + typedef typename TileCoordsType::coords coords; - TileIterator ( void ); + TileIterator ( void ) = default; TileIterator ( const TileIterator& parOther ) = default; TileIterator ( TileIterator&& parOther ) = default; - TileIterator ( qualif_vector_type* parData, const coords& parFrom, const coords& parTo ); - TileIterator ( qualif_vector_type* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo ); - TileIterator ( qualif_vector_type* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo, const coords& parSubdiv ); + TileIterator ( qualif_vector_type* parData, const coords& parArea ); + TileIterator ( qualif_vector_type* parData, const coords& parStart, const coords& parArea ); ~TileIterator ( void ) = default; - const coords& abs_position ( void ) const { return m_pos; } + const TileCoordsType& raw_coords ( void ) const; + const coords& position ( void ) const; private: void increment ( void ); @@ -69,15 +57,9 @@ namespace dk { ptrdiff_t distance_to ( const TileIterator& parOther ); bool equal ( const TileIterator& parOther ) const; T& dereference ( void ) const; - size_t get_current_index ( void ) const { return implem::get_index_from_pos(m_pos, m_subdivareasize) + m_subindex; } - coords m_pos; - coords m_from; - coords m_to; - coords m_subdivareasize; + TileCoordsType m_tile_range;; qualif_vector_type* m_data; - CoordinateScalarType m_subindex; - CoordinateScalarType m_maxsubindex; }; } //namespace dk diff --git a/include/doorkeeper/implem/tilecoords.inl b/include/doorkeeper/implem/tilecoords.inl index 214634e..b3711f0 100644 --- a/include/doorkeeper/implem/tilecoords.inl +++ b/include/doorkeeper/implem/tilecoords.inl @@ -111,7 +111,7 @@ namespace dk { for (std::size_t d = 0; d < static_cast(D); ++d) { if (m_pos[d] > lower[d]) { --m_pos[d]; - return; + return *this; } else { m_pos[d] = m_size[d]; diff --git a/include/doorkeeper/implem/tileiterator.inl b/include/doorkeeper/implem/tileiterator.inl index 38db99f..84459d1 100644 --- a/include/doorkeeper/implem/tileiterator.inl +++ b/include/doorkeeper/implem/tileiterator.inl @@ -1,128 +1,28 @@ namespace dk { - namespace implem { - template - inline size_t get_index_from_pos (const Vector& parPos, const Vector& parSize) { - size_t index = 0; - for (size_t d = 0; d < D; ++d) { - size_t pos = static_cast(parPos[D - 1 - d]); - for (size_t p = 0; p < D - 1 - d; ++p) { - pos *= static_cast(parSize[p]); - } - - index += pos; - } - return index; - } - -#if defined(NDEBUG) - template <> - inline size_t get_index_from_pos<2> (const Vector<2>& parPos, const Vector<2>& parSize) { - return parPos.y() * parSize.x() + parPos.x(); - } -#endif - - template - inline Vector buildPastEndCoordinate (const Vector& parFrom, const Vector& parTo) { - Vector retval; - for (size_t d = 0; d < D - 1; ++d) { - retval[d] = parFrom[d]; - } - retval[D - 1] = parTo[D - 1]; - return retval; - } - - template - inline const Vector& get_from_from_iterator (const TileIterator& parIterator) { - return parIterator.m_from; - } - } //namespace implem - template - TileIterator::TileIterator() : - m_pos(CoordinateScalarType()), - m_from(CoordinateScalarType()), - m_to(CoordinateScalarType()), - m_subdivareasize(CoordinateScalarType()), - m_data(nullptr), - m_subindex(0), - m_maxsubindex(0) - { - } - - template - TileIterator::TileIterator (qualif_vector_type* parData, const coords& parFrom, const coords& parTo) : - m_pos(parFrom), - m_from(parFrom), - m_to(parTo), - m_subdivareasize(parTo - parFrom), - m_data(parData), - m_subindex(0), - m_maxsubindex(0) + TileIterator::TileIterator (qualif_vector_type* parData, const coords& parArea) : + m_tile_range(parArea), + m_data(parData) { DK_ASSERT(parData); } template - TileIterator::TileIterator (qualif_vector_type* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo) : - m_pos(parFrom), - m_from(parFrom), - m_to(parTo), - m_subdivareasize(parAreaTo - parAreaFrom), - m_data(parData), - m_subindex(0), - m_maxsubindex(0) - { - DK_ASSERT(parData); - } - - template - TileIterator::TileIterator (qualif_vector_type* parData, const coords& parFrom, const coords& parTo, const coords& parAreaFrom, const coords& parAreaTo, const coords& parSubdiv) : - m_pos(parFrom), - m_from(parFrom), - m_to(parTo), - m_subdivareasize((parAreaTo - parAreaFrom) * parSubdiv), - m_data(parData), - m_subindex(0), - m_maxsubindex(implem::area(parSubdiv) - 1) + TileIterator::TileIterator (qualif_vector_type* parData, const coords& parStart, const coords& parArea) : + m_tile_range(parStart, parArea), + m_data(parData) { DK_ASSERT(parData); } template void TileIterator::increment() { - if (m_subindex < m_maxsubindex) { - ++m_subindex; - return; - } - - m_subindex = 0; - for (size_t d = 0; d < D - 1; ++d) { - ++m_pos[d]; - if (m_pos[d] >= m_to[d]) - m_pos[d] = m_from[d]; - else - return; - } - ++m_pos[D - 1]; + ++m_tile_range; } template void TileIterator::decrement() { - if (m_maxsubindex > 0 and m_subindex == 0) { - --m_subindex; - } - - m_subindex = m_maxsubindex; - for (size_t d = 0; d < D; ++d) { - if (m_pos[d] > m_from[d]) { - --m_pos[d]; - return; - } - else { - m_pos[d] = m_to[d]; - } - } - ++m_pos[D - 1]; + --m_tile_range; } template @@ -132,19 +32,29 @@ namespace dk { template ptrdiff_t TileIterator::distance_to (const TileIterator& parOther) { - return std::distance(this->get_current_index(), parOther.get_current_index()); + return std::distance(to_index(m_tile_range), to_index(parOther.m_tile_range)); } template bool TileIterator::equal (const TileIterator& parOther) const { - return m_data == parOther.m_data and m_pos == parOther.m_pos; + return m_data == parOther.m_data and m_tile_range == parOther.m_tile_range and m_tile_range == parOther.m_tile_range; } template T& TileIterator::dereference() const { - const auto index = this->get_current_index(); + const auto index = to_index(m_tile_range); DK_ASSERT(m_data); DK_ASSERT(index < m_data->size()); return (*m_data)[index]; } + + template + auto TileIterator::raw_coords() const -> const TileCoordsType& { + return m_tile_range; + } + + template + auto TileIterator::position() const -> const coords& { + return m_tile_range.position(); + } } //namespace dk diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index f85ee11..686d40a 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/../gtest-1.7.0/src/gtest_main.cc" tilecoords.cpp vector.cpp + tileiterator.cpp ) target_link_libraries(${PROJECT_NAME} diff --git a/test/unit/tileiterator.cpp b/test/unit/tileiterator.cpp new file mode 100644 index 0000000..d9fd96c --- /dev/null +++ b/test/unit/tileiterator.cpp @@ -0,0 +1,26 @@ +#include +#include "doorkeeper/components/tileiterator.hpp" +#include +#include +#include + +TEST(increment, tileiterator) { + typedef dk::TileIterator tileit7; + typedef dk::Vector<7> coords7; + + using boost::counting_iterator; + + std::vector data(counting_iterator(0), counting_iterator(100000)); + + { + const coords7 max_coords(99, 999, 2, 2, 2, 2, 2); + tileit7 it(&data, max_coords); + + for (std::size_t z = 0; z < data.size(); ++z) { + EXPECT_EQ(data[z], *it); + ++it; + } + + EXPECT_EQ(coords7(0, 0, 1, 0, 0, 0, 0), it.position()); + } +}