ldionne on gh-pages
Update benchmarks to 490dbf6 fo… (compare)
ldionne on gh-pages
Update benchmarks to 490dbf6 fo… (compare)
ldionne on gh-pages
Update benchmarks to 490dbf6 fo… (compare)
ldionne on gh-pages
Update benchmarks to 490dbf6 fo… (compare)
ldionne on gh-pages
Update benchmarks to 490dbf6 fo… (compare)
#include<boost/hana.hpp>
namespace hana = boost::hana;
auto rearrange = [](auto xs, auto spec) {
auto type_map = hana::unpack(
hana::range_c<int, 0, hana::length(xs)>,
[&](auto... i) {
return hana::make_map(hana::make_pair(
hana::decltype_(xs[i]), i)...);
});
return hana::unpack(spec,
[&](auto... x) {
return hana::make_tuple(xs[type_map[hana::decltype_(x)]]...);
});
};
int main()
{
BOOST_HANA_RUNTIME_ASSERT(
rearrange(
hana::make_tuple(1, 1.0f, 1.0),
hana::tuple_t<double, int, float>)
== hana::make_tuple(1.0, 1, 1.0f));
}
spec
. I decided to play around with making different implementations of the following psuedo code (from wikipedia :P):function is_prime(n : integer)
if n ≤ 1
return false
else if n ≤ 3
return true
else if n mod 2 = 0 or n mod 3 = 0
return false
let i ← 5
while i×i ≤ n
if n mod i = 0 or n mod (i + 2) = 0
return false
i ← i + 6
return true
if_
s#include<boost/hana.hpp>
namespace hana = boost::hana;
constexpr auto if_ = hana::if_;
template<int c>
constexpr auto int_c = hana::int_c<c>;
template<bool c>
constexpr auto bool_c = hana::bool_c<c>;
auto primality_test = [](auto n)
{
return
if_(n <= int_c<1>, hana::nothing,
if_(n <= int_c<3>, hana::just(n),
if_(n % int_c<2> == int_c<0> || n % int_c<3> == int_c<0>, hana::nothing,
if_(hana::is_just(hana::while_(
[&](auto just_i) {
return hana::maybe(bool_c<false>,
[&](auto i) {
return bool_c<i * i <= n>;
}, just_i);
},
hana::just(int_c<5>),
[&](auto just_i) {
return hana::maybe(hana::nothing,
[&](auto i) {
return if_(n % i == int_c<0> || n % (i + int_c<2>) == int_c<0>, hana::nothing,
hana::just(i + int_c<6>));
}, just_i);
})), hana::just(n), hana::nothing)))); //practically lisp!
};
int main()
{
static_assert(decltype(primality_test(int_c<1009>)){} == hana::just(int_c<1009>), "");
static_assert(decltype(primality_test(int_c<1010>)){} == hana::nothing, "");
}
while_
the best choice here?
Regarding your primality testing example, here's how I would do it:
#include <boost/hana.hpp>
namespace hana = boost::hana;
constexpr bool is_prime_impl(int n) {
if (n <= 1)
return false;
else if (n <= 3)
return true;
else if (n % 2 == 0 or n % 3 == 0)
return false;
int i = 5;
while (i*i <= n) {
if (n % i == 0 or n % (i + 2) == 0)
return false;
i += 6;
}
return true;
}
template <typename N>
constexpr auto is_prime(N const&) {
return hana::bool_c<is_prime_impl(hana::value<N>())>;
}
auto primes = hana::tuple_c<int,
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97,101,103,107,109,113,
127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199,211,223,227,229,
233,239,241,251,257,263,269,271,277,281,
283,293,307,311,313,317,331,337,347,349,
353,359,367,373,379,383,389,397,401,409,
419,421,431,433,439,443,449,457,461,463,
467,479,487,491,499
>;
int main() {
auto integers = hana::make_range(hana::int_c<0>, hana::int_c<100>);
hana::for_each(integers, [](auto i) {
static_assert(decltype(hana::contains(primes, i) == is_prime(i)){}, "");
});
}
For homogeneous problems, it's much easier and much faster to just use constexpr
.
hana::contains
is quite slow (it could be optimized, at least for hana::types
and hana::integral_constant
s, but it isn’t).
Wait it should work with 1, but should not accept 0 or 2+. size == 0 doesn't work because 1 == 0 will trigger the assert, and static_assert triggers at false not true.
size != 0 doesn't work because it will also trigger at 1+. I could solve this but it would require some boolean shenanigans