#include <cstdint>
constexpr uint32_t pow(const uint32_t base, const uint32_t exponent)
{
return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
}
constexpr uint32_t log2(const uint32_t n, const uint32_t p = 0) {
return (n <= 1) ? p : log2(n / 2, p + 1);
}
constexpr bool isPowerOf2(const uint32_t uInput)
{
return uInput == 0 ? false : ((uInput & (uInput - 1)) == 0);
}
//TODO replace sizeof...(I) with std::index_sequence<I...>::size() #include <utility>
//TODO replace std::integral_constant<int,D> with int2type<D> (and 'int D' → 'std::size_t D') if needed
// template<std::size_t> struct int2type{};
#include <array>
#include <type_traits>
//Base case for depth==0
template<int Head, int... Tail>
constexpr std::array<int, sizeof...(Tail)> create_morton_delta_table(std::integral_constant<int,0>)
{
return std::array<int, sizeof...(Tail)>{Tail...};
}
template<int Head=1, int... Tail, int Depth>
constexpr std::array<int, pow(2,Depth)*(sizeof...(Tail)+1)-1> create_morton_delta_table(std::integral_constant<int,Depth>)
{
return create_morton_delta_table<Head+6*pow(sizeof...(Tail)+1,3), Tail..., Head, Tail...>(std::integral_constant<int,Depth-1>{});
}
//Helper function
template<int Size>
constexpr std::array<int, Size-1> morton_delta_table()
{
static_assert(isPowerOf2(Size), "Morton delta table can only be generated for powers of two");
static_assert(Size>1, "Morton delta table can only be generated for a size>1");
return create_morton_delta_table(std::integral_constant<int,log2(Size)>{});
}
#include <iostream>
int main(int argc, char **argv) {
constexpr auto d = morton_delta_table<32>();
for(const int& i : d)
{
std::cout << i << std::endl;
}
return 0;
}
I2luY2x1ZGUgPGNzdGRpbnQ+Cgpjb25zdGV4cHIgdWludDMyX3QgcG93KGNvbnN0IHVpbnQzMl90IGJhc2UsIGNvbnN0IHVpbnQzMl90IGV4cG9uZW50KQp7CiAgICByZXR1cm4gKGV4cG9uZW50ID09IDApID8gMSA6IChiYXNlICogcG93KGJhc2UsIGV4cG9uZW50LTEpKTsKfQoKY29uc3RleHByIHVpbnQzMl90IGxvZzIoY29uc3QgdWludDMyX3QgbiwgY29uc3QgdWludDMyX3QgcCA9IDApIHsKICAgIHJldHVybiAobiA8PSAxKSA/IHAgOiBsb2cyKG4gLyAyLCBwICsgMSk7Cn0KCmNvbnN0ZXhwciBib29sIGlzUG93ZXJPZjIoY29uc3QgdWludDMyX3QgdUlucHV0KQp7CglyZXR1cm4gdUlucHV0ID09IDAgPyBmYWxzZSA6ICgodUlucHV0ICYgKHVJbnB1dCAtIDEpKSA9PSAwKTsKfQoKLy9UT0RPIHJlcGxhY2Ugc2l6ZW9mLi4uKEkpIHdpdGggc3RkOjppbmRleF9zZXF1ZW5jZTxJLi4uPjo6c2l6ZSgpICNpbmNsdWRlIDx1dGlsaXR5PgovL1RPRE8gcmVwbGFjZSBzdGQ6OmludGVncmFsX2NvbnN0YW50PGludCxEPiB3aXRoIGludDJ0eXBlPEQ+IChhbmQgJ2ludCBEJyDihpIgJ3N0ZDo6c2l6ZV90IEQnKSBpZiBuZWVkZWQKLy8gICAgIHRlbXBsYXRlPHN0ZDo6c2l6ZV90PiBzdHJ1Y3QgaW50MnR5cGV7fTsKCiNpbmNsdWRlIDxhcnJheT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKLy9CYXNlIGNhc2UgZm9yIGRlcHRoPT0wCnRlbXBsYXRlPGludCBIZWFkLCBpbnQuLi4gVGFpbD4KY29uc3RleHByIHN0ZDo6YXJyYXk8aW50LCBzaXplb2YuLi4oVGFpbCk+IGNyZWF0ZV9tb3J0b25fZGVsdGFfdGFibGUoc3RkOjppbnRlZ3JhbF9jb25zdGFudDxpbnQsMD4pCnsKCXJldHVybiBzdGQ6OmFycmF5PGludCwgc2l6ZW9mLi4uKFRhaWwpPntUYWlsLi4ufTsKfQoKdGVtcGxhdGU8aW50IEhlYWQ9MSwgaW50Li4uIFRhaWwsIGludCBEZXB0aD4KY29uc3RleHByIHN0ZDo6YXJyYXk8aW50LCBwb3coMixEZXB0aCkqKHNpemVvZi4uLihUYWlsKSsxKS0xPiBjcmVhdGVfbW9ydG9uX2RlbHRhX3RhYmxlKHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8aW50LERlcHRoPikKewoJcmV0dXJuIGNyZWF0ZV9tb3J0b25fZGVsdGFfdGFibGU8SGVhZCs2KnBvdyhzaXplb2YuLi4oVGFpbCkrMSwzKSwgVGFpbC4uLiwgSGVhZCwgVGFpbC4uLj4oc3RkOjppbnRlZ3JhbF9jb25zdGFudDxpbnQsRGVwdGgtMT57fSk7Cn0KCi8vSGVscGVyIGZ1bmN0aW9uCnRlbXBsYXRlPGludCBTaXplPgpjb25zdGV4cHIgc3RkOjphcnJheTxpbnQsIFNpemUtMT4gbW9ydG9uX2RlbHRhX3RhYmxlKCkKewoJc3RhdGljX2Fzc2VydChpc1Bvd2VyT2YyKFNpemUpLCAiTW9ydG9uIGRlbHRhIHRhYmxlIGNhbiBvbmx5IGJlIGdlbmVyYXRlZCBmb3IgcG93ZXJzIG9mIHR3byIpOwoJc3RhdGljX2Fzc2VydChTaXplPjEsICJNb3J0b24gZGVsdGEgdGFibGUgY2FuIG9ubHkgYmUgZ2VuZXJhdGVkIGZvciBhIHNpemU+MSIpOwoJcmV0dXJuIGNyZWF0ZV9tb3J0b25fZGVsdGFfdGFibGUoc3RkOjppbnRlZ3JhbF9jb25zdGFudDxpbnQsbG9nMihTaXplKT57fSk7Cn0KCiNpbmNsdWRlIDxpb3N0cmVhbT4KCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikgewoJY29uc3RleHByIGF1dG8gZCA9IG1vcnRvbl9kZWx0YV90YWJsZTwzMj4oKTsKCQoJZm9yKGNvbnN0IGludCYgaSA6IGQpCgl7CgkJc3RkOjpjb3V0IDw8IGkgPDwgc3RkOjplbmRsOwoJfQogICAgcmV0dXJuIDA7Cn0K