Created
December 20, 2023 09:13
-
-
Save comefrombottom/697f41af89bbfbb92bf9feda08aac51f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
namespace s3d { | |
class Step3D | |
{ | |
public: | |
class Iterator | |
{ | |
public: | |
SIV3D_NODISCARD_CXX20 | |
constexpr Iterator() noexcept | |
: m_countX{ 0 } | |
, m_countY{ 0 } | |
, m_startX{ 0 } | |
, m_startY{ 0 } | |
, m_step_counter{ 0, 0, 0 } | |
, m_counter{ 0, 0, 0 } | |
, m_step{ 0, 0, 0 } {} | |
SIV3D_NODISCARD_CXX20 | |
constexpr Iterator(Point3D steps_count, Point3D start, Point3D step) noexcept | |
: m_countX{ steps_count.x } | |
, m_countY{ steps_count.y } | |
, m_startX{ start.x } | |
, m_startY{ start.y } | |
, m_step_counter{ steps_count } | |
, m_counter{ start } | |
, m_step{ step } {} | |
constexpr Iterator& operator ++() noexcept | |
{ | |
if (m_step_counter.x == 1) | |
{ | |
if (m_step_counter.y == 1) | |
{ | |
m_step_counter.y = m_countY; | |
--m_step_counter.z; | |
m_counter.y = m_startY; | |
m_counter.z = m_counter.z + m_step.z; | |
} | |
else | |
{ | |
--m_step_counter.y; | |
m_counter.y = m_counter.y + m_step.y; | |
} | |
m_step_counter.x = m_countX; | |
m_counter.x = m_startX; | |
} | |
else | |
{ | |
--m_step_counter.x; | |
m_counter.x = m_counter.x + m_step.x; | |
} | |
return *this; | |
} | |
constexpr Iterator operator ++(int) noexcept { | |
Iterator it = *this; | |
++(*this); | |
return it; | |
} | |
[[nodiscard]] | |
constexpr const Point3D& operator *() const noexcept { | |
return m_counter; | |
} | |
[[nodiscard]] | |
constexpr const Point3D* operator ->() const noexcept { | |
return &m_counter; | |
} | |
[[nodiscard]] | |
constexpr bool operator ==(const Iterator& r) const noexcept { | |
return m_step_counter == r.m_step_counter; | |
} | |
[[nodiscard]] | |
constexpr bool operator !=(const Iterator& r) const noexcept { | |
return !(m_step_counter == r.m_step_counter); | |
} | |
private: | |
int32 m_countX; | |
int32 m_countY; | |
int32 m_startX; | |
int32 m_startY; | |
Point3D m_step_counter; | |
Point3D m_counter; | |
Point3D m_step; | |
}; | |
using iterator = Iterator; | |
SIV3D_NODISCARD_CXX20 | |
constexpr Step3D(Point3D start, Point3D step_count, Point3D step) noexcept | |
: m_start{ start } | |
, m_step_count{ step_count } | |
, m_step_length{ step } | |
, m_end_iterator{ { step_count.x, step_count.y, 0 }, Point3D{ 0, 0, 0 }, Point3D{ 0, 0, 0 } } | |
, m_start_iterator{ step_count, start, step } {} | |
[[nodiscard]] | |
constexpr iterator begin() const noexcept { | |
return m_start_iterator; | |
} | |
[[nodiscard]] | |
constexpr iterator end() const noexcept { | |
return m_end_iterator; | |
} | |
[[nodiscard]] | |
constexpr Point3D startValue() const noexcept { | |
return m_start; | |
} | |
[[nodiscard]] | |
constexpr Point3D count() const noexcept { | |
return m_step_count; | |
} | |
[[nodiscard]] | |
constexpr int32 num_elements() const noexcept { | |
return (m_step_count.x * m_step_count.y * m_step_count.z); | |
} | |
[[nodiscard]] | |
constexpr Point3D step() const noexcept { | |
return m_step_length; | |
} | |
[[nodiscard]] | |
constexpr bool isEmpty() const noexcept { | |
return ((m_step_count.x == 0) | |
|| (m_step_count.y == 0) | |
|| (m_step_count.z == 0)); | |
} | |
/// @brief 範囲の値を配列に変換します。 | |
/// @return 配列 | |
[[nodiscard]] | |
Array<Point3D> asArray() const { | |
Array<Point3D> new_array; | |
if (isEmpty()) | |
{ | |
return new_array; | |
} | |
new_array.reserve(num_elements()); | |
for (auto it = m_start_iterator; it != m_end_iterator; ++it) | |
{ | |
new_array.push_back(*it); | |
} | |
return new_array; | |
} | |
private: | |
Point3D m_start; | |
Point3D m_step_count; | |
Point3D m_step_length; | |
iterator m_end_iterator; | |
iterator m_start_iterator; | |
}; | |
inline constexpr auto step(const Point3D n) noexcept | |
{ | |
return Step3D{ Point3D{ 0, 0, 0 }, n, Point3D{ 1, 1, 1 } }; | |
} | |
inline constexpr auto step(const Point3D a, const Point3D n) noexcept | |
{ | |
return Step3D{ a, n, Point3D{ 1, 1, 1 } }; | |
} | |
inline constexpr auto step(const Point3D a, const Point3D n, const Point3D s) noexcept | |
{ | |
return Step3D{ a, n, s }; | |
} | |
inline constexpr auto step_backward(const Point3D n) noexcept | |
{ | |
return Step3D{ Point3D{ (n.x - 1), (n.y - 1), (n.z - 1) }, n, Point3D{ -1, -1, -1 } }; | |
} | |
inline constexpr auto Iota3D(const Point3D end) noexcept | |
{ | |
return Step3D{ Point3D{ 0, 0, 0 }, end, Point3D{ 1, 1, 1 } }; | |
} | |
inline constexpr auto Iota3D(const int32 xEnd, const int32 yEnd, const int32 zEnd) noexcept | |
{ | |
return Iota3D(Point3D{ xEnd, yEnd, zEnd }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment