265 lines
6.7 KiB
C++
265 lines
6.7 KiB
C++
|
#include <catch.hpp>
|
||
|
#include <alsk/skeleton/skeleton.h>
|
||
|
|
||
|
using namespace alsk;
|
||
|
using tmp::Pack;
|
||
|
|
||
|
struct Int {
|
||
|
int v;
|
||
|
Int(int v): v{v} {}
|
||
|
operator int() const { return v; }
|
||
|
};
|
||
|
|
||
|
struct A: Int {};
|
||
|
struct B: Int {};
|
||
|
struct C: Int {};
|
||
|
struct D: Int {};
|
||
|
struct E: Int {};
|
||
|
struct F: Int {};
|
||
|
struct G: Int {};
|
||
|
struct H: Int {};
|
||
|
struct I: Int {};
|
||
|
|
||
|
template<typename R>
|
||
|
struct Unary {
|
||
|
template<typename T>
|
||
|
R operator()(T a) { return{a+1}; }
|
||
|
};
|
||
|
|
||
|
template<typename R>
|
||
|
struct Binary {
|
||
|
template<typename T, typename U>
|
||
|
R operator()(T a, U b) { return{a+b}; }
|
||
|
};
|
||
|
|
||
|
template<>
|
||
|
struct Binary<void> {
|
||
|
template<typename T, typename U>
|
||
|
void operator()(T, U) {}
|
||
|
};
|
||
|
|
||
|
using S_ =
|
||
|
S<Serial,
|
||
|
S<Serial, Unary<D>, Binary<E>>,
|
||
|
Unary<F>,
|
||
|
S<Serial,
|
||
|
Unary<G>,
|
||
|
S<Serial, Unary<H>, Binary<void>>,
|
||
|
Unary<I>
|
||
|
>
|
||
|
>;
|
||
|
|
||
|
using L1 =
|
||
|
L<Serial, arg::R<1>(arg::P<1>, arg::P<2>),
|
||
|
D(arg::P<1>),
|
||
|
E(arg::R<0>, arg::P<0>)
|
||
|
>;
|
||
|
|
||
|
using L2 = F(arg::P<2>);
|
||
|
|
||
|
using L31 = G(arg::P<0>, arg::P<2>);
|
||
|
using L32 =
|
||
|
L<Serial, arg::R<0>(arg::R<0>, arg::P<1>),
|
||
|
H(arg::P<0>),
|
||
|
void(arg::P<0>, arg::P<1>)
|
||
|
>;
|
||
|
|
||
|
using L33 = I(arg::R<0>);
|
||
|
|
||
|
using L3 =
|
||
|
L<Serial, arg::R<2>(arg::R<1>, arg::P<0>, arg::R<0>),
|
||
|
L31, L32, L33
|
||
|
>;
|
||
|
|
||
|
using L_ =
|
||
|
L<Serial, arg::R<2>(A, B, C),
|
||
|
L1, L2, L3
|
||
|
>;
|
||
|
|
||
|
TEST_CASE("LinksToReturnTypes") {
|
||
|
REQUIRE(std::is_same<Pack<E>, impl::LinksToReturnTypes<L1>::type>{});
|
||
|
REQUIRE(std::is_same<Pack<F>, impl::LinksToReturnTypes<L2>::type>{});
|
||
|
REQUIRE(std::is_same<Pack<G>, impl::LinksToReturnTypes<L31>::type>{});
|
||
|
REQUIRE(std::is_same<Pack<H>, impl::LinksToReturnTypes<L32>::type>{});
|
||
|
REQUIRE(std::is_same<Pack<I>, impl::LinksToReturnTypes<L33>::type>{});
|
||
|
REQUIRE(std::is_same<Pack<I>, impl::LinksToReturnTypes<L3>::type>{});
|
||
|
REQUIRE(std::is_same<Pack<I>, impl::LinksToReturnTypes<L_>::type>{});
|
||
|
|
||
|
REQUIRE(std::is_same<Pack<E, F, I>, impl::LinksToReturnTypes<L1, L2, L3>::type>{});
|
||
|
}
|
||
|
|
||
|
using T_ =
|
||
|
Serial<arg::R<2>(A, B, C),
|
||
|
// 1
|
||
|
Fun<Serial<arg::R<1>(B, C),
|
||
|
Fun<Unary<D>, D(arg::P<1>)>,
|
||
|
Fun<Binary<E>, E(arg::R<0>, arg::P<0>)>
|
||
|
>, E(arg::P<1>, arg::P<2>)>,
|
||
|
// 2
|
||
|
Fun<Unary<F>, F(arg::P<2>)>,
|
||
|
// 3
|
||
|
Fun<Serial<arg::R<2>(F, A, E),
|
||
|
Fun<Unary<G>, G(arg::P<0>, arg::P<2>)>,
|
||
|
Fun<Serial<arg::R<0>(G, A),
|
||
|
Fun<Unary<H>, H(arg::P<0>)>,
|
||
|
Fun<Binary<void>, void(arg::P<0>, arg::P<1>)>
|
||
|
>, H(arg::R<0>, arg::P<1>)>,
|
||
|
Fun<Unary<I>, I(arg::R<0>)>
|
||
|
>, I(arg::R<1>, arg::P<0>, arg::R<0>)>
|
||
|
>;
|
||
|
|
||
|
template<typename...>
|
||
|
using TS_ = S_;
|
||
|
|
||
|
template<typename...>
|
||
|
using TL_ = L_;
|
||
|
|
||
|
TEST_CASE("BuildSkeleton") {
|
||
|
using T1 = BuildSkeleton<TS_, TL_>::skeleton<Pack<>, Pack<>>;
|
||
|
using T2 = BuildSkeletonT<S_, L_>;
|
||
|
|
||
|
REQUIRE(std::is_same<T_, T1>{});
|
||
|
REQUIRE(std::is_same<T_, T2>{});
|
||
|
}
|
||
|
|
||
|
TEST_CASE("TreeFromSkeleton") {
|
||
|
SECTION("simple") {
|
||
|
struct F {};
|
||
|
|
||
|
using Struct = S<Serial, F>;
|
||
|
using Links = L<Serial, void(), void()>;
|
||
|
using Skel = BuildSkeletonT<Struct, Links>;
|
||
|
using Expected =
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, void ()>,
|
||
|
tmp::Tree<Leaf<F, void ()>>
|
||
|
>;
|
||
|
|
||
|
using Result = TreeFromSkeleton<Skel>;
|
||
|
|
||
|
REQUIRE(std::is_same<Expected, Result>{});
|
||
|
}
|
||
|
|
||
|
SECTION("with links") {
|
||
|
struct F {}; struct G {};
|
||
|
|
||
|
using Struct = S<Serial, S<Serial, F, G>>;
|
||
|
using Links = L<Serial, arg::R<0>(int&, int), L<Serial, arg::R<1>(arg::P<1>, arg::P<0>), long(arg::P<1>, arg::P<0>), int(arg::R<0>)>>;
|
||
|
using Skel = BuildSkeletonT<Struct, Links>;
|
||
|
using Expected =
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, arg::R<0>(int&, int)>,
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, arg::R<1>(int, int&), int(arg::P<1>, arg::P<0>)>,
|
||
|
tmp::Tree<Leaf<F, long(arg::P<1>, arg::P<0>)>>,
|
||
|
tmp::Tree<Leaf<G, int(arg::R<0>)>>
|
||
|
>
|
||
|
>;
|
||
|
|
||
|
using Result = TreeFromSkeleton<Skel>;
|
||
|
|
||
|
REQUIRE(std::is_same<Expected, Result>{});
|
||
|
}
|
||
|
|
||
|
SECTION("complex") {
|
||
|
struct A0 {}; struct A1 {}; struct A2 {}; struct A3 {}; struct R {};
|
||
|
|
||
|
using Struct = S<Serial, A0, S<Farm, S<Serial, A1, A2>>, A0, S<Serial, A3, A3>>;
|
||
|
using Links = L<Serial, void(), R(), L<Farm, bool(), L<Serial, char(), short(), int()>>, R(), L<Serial, long(), float(), double()>>;
|
||
|
using Skel = BuildSkeletonT<Struct, Links>;
|
||
|
using Expected =
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, void()>,
|
||
|
tmp::Tree<Leaf<A0, R()>>,
|
||
|
tmp::Tree<
|
||
|
Branch<Farm, bool()>,
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, char()>,
|
||
|
tmp::Tree<Leaf<A1, short()>>,
|
||
|
tmp::Tree<Leaf<A2, int()>>
|
||
|
>
|
||
|
>,
|
||
|
tmp::Tree<Leaf<A0, R()>>,
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, long()>,
|
||
|
tmp::Tree<Leaf<A3, float()>>,
|
||
|
tmp::Tree<Leaf<A3, double()>>
|
||
|
>
|
||
|
>;
|
||
|
|
||
|
using Result = TreeFromSkeleton<Skel>;
|
||
|
|
||
|
REQUIRE(std::is_same<Expected, Result>{});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TEST_CASE("ToSkeleton") {
|
||
|
struct A0 {}; struct A1 {}; struct A2 {}; struct A3 {}; struct R {};
|
||
|
using Struct = S<Serial, A0, S<Farm, S<Serial, A1, A2>>, A0, S<Serial, A3, A3>>;
|
||
|
using Links = L<Serial, void(), R(), L<Farm, bool(), L<Serial, char(), short(), int()>>, R(), L<Serial, long(), float(), double()>>;
|
||
|
using Expected = BuildSkeletonT<Struct, Links>;
|
||
|
|
||
|
using Input =
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, void()>,
|
||
|
tmp::Tree<Leaf<A0, R()>>,
|
||
|
tmp::Tree<
|
||
|
Branch<Farm, bool()>,
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, char()>,
|
||
|
tmp::Tree<Leaf<A1, short()>>,
|
||
|
tmp::Tree<Leaf<A2, int()>>
|
||
|
>
|
||
|
>,
|
||
|
tmp::Tree<Leaf<A0, R()>>,
|
||
|
tmp::Tree<
|
||
|
Branch<Serial, long()>,
|
||
|
tmp::Tree<Leaf<A3, float()>>,
|
||
|
tmp::Tree<Leaf<A3, double()>>
|
||
|
>
|
||
|
>;
|
||
|
|
||
|
using Result = SkeletonFromTree<Input>;
|
||
|
|
||
|
REQUIRE(std::is_same<Expected, Result>{});
|
||
|
REQUIRE(std::is_same<Expected, SkeletonFromTree<TreeFromSkeleton<Expected>>>{});
|
||
|
}
|
||
|
|
||
|
TEST_CASE("SkeletonParallelHeight") {
|
||
|
SECTION("serial") {
|
||
|
struct F {}; struct G {};
|
||
|
using Struct = S<Serial, S<Serial, F, G>>;
|
||
|
using Links = L<Serial, arg::R<0>(int&, int), L<Serial, arg::R<1>(arg::P<1>, arg::P<0>), long(arg::P<1>, arg::P<0>), int(arg::R<0>)>>;
|
||
|
using Skel = BuildSkeletonT<Struct, Links>;
|
||
|
|
||
|
REQUIRE(skeletonParallelHeight<Skel> == 0);
|
||
|
}
|
||
|
|
||
|
SECTION("par2") {
|
||
|
struct A0 {}; struct A1 {}; struct A2 {};
|
||
|
using Struct = S<Serial, A0, S<Farm, S<Farm, A1>>, S<Farm, A2>>;
|
||
|
using Links = L<Serial, int(), int(), L<Farm, int(), L<Farm, int(), int()>>, L<Farm, int(), int()>>;
|
||
|
using Skel = BuildSkeletonT<Struct, Links>;
|
||
|
|
||
|
REQUIRE(skeletonParallelHeight<Skel> == 2);
|
||
|
}
|
||
|
|
||
|
SECTION("par4") {
|
||
|
struct A0 {};
|
||
|
using Struct = S<Farm, S<Farm, S<Farm, S<Farm, A0>>>>;
|
||
|
using Links = L<Farm, int(), L<Farm, int(), L<Farm, int(), L<Farm, int(), int()>>>>;
|
||
|
using Skel = BuildSkeletonT<Struct, Links>;
|
||
|
|
||
|
REQUIRE(skeletonParallelHeight<Skel> == 4);
|
||
|
}
|
||
|
|
||
|
SECTION("complex") {
|
||
|
struct A0 {};
|
||
|
using Struct = S<Farm, S<Serial, S<Farm, S<Farm, A0>>, S<Farm, S<Serial, S<Farm, A0>>>>>;
|
||
|
using Links = L<Farm, int(), L<Serial, int(), L<Farm, int(), L<Farm, int(), int()>>, L<Farm, int(), L<Serial, int(), L<Farm, int(), int()>>>>>;
|
||
|
using Skel = BuildSkeletonT<Struct, Links>;
|
||
|
|
||
|
REQUIRE(skeletonParallelHeight<Skel> == 3);
|
||
|
}
|
||
|
}
|