18 #ifndef NDARRAY_Z_ORDER_H 19 #define NDARRAY_Z_ORDER_H 30 inline index_t next_power_of_two(index_t x) {
40 template <
size_t Rank,
class Fn>
41 NDARRAY_UNIQUE
void for_each_index_in_z_order_impl(
const std::array<index_t, Rank>& end,
42 std::array<index_t, Rank> z, index_t dim, index_t step,
const Fn& fn) {
43 if (dim == 0 && step == 1) {
50 }
else if (dim == 0) {
53 for_each_index_in_z_order_impl(end, z, Rank - 1, step >> 1, fn);
56 for_each_index_in_z_order_impl(end, z, Rank - 1, step >> 1, fn);
60 for_each_index_in_z_order_impl(end, z, dim - 1, step, fn);
62 if (z[dim] < end[dim]) {
63 for_each_index_in_z_order_impl(end, z, dim - 1, step, fn);
70 template <
class Extents,
class Fn>
71 NDARRAY_UNIQUE
void for_each_index_in_z_order(
const Extents& extents,
const Fn& fn) {
72 constexpr
index_t Rank = std::tuple_size<Extents>::value;
74 const auto end = tuple_to_array<index_t>(extents, make_index_sequence<Rank>());
75 const index_t max_extent = *std::max_element(end.begin(), end.end());
76 const index_t step = std::max<index_t>(1, next_power_of_two(max_extent) >> 1);
77 std::array<index_t, Rank> z = {{0,}};
78 for_each_index_in_z_order_impl(end, z, Rank - 1, step, fn);
81 template <
class... Ranges,
class Fn,
size_t... Is>
82 NDARRAY_UNIQUE
void for_each_in_z_order_impl(
83 const std::tuple<Ranges...>& ranges,
const Fn& fn, index_sequence<Is...>) {
84 constexpr
size_t Rank =
sizeof...(Is);
85 std::array<index_t, Rank> extents = {
86 {(std::end(std::get<Is>(ranges)) - std::begin(std::get<Is>(ranges)))...}};
87 for_each_index_in_z_order(extents, [&](
const std::array<index_t, Rank>& i) {
88 fn(std::make_tuple(*(std::begin(std::get<Is>(ranges)) + std::get<Is>(i))...));
98 template <
class... Ranges,
class Fn>
100 const std::tuple<Ranges...>& ranges,
const Fn& fn) {
101 internal::for_each_in_z_order_impl(
102 ranges, fn, internal::make_index_sequence<
sizeof...(Ranges)>());
104 template <
class Fn,
class... Ranges>
105 NDARRAY_UNIQUE
void for_all_in_z_order(
106 const std::tuple<Ranges...>& ranges,
const Fn& fn) {
107 internal::for_each_in_z_order_impl(
108 ranges, [&](
const auto& i) { internal::apply(fn, i); },
109 internal::make_index_sequence<
sizeof...(Ranges)>());
114 #endif // NDARRAY_Z_ORDER_H NDARRAY_UNIQUE void for_each_in_z_order(const std::tuple< Ranges... > &ranges, const Fn &fn)
Definition: z_order.h:99
Main header for array library.
std::ptrdiff_t index_t
Definition: array.h:87