Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tomilov/2dcde5b0a75cc778e5a5 to your computer and use it in GitHub Desktop.
Save tomilov/2dcde5b0a75cc778e5a5 to your computer and use it in GitHub Desktop.
#include <utility>
template< typename F, std::size_t ...indices >
struct enumerator
{
static constexpr const std::size_t size_ = sizeof...(indices);
static constexpr const std::size_t count_ = (indices * ...);
template< typename I >
struct decomposer;
template< std::size_t ...I >
struct decomposer< std::index_sequence< I... > >
{
F & f;
static constexpr const std::size_t indices_[size_] = {indices...};
static
constexpr
std::size_t
order(std::size_t const i)
{
std::size_t o = 1;
for (std::size_t n = i + 1; n < size_; ++n) {
o *= indices_[n];
}
return o;
}
static constexpr std::size_t const orders_[size_] = {order(I)...};
static
constexpr
std::size_t
digit(std::size_t c, std::size_t const i)
{
for (std::size_t n = 0; n < i; ++n) {
c = c % orders_[n];
}
return c / orders_[i];
}
template< std::size_t c >
constexpr
bool
call() const
{
return f.template operator () < digit(c, I)... >(); // error here
}
};
decomposer< std::make_index_sequence< size_ > > decomposer_;
constexpr
bool
operator () () const
{
return call(std::make_index_sequence< count_ >{});
}
template< std::size_t ...counter >
constexpr
bool
call(std::index_sequence< counter... >) const
{
return (decomposer_.template call< counter >() && ...);
}
};
#include <iterator>
#include <iostream>
#include <initializer_list>
#include <algorithm>
#include <cstdlib>
struct print
{
template< std::size_t ...indices >
constexpr
bool
operator () () const
{
for (std::size_t const i : {indices...}) {
std::cout << i << ' ';
}
std::cout << std::endl;
return true;
}
};
int
main()
{
print const print_{};
enumerator< print const, 11, 7, 3 >{{print_}}();
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment