tmp/tests/treealgo.cpp

123 lines
3.4 KiB
C++

#include "catch_tmp.h"
#include <treealgo.h>
using namespace tmp;
namespace {
template<typename T> struct IdentityImpl { using type = T; };
template<typename T> using Identity = typename IdentityImpl<T>::type;
template<typename> struct UnpackImpl;
template<typename T> struct UnpackImpl<Pack<T>> { using type = T; };
template<typename T> using Unpack = typename UnpackImpl<T>::type;
template<unsigned...> struct Unsigneds;
template<typename, typename> struct MakeSizeListImpl;
template<unsigned... Us, typename T> struct MakeSizeListImpl<Unsigneds<Us...>, T> { using type = Unsigneds<Us..., sizeof(T)>; };
template<typename U, typename T> using MakeSizeList = typename MakeSizeListImpl<U, T>::type;
template<typename, typename... Ts>
using CalcHeight = std::integral_constant<Depth, 1 + detail::Max<Ts::type::value...>>;
struct A {};
struct B {};
struct C {};
struct D {};
struct E {};
struct F {};
struct G {};
struct H {};
struct I {};
using T0 = Tree<>;
using T1 = Tree<A>;
using T2 = Tree<A, Tree<B>, Tree<C>>;
using T3 = Tree<A, Tree<B, Tree<C>, Tree<D>, Tree<E>>, Tree<F, Tree<G>>>;
using T4 = Tree<A,
Tree<B, Tree<C, Tree<D>, Tree<E>>>,
Tree<F, Tree<G, Tree<H>>>,
Tree<I>
>;
}
TEST_CASE("TreeTransform") {
SECTION("empty input") {
using Result = TreeTransform<Tree<>, Identity>;
REQUIRE_SAME(Tree<>, Result);
}
using Input1 = Tree<Pack<char>>;
using Input2 = Tree<Pack<bool>, Tree<Pack<char>, Tree<Pack<int>>>, Tree<Pack<long>>>;
SECTION("Identity") {
REQUIRE(std::is_same<Input1, TreeTransform<Input1, Identity>>{});
REQUIRE(std::is_same<Input2, TreeTransform<Input2, Identity>>{});
}
SECTION("Unpack") {
using Expected = Tree<bool, Tree<char, Tree<int>>, Tree<long>>;
using Result = TreeTransform<Input2, Unpack>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("TreeAccumulate") {
using Default = std::integral_constant<Depth, -1>;
SECTION("empty input") {
using Result = TreeAccumulate<Tree<>, CalcHeight, Default>;
REQUIRE_SAME(Default, Result);
}
SECTION("Unpack") {
REQUIRE(0 == TreeAccumulate<T1, CalcHeight, Default>::value);
REQUIRE(1 == TreeAccumulate<T2, CalcHeight, Default>::value);
REQUIRE(1 == TreeAccumulate<Tree<Tree<T1>, T1, T1>, CalcHeight, Default>::value);
REQUIRE(2 == TreeAccumulate<T3, CalcHeight, Default>::value);
}
}
TEST_CASE("TreeNLRAccumulate") {
SECTION("empty input") {
using Result = TreeNLRAccumulate<Tree<>, MakeSizeList, void>;
REQUIRE_SAME(void, Result);
}
SECTION("MakeSizeList") {
using Input = Tree<char, Tree<int, Tree<long long>>, Tree<float>, Tree<double>>;
using Expected = Unsigneds<sizeof(char), sizeof(int), sizeof(long long), sizeof(float), sizeof(double)>;
using Result = TreeNLRAccumulate<Input, MakeSizeList, Unsigneds<>>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("TreeHeight") {
REQUIRE(-1 == TreeHeight<T0>);
REQUIRE(0 == TreeHeight<T1>);
REQUIRE(1 == TreeHeight<T2>);
REQUIRE(1 == TreeHeight<Tree<Tree<T1>, T1, T1>>);
REQUIRE(2 == TreeHeight<T3>);
}
TEST_CASE("TreeAllRTLPaths") {
SECTION("empty input") {
using Result = TreeAllRTLPaths<T0>;
REQUIRE_SAME(Pack<>, Result);
}
SECTION("only root") {
using Expected = Pack<Pack<A>>;
using Result = TreeAllRTLPaths<T1>;
REQUIRE_SAME(Expected, Result);
}
SECTION("general case") {
using Expected = Pack<Pack<A,B,C,D>, Pack<A,B,C,E>, Pack<A,F,G,H>, Pack<A,I>>;
using Result = TreeAllRTLPaths<T4>;
REQUIRE_SAME(Expected, Result);
}
}