14#ifndef MORTON_ITERATE_HPP
15#define MORTON_ITERATE_HPP
26template <
unsigned Dim,
unsigned Bits,
typename Fn>
30 using coord =
typename M::coord_type;
32 for (
unsigned d = 0; d < Dim; ++d)
36 M cur = M::encode(lo);
37 std::array<coord, Dim> idx = lo;
42 for (; d < Dim; ++d) {
64template <
unsigned Dim,
unsigned Bits>
69 using code =
typename M::code_type;
72 for (
int i =
int(M::code_bits) - 1; i >= 0; --i) {
73 const unsigned d = unsigned(i) % Dim;
74 const code bit = code(1) << i;
75 const code same_dim_below = M::axis_mask(d) & (bit - 1);
77 const int zb = int((z >> i) & 1);
78 const int lb = int((zmin >> i) & 1);
79 const int hb = int((zmax >> i) & 1);
81 if (!zb && !lb && !hb) {
83 }
else if (!zb && !lb && hb) {
84 result = (zmin & ~same_dim_below) | bit;
85 zmax = (zmax & ~bit) | same_dim_below;
86 }
else if (!zb && lb && hb) {
88 }
else if (zb && !lb && !hb) {
90 }
else if (zb && !lb && hb) {
91 zmin = (zmin & ~same_dim_below) | bit;
106template <
unsigned Dim,
unsigned Bits>
113 using code =
typename M::code_type;
117 for (
int i =
int(M::code_bits) - 1; i >= 0; --i) {
118 const unsigned d = unsigned(i) % Dim;
119 const code bit = code(1) << i;
120 const code below = M::axis_mask(d) & (bit - 1);
122 const int zb = int((z >> i) & 1);
123 const int lb = int((zmin >> i) & 1);
124 const int hb = int((zmax >> i) & 1);
125 const int v = (zb << 2) | (lb << 1) | hb;
132 bigmin = (zmin & ~below) | bit;
133 zmax = (zmax & ~bit) | below;
142 litmax = (zmax & ~bit) | below;
143 zmin = (zmin & ~below) | bit;
155template <
unsigned Dim,
unsigned Bits>
160 const auto zmin = M::encode(lo).
code();
161 const auto zmax = M::encode(hi).code();
162 if (probe.
code() >= zmax)
164 typename M::code_type lm, bm;
165 detail::litmax_bigmin<Dim, Bits>(zmin, zmax, probe.
code(), lm, bm);
166 out = M::from_code(bm);
172template <
unsigned Dim,
unsigned Bits>
177 const auto zmin = M::encode(lo).
code();
178 const auto zmax = M::encode(hi).code();
179 if (probe.
code() <= zmin)
181 typename M::code_type lm, bm;
182 detail::litmax_bigmin<Dim, Bits>(zmin, zmax, probe.
code(), lm, bm);
183 out = M::from_code(lm);
188template <
unsigned Dim,
unsigned Bits>
192 for (
unsigned d = 0; d < Dim; ++d) {
194 if (c < lo[d] || c > hi[d])
202template <
unsigned Dim,
unsigned Bits,
typename Fn>
207 using code =
typename M::code_type;
209 for (
unsigned d = 0; d < Dim; ++d)
213 const code zmin = M::encode(lo).
code();
214 const code zmax = M::encode(hi).code();
218 M m = M::from_code(z);
219 if (in_box<Dim, Bits>(lo, hi, m)) {
226 detail::litmax_bigmin<Dim, Bits>(zmin, zmax, z, lm, next);
A Morton (Z-order) code interleaving Dim unsigned coordinates of Bits bits each.
Definition morton.hpp:203
detail::uint_for_t< Bits > coord_type
Definition morton.hpp:215
MORTON_HD constexpr code_type code() const noexcept
Definition morton.hpp:265
detail::uint_for_t< Dim *Bits > code_type
Definition morton.hpp:214
MORTON_HD constexpr coord_type get(unsigned d) const
Decode coordinate of a single axis.
Definition morton.hpp:268
#define MORTON_HD
Definition hd.hpp:27
Core Morton<Dim,Bits> type — Z-order codes with O(1) arithmetic in Morton space.
MORTON_HD Morton< Dim, Bits >::code_type bigmin(typename Morton< Dim, Bits >::code_type zmin, typename Morton< Dim, Bits >::code_type zmax, typename Morton< Dim, Bits >::code_type z)
Definition iterate.hpp:65
MORTON_HD void litmax_bigmin(typename Morton< Dim, Bits >::code_type zmin, typename Morton< Dim, Bits >::code_type zmax, typename Morton< Dim, Bits >::code_type z, typename Morton< Dim, Bits >::code_type &litmax, typename Morton< Dim, Bits >::code_type &bigmin)
Definition iterate.hpp:107
bool litmax_in_box(const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &lo, const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &hi, Morton< Dim, Bits > probe, Morton< Dim, Bits > &out)
Largest Morton code in the inclusive box [lo, hi] that is strictly less than probe.
Definition iterate.hpp:173
void for_each_in_box_zorder(const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &lo, const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &hi, Fn &&fn)
Visit every cell of the inclusive box [lo, hi] in Z-order (increasing Morton code),...
Definition iterate.hpp:203
void for_each_in_box(const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &lo, const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &hi, Fn &&fn)
Visit every cell of the inclusive box [lo, hi] in row-major order (axis 0 varies fastest).
Definition iterate.hpp:27
bool bigmin_in_box(const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &lo, const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &hi, Morton< Dim, Bits > probe, Morton< Dim, Bits > &out)
Smallest Morton code in the inclusive box [lo, hi] that is strictly greater than probe.
Definition iterate.hpp:156
MORTON_HD bool in_box(const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &lo, const std::array< typename Morton< Dim, Bits >::coord_type, Dim > &hi, Morton< Dim, Bits > m)
Test whether m lies inside the inclusive box [lo, hi].
Definition iterate.hpp:189