-
-
Save plasma-effect/655c79d850f406fe0863b37b33ef661b to your computer and use it in GitHub Desktop.
ジャパニーズなかなか迷惑コード(TMPエラトステネス)
This file contains hidden or 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<iostream> | |
#include<type_traits> | |
#include<utility> | |
#include<functional> | |
namespace eratosthenes | |
{ | |
template<std::size_t I, class Sequence>struct add; | |
template<std::size_t I, std::size_t... Is>struct add<I, std::index_sequence<Is...>> | |
{ | |
typedef std::index_sequence<(I + Is)...> type; | |
}; | |
constexpr std::size_t log2(std::size_t i) | |
{ | |
return i == 0 ? 0 : i == 1 ? 0 : 1 + log2(i / 2); | |
} | |
template<std::size_t I, std::size_t S, bool, std::size_t U, std::size_t... Is> | |
struct make_sequence_i | |
{ | |
typedef typename make_sequence_i<I%S, S / 2, I&S, 2 * U, Is..., (Is + U)...>::type type; | |
}; | |
template<std::size_t I, std::size_t S, std::size_t U, std::size_t... Is> | |
struct make_sequence_i<I, S, true, U, Is...> | |
{ | |
typedef typename make_sequence_i<I%S, S / 2, I&S, 2 * U + 1, Is..., (Is + U)..., 2 * U>::type type; | |
}; | |
template<std::size_t U, std::size_t... Is> | |
struct make_sequence_i<0, 0, false, U, Is...> | |
{ | |
typedef std::index_sequence<Is..., (Is + U)...> type; | |
}; | |
template<std::size_t U, std::size_t... Is> | |
struct make_sequence_i<0, 0, true, U, Is...> | |
{ | |
typedef std::index_sequence<Is..., (Is + U)..., 2 * U> type; | |
}; | |
template<std::size_t Size>struct make_index_sequence | |
{ | |
static constexpr auto val = 1 << log2(Size); | |
typedef typename make_sequence_i<Size % val, val / 2, Size&val, 0>::type type; | |
}; | |
template<std::size_t Start, std::size_t End>struct make_range_sequence | |
{ | |
typedef typename add<Start, typename make_index_sequence<End - Start + 1>::type>::type type; | |
}; | |
template<std::size_t I, std::size_t B, bool, class Sequence,std::size_t... Rs>struct filter_i; | |
template<std::size_t I,std::size_t B,std::size_t T,std::size_t... Is,std::size_t... Rs> | |
struct filter_i<I, B, true, std::index_sequence<T, Is...>, Rs...> | |
{ | |
typedef typename filter_i<I, T, T%I == 0, std::index_sequence<Is...>, Rs...>::type type; | |
}; | |
template<std::size_t I, std::size_t B, std::size_t T, std::size_t... Is, std::size_t... Rs> | |
struct filter_i<I, B, false, std::index_sequence<T, Is...>, Rs...> | |
{ | |
typedef typename filter_i<I, T, T%I == 0, std::index_sequence<Is...>, Rs..., B>::type type; | |
}; | |
template<std::size_t I, std::size_t B, std::size_t... Rs> | |
struct filter_i<I, B, true, std::index_sequence<>, Rs...> | |
{ | |
typedef std::index_sequence<Rs...> type; | |
}; | |
template<std::size_t I, std::size_t B, std::size_t... Rs> | |
struct filter_i<I, B, false, std::index_sequence<>, Rs... > | |
{ | |
typedef std::index_sequence<Rs..., B> type; | |
}; | |
template<std::size_t I, class Sequence>struct filter; | |
template<std::size_t I, std::size_t T, std::size_t... Is>struct filter<I, std::index_sequence<T, Is...>> | |
{ | |
typedef typename filter_i<I, T, T%I == 0, std::index_sequence<Is...>>::type type; | |
}; | |
template<std::size_t I>struct filter<I, std::index_sequence<>> | |
{ | |
typedef std::index_sequence<> type; | |
}; | |
template<std::size_t I, class Sequence>using filter_t = typename filter<I, Sequence>::type; | |
template<class...>struct tuple {}; | |
template<std::size_t Now, std::size_t End, std::size_t Rest, class... Ts>struct make_sequence_tuple_i | |
{ | |
static constexpr auto val = Now + (End - Now) / Rest; | |
typedef typename make_sequence_tuple_i<val + 1, End, Rest - 1, Ts..., typename make_range_sequence<Now, val>::type>::type type; | |
}; | |
template<std::size_t Now, std::size_t End, class... Ts>struct make_sequence_tuple_i<Now, End, 0, Ts...> | |
{ | |
typedef tuple<Ts...> type; | |
}; | |
constexpr std::size_t twice(std::size_t i) | |
{ | |
return i*i; | |
} | |
constexpr std::size_t sqrt_i(std::size_t val, std::size_t min, std::size_t max) | |
{ | |
return max - min <= 1 ? min : | |
twice((min + max) / 2) <= val ? | |
sqrt_i(val, (min + max) / 2, max) : | |
sqrt_i(val, min, (min + max) / 2); | |
} | |
constexpr std::size_t sqrt(std::size_t val) | |
{ | |
return val == 0 ? 0 : val == 1 ? 1 : sqrt_i(val, 1, val); | |
} | |
template<std::size_t Start, std::size_t End>struct make_sequence_tuple | |
{ | |
typedef typename make_sequence_tuple_i<Start, End, sqrt(End - Start)>::type type; | |
}; | |
template<class Tuple, std::size_t...>struct sieve; | |
template<std::size_t... Us, class... Ts> | |
struct sieve<tuple<std::index_sequence<>, Ts...>, Us...> | |
{ | |
typedef tuple<std::index_sequence<Us...>, tuple<Ts...>> type; | |
}; | |
template<std::size_t T,std::size_t... Is,std::size_t... Us,class... Ts> | |
struct sieve<tuple<std::index_sequence<T, Is...>, Ts...>, Us...> | |
{ | |
typedef typename sieve<tuple<typename filter<T, std::index_sequence<Is...>>::type,filter_t<T, Ts>...>, Us..., T>::type type; | |
}; | |
template<class Tuple>struct projection1; | |
template<class T, class... Ts>struct projection1<tuple<T, Ts...>> | |
{ | |
typedef T type; | |
}; | |
template<class Tuple>struct projection2; | |
template<class U, class T, class... Ts>struct projection2<tuple<U, T, Ts...>> | |
{ | |
typedef T type; | |
}; | |
template<class Tuple, class... Ts>struct sieve2 | |
{ | |
typedef typename sieve<Tuple>::type first; | |
typedef typename sieve2<typename projection2<first>::type, Ts..., typename projection1<first>::type>::type type; | |
}; | |
template<class... Ts>struct sieve2<tuple<>, Ts...> | |
{ | |
typedef tuple<Ts...> type; | |
}; | |
template<class Tuple,std::size_t...>struct sequence_merge; | |
template<std::size_t... Is, class... Ts, std::size_t... Us>struct sequence_merge<tuple<std::index_sequence<Is...>, Ts...>, Us...> | |
{ | |
typedef typename sequence_merge<tuple<Ts...>, Us..., Is...>::type type; | |
}; | |
template<std::size_t... Is>struct sequence_merge<tuple<>, Is...> | |
{ | |
typedef std::index_sequence<Is...> type; | |
}; | |
template<std::size_t Max>struct prime_sequence | |
{ | |
typedef | |
typename sequence_merge< | |
typename sieve2< | |
typename make_sequence_tuple<2, Max>::type>::type>::type type; | |
}; | |
} | |
int main() | |
{ | |
typedef eratosthenes::prime_sequence<10000>::type primes; | |
std::cout << typeid(primes).name() << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment