Add implementation for operator-=
This commit is contained in:
parent
28fc001540
commit
a1996b2d75
4 changed files with 93 additions and 4 deletions
|
@ -6,6 +6,8 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace dk {
|
namespace dk {
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
|
@ -32,6 +34,9 @@ namespace dk {
|
||||||
const CoordinateScalarType& operator[] ( int parIndex ) const;
|
const CoordinateScalarType& operator[] ( int parIndex ) const;
|
||||||
CoordinateScalarType& operator[] ( int parIndex );
|
CoordinateScalarType& operator[] ( int parIndex );
|
||||||
|
|
||||||
|
const coords& position ( void ) const;
|
||||||
|
const coords& upper ( void ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
coords m_pos;
|
coords m_pos;
|
||||||
coords m_size;
|
coords m_size;
|
||||||
|
@ -40,6 +45,8 @@ namespace dk {
|
||||||
namespace implem {
|
namespace implem {
|
||||||
CoordinateScalarType sum_mod ( CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv ) a_pure;
|
CoordinateScalarType sum_mod ( CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv ) a_pure;
|
||||||
CoordinateScalarType sum_div ( CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv ) a_pure;
|
CoordinateScalarType sum_div ( CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv ) a_pure;
|
||||||
|
CoordinateScalarType sub_mod ( CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv ) a_pure;
|
||||||
|
CoordinateScalarType sub_div ( CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv ) a_pure;
|
||||||
} //namespace implem
|
} //namespace implem
|
||||||
} //namespace dk
|
} //namespace dk
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,25 @@ namespace dk {
|
||||||
///Equivalent to (parA + parB) / parDiv
|
///Equivalent to (parA + parB) / parDiv
|
||||||
///----------------------------------------------------------------------
|
///----------------------------------------------------------------------
|
||||||
inline CoordinateScalarType sum_div (CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv) {
|
inline CoordinateScalarType sum_div (CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv) {
|
||||||
|
DK_ASSERT(parA >= 0 and parB >= 0 and parDiv > 0);
|
||||||
|
DK_ASSERT(std::numeric_limits<CoordinateScalarType>::max() - (parA % parDiv) >= (parB % parDiv));
|
||||||
const auto x = ((parA % parDiv) + (parB % parDiv)) / parDiv;
|
const auto x = ((parA % parDiv) + (parB % parDiv)) / parDiv;
|
||||||
|
DK_ASSERT(std::numeric_limits<CoordinateScalarType>::max() - parA / parDiv >= parB / parDiv);
|
||||||
|
DK_ASSERT(std::numeric_limits<CoordinateScalarType>::max() - parA / parDiv - parB / parDiv >= x);
|
||||||
return parA / parDiv + parB / parDiv + x;
|
return parA / parDiv + parB / parDiv + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline CoordinateScalarType sub_mod (CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv) {
|
||||||
|
typedef std::make_unsigned<CoordinateScalarType>::type unsigned_coord;
|
||||||
|
const unsigned_coord rounded_sum = static_cast<unsigned_coord>(sub_div(parA, parB, parDiv) * parDiv);
|
||||||
|
const unsigned_coord ret = static_cast<unsigned_coord>(parA) - rounded_sum - static_cast<unsigned_coord>(parB);
|
||||||
|
return static_cast<CoordinateScalarType>(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CoordinateScalarType sub_div (CoordinateScalarType parA, CoordinateScalarType parB, CoordinateScalarType parDiv) {
|
||||||
|
const auto x = ((parA % parDiv) + (parB % parDiv)) / parDiv;
|
||||||
|
return parA / parDiv - parB / parDiv + x;
|
||||||
|
}
|
||||||
} //namespace implem
|
} //namespace implem
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
|
@ -86,6 +102,34 @@ namespace dk {
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
const TileCoords<D>& TileCoords<D>::operator-= (CoordinateScalarType parValue) {
|
||||||
|
std::size_t index = 0;
|
||||||
|
if (parValue > 0) {
|
||||||
|
while (parValue) {
|
||||||
|
const auto t = parValue % (m_size[index] + 1);
|
||||||
|
DK_ASSERT(t >= 0);
|
||||||
|
const CoordinateScalarType r = (t > m_pos[index] ? 1 : 0);
|
||||||
|
m_pos[index] = (m_size[index] + 1) * r + m_pos[index] - t;
|
||||||
|
parValue /= (m_size[index] + 1);
|
||||||
|
parValue += r;
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (parValue < 0) {
|
||||||
|
while (parValue) {
|
||||||
|
const auto new_pos = implem::sub_mod(m_pos[index], parValue, m_size[index] + 1);
|
||||||
|
parValue = -implem::sub_div(m_pos[index], parValue, m_size[index] + 1);
|
||||||
|
m_pos[index] = new_pos;
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <uint32_t D>
|
template <uint32_t D>
|
||||||
const TileCoords<D>& TileCoords<D>::operator+= (CoordinateScalarType parValue) {
|
const TileCoords<D>& TileCoords<D>::operator+= (CoordinateScalarType parValue) {
|
||||||
std::size_t index = 0;
|
std::size_t index = 0;
|
||||||
|
@ -143,4 +187,14 @@ namespace dk {
|
||||||
DK_ASSERT(static_cast<uint32_t>(parIndex) < D);
|
DK_ASSERT(static_cast<uint32_t>(parIndex) < D);
|
||||||
return m_pos[parIndex];
|
return m_pos[parIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
auto TileCoords<D>::position() const -> const coords& {
|
||||||
|
return m_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <uint32_t D>
|
||||||
|
auto TileCoords<D>::upper() const -> const coords& {
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
} //namespace dk
|
} //namespace dk
|
||||||
|
|
|
@ -90,6 +90,11 @@ TEST(advance, tilecoords) {
|
||||||
EXPECT_EQ(1201, test[2]);
|
EXPECT_EQ(1201, test[2]);
|
||||||
EXPECT_EQ(710, test[3]);
|
EXPECT_EQ(710, test[3]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(back_forward, tilecoords) {
|
||||||
|
typedef dk::TileCoords<4> tcoords4;
|
||||||
|
typedef dk::TileCoords<4>::coords coords4;
|
||||||
|
|
||||||
{
|
{
|
||||||
const coords4 max_coords(32);
|
const coords4 max_coords(32);
|
||||||
|
@ -111,4 +116,27 @@ TEST(advance, tilecoords) {
|
||||||
test += -33 * 33 * 2;
|
test += -33 * 33 * 2;
|
||||||
EXPECT_EQ(tcoords4(max_coords), test);
|
EXPECT_EQ(tcoords4(max_coords), test);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const coords4 max_coords(5300, 2499, 12631, 171244);
|
||||||
|
tcoords4 test(max_coords);
|
||||||
|
|
||||||
|
test += 5000000;
|
||||||
|
EXPECT_EQ(coords4(1157, 943, 0, 0), test.position());
|
||||||
|
|
||||||
|
test -= 3350000;
|
||||||
|
EXPECT_EQ(coords4(1389, 311, 0, 0), test.position());
|
||||||
|
|
||||||
|
test += 50000000 - 5000000 + 3350000;
|
||||||
|
EXPECT_EQ(coords4(968, 1932, 3, 0), test.position());
|
||||||
|
|
||||||
|
test -= 900;
|
||||||
|
EXPECT_EQ(coords4(68, 1932, 3, 0), test.position());
|
||||||
|
|
||||||
|
test += 5300 + 1;
|
||||||
|
EXPECT_EQ(coords4(68, 1933, 3, 0), test.position());
|
||||||
|
|
||||||
|
test -= -5302;
|
||||||
|
EXPECT_EQ(coords4(69, 1934, 3, 0), test.position());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
M = 2147483647
|
M = 2147483647
|
||||||
|
|
||||||
def calc(arr, m)
|
def calc(v, arr, m)
|
||||||
v = M
|
|
||||||
index = 0
|
index = 0
|
||||||
out = arr.dup
|
out = arr.dup
|
||||||
while (v > 0) do
|
while (v > 0) do
|
||||||
|
@ -16,5 +15,6 @@ def calc(arr, m)
|
||||||
out
|
out
|
||||||
end
|
end
|
||||||
|
|
||||||
p calc([540, 800, 1200, 710], [M - 10, M - 11, M - 12, M - 13])
|
p calc(M, [540, 800, 1200, 710], [M - 10, M - 11, M - 12, M - 13])
|
||||||
p calc([M - 1, 800, 1200, 710], [M - 1, 800, M - 1, M - 1])
|
p calc(M, [M - 1, 800, 1200, 710], [M - 1, 800, M - 1, M - 1])
|
||||||
|
p calc(1650000, [0, 0, 0, 0], [5300, 2499, 12631, 171244])
|
||||||
|
|
Loading…
Add table
Reference in a new issue