Created
December 28, 2017 11:54
-
-
Save Holt59/24c09c94245b1a25966122474d44c321 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
#include <array> | |
template<class T, size_t size, size_t... sizes> | |
struct MArr { | |
constexpr static std::size_t ndims = sizeof...(sizes) + 1; | |
typedef std::array<typename MArr<T, sizes...>::type, size> type; | |
std::array<MArr<T, sizes...>,size> data; | |
const T& operator[](const size_t (&idx)[ndims]) const { | |
return access_ptr(idx); | |
} | |
protected: | |
const T& access_ptr(const size_t *idx) const { | |
return data[*idx].access_ptr(idx + 1); | |
} | |
}; | |
template<class T, size_t size> | |
struct MArr<T, size> { | |
constexpr static std::size_t ndims = 1; | |
typedef std::array<T, size> type; | |
type data; | |
const T& operator[](const size_t (&idx)[ndims]) const { | |
return data[idx[0]]; | |
} | |
protected: | |
const T& access_ptr(const size_t *idx) const { | |
return data[*idx]; | |
} | |
template <class, size_t, size_t...> | |
friend struct MArr; | |
}; | |
template <class T, std::size_t... Sizes, class F, class... Is, | |
std::size_t... IsP2N, std::size_t... IsP2NN> | |
auto around_impl(MArr<T, Sizes...> const& arr, | |
std::index_sequence<IsP2N...>, | |
std::index_sequence<IsP2NN...>, | |
F &&f, Is&&... pt) { | |
const std::size_t pts[] = {(std::size_t)pt... }; | |
const std::size_t pts2[2 * sizeof...(Sizes)][sizeof...(Sizes)] = { | |
(pts[IsP2NN % sizeof...(Sizes)] | |
+ (1 - 2 * ((IsP2NN / sizeof...(Sizes)) % 2)) | |
* (IsP2NN % sizeof...(Sizes) == IsP2NN / (2 * sizeof...(Sizes))))... | |
}; | |
return f(arr[pts2[IsP2N]]... ); | |
} | |
template <class T, std::size_t... Sizes, class F, class... Is> | |
auto around(MArr<T, Sizes...> const& arr, F &&f, Is&&... pt) { | |
return around_impl(arr, | |
std::make_index_sequence<2 * sizeof...(Sizes)>{}, | |
std::make_index_sequence<2 * sizeof...(Sizes) * sizeof...(Sizes)>{}, | |
std::forward<F>(f), | |
std::forward<Is>(pt)... ); | |
} | |
int main() { | |
MArr<int, 3, 3> arr; | |
around(arr, | |
[](int a, int b, int c, int d) { return a + b + c + d; }, | |
1, 1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment