Skip to content

Instantly share code, notes, and snippets.

@adrian17
Last active August 29, 2015 14:21
Show Gist options
  • Save adrian17/94f0eb6204335377aec6 to your computer and use it in GitHub Desktop.
Save adrian17/94f0eb6204335377aec6 to your computer and use it in GitHub Desktop.
each_cons in C++
#include <utility>
namespace detail
{
template <typename Fun>
struct function_params
: public function_params<decltype(&Fun::operator())>
{};
template <typename Class, typename Ret, typename... Args> // for lambdas
struct function_params<Ret(Class::*)(Args...) const> {
static constexpr int n_args = sizeof...(Args);
};
template <typename Class, typename Ret, typename... Args> // for mutable lambdas
struct function_params<Ret(Class::*)(Args...)> {
static constexpr int n_args = sizeof...(Args);
};
template <typename Ret, typename... Args> // for function pointers
struct function_params<Ret(*)(Args...)> {
static constexpr int n_args = sizeof...(Args);
};
template<typename It, typename Fun, int N = function_params<Fun>::n_args, std::size_t... I>
void for_each_cons_impl(It first, It last, Fun f, std::index_sequence<I...>) {
for(auto it = first; it + N - 1 < last; ++it)
f(*(it + I)...);
}
template<typename It, typename Fun, int N = function_params<Fun>::n_args, typename Indices = std::make_index_sequence<N>>
void for_each_cons(It first, It last, Fun f) {
for_each_cons_impl(first, last, f, Indices());
}
template<typename It, typename Fun, int N = function_params<Fun>::n_args, std::size_t... I>
void for_each_slice_impl(It first, It last, Fun f, std::index_sequence<I...>) {
for(auto it = first; it + N - 1 < last; it += N)
f(*(it + I)...);
}
template<typename It, typename Fun, int N = function_params<Fun>::n_args, typename Indices = std::make_index_sequence<N>>
void for_each_slice(It first, It last, Fun f) {
for_each_slice_impl(first, last, f, Indices());
}
}
template<typename It, typename Fun>
void for_each_cons(It first, It last, Fun f) {
detail::for_each_cons(first, last, f);
}
template<typename Rng, typename Fun>
void for_each_cons(Rng &&rng, Fun f) {
for_each_cons(rng.begin(), rng.end(), f);
}
template<typename It, typename Fun>
void for_each_slice(It first, It last, Fun f) {
detail::for_each_slice(first, last, f);
}
template<typename Rng, typename Fun>
void for_each_slice(Rng &&rng, Fun f) {
detail::for_each_slice(rng.begin(), rng.end(), f);
}
#include "each_cons.h"
#include <vector>
#include <cstdio>
void example_cons(const std::vector<int> &vec) {
for_each_cons(vec, [](int a, int b, int c){
printf("%d %d %d\n", a, b, c);
});
}
void example_slice(const std::vector<int> &vec) {
for_each_slice(vec, [](int a, int b, int c){
printf("%d %d %d\n", a, b, c);
});
}
int main() {
const std::vector<int> vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
example_cons(vec);
printf("\n");
example_slice(vec);
}
/*
Outputs:
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
0 1 2
3 4 5
6 7 8
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment