Skip to content

Instantly share code, notes, and snippets.

@plasma-effect
Last active November 13, 2016 14:51
Show Gist options
  • Save plasma-effect/1ee536a07b42f223cfe91e714f64fef8 to your computer and use it in GitHub Desktop.
Save plasma-effect/1ee536a07b42f223cfe91e714f64fef8 to your computer and use it in GitHub Desktop.
ジャパニーズ結構迷惑コード(コンパイル時エラトステネス)
#include<iostream>
#include<type_traits>
#include<utility>
struct none_t
{
};
template<std::size_t I>using index_node = std::integral_constant<std::size_t, I>;
template<class Lhs, class Rhs>struct tree
{
};
template<std::size_t Start, std::size_t End>struct make_index_tree
{
typedef tree<
typename make_index_tree<Start, (Start + End) / 2>::type,
typename make_index_tree<(Start + End) / 2 + 1, End>::type> type;
};
template<std::size_t I>struct make_index_tree<I, I>
{
typedef index_node<I> type;
};
namespace detail
{
template<class Lhs, class Rhs>struct filter_i2
{
typedef tree<Lhs, Rhs> type;
};
template<>struct filter_i2<none_t, none_t>
{
typedef none_t type;
};
template<class Tree, template<std::size_t>class Cond>struct filter_i;
template<class Lhs, class Rhs, template<std::size_t>class Cond>
struct filter_i<tree<Lhs, Rhs>, Cond>
{
typedef typename filter_i<Lhs, Cond>::type lhs;
typedef typename filter_i<Rhs, Cond>::type rhs;
typedef typename filter_i2<lhs, rhs>::type type;
};
template<std::size_t I, template<std::size_t>class Cond>struct filter_i<index_node<I>, Cond>
{
typedef typename std::conditional<Cond<I>::value, index_node<I>, none_t>::type type;
};
template<template<std::size_t>class Cond>struct filter_i<none_t, Cond>
{
typedef none_t type;
};
}
template<class Tree, template<std::size_t I>class Cond>struct filter
{
typedef typename detail::filter_i<Tree,Cond>::type type;
};
namespace detail
{
template<std::size_t I, std::size_t... Is>auto sequence_push_back(std::index_sequence<Is...>)
->std::index_sequence<Is..., I>;
}
template<class Sequence, std::size_t I>struct sequence_push_back
{
typedef decltype(detail::sequence_push_back<I>(std::declval<Sequence>())) type;
};
template<class Tree>struct get_first;
template<class Lhs, class Rhs>struct get_first<tree<Lhs, Rhs>>
{
typedef typename get_first<Lhs>::type type;
};
template<class Rhs>struct get_first<tree<none_t, Rhs>>
{
typedef typename get_first<Rhs>::type type;
};
template<std::size_t I>struct get_first<index_node<I>>
{
typedef index_node<I> type;
};
template<std::size_t I, class Tree>struct sieve
{
typedef sieve<I - 1, Tree> first;
typedef typename first::type lhs;
typedef typename first::tree next_tree;
typedef sieve<I - 1, next_tree> second;
typedef tree<lhs, typename second::type> type;
typedef typename second::tree tree;
};
template<class Tree>struct sieve<0, Tree>
{
typedef typename get_first<Tree>::type first;
static constexpr auto val = first::value;
template<std::size_t I>struct diver_check :std::integral_constant<bool, (I%val != 0)>
{
};
typedef first type;
typedef typename filter<Tree, diver_check>::type tree;
};
template<std::size_t I>struct sieve<I, none_t>
{
typedef none_t type;
typedef none_t tree;
};
template<>struct sieve<0, none_t>
{
typedef none_t type;
typedef none_t tree;
};
template<std::size_t I, class Return, class Tree>struct start_point
{
typedef sieve<I, Tree> first;
typedef typename first::tree next;
typedef typename start_point<I + 1, tree<Return, typename first::type>, next>::type type;
};
template<std::size_t I, class Return>struct start_point<I, Return, none_t>
{
typedef Return type;
};
template<std::size_t Max>using prime_tree = typename start_point<0, none_t, typename make_index_tree<2, Max>::type>::type;
template<std::size_t I>void print(index_node<I>)
{
std::cout << I;
}
void print(none_t)
{
std::cout << "--";
}
template<class Lhs, class Rhs>void print(tree<Lhs, Rhs>)
{
std::cout << "(";
print(Lhs());
std::cout << ", ";
print(Rhs());
std::cout << ")";
}
int main()
{
print(prime_tree<100>());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment