thesis version

This commit is contained in:
2021-05-10 18:10:51 +02:00
commit 08d655ad70
23 changed files with 19771 additions and 0 deletions

3
tests/catch_tmp.h Normal file
View File

@ -0,0 +1,3 @@
#include <catch.hpp>
#define REQUIRE_SAME(T0, T1) REQUIRE(std::is_same<T0, T1>{})

39
tests/debug.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "catch_tmp.h"
#include <debug.h>
using namespace tmp;
#if defined(__clang__)
TEST_CASE("typeName") {
REQUIRE("void" == std::string{typeName<void>()});
REQUIRE("int &" == std::string{typeName<int&>()});
REQUIRE("int *" == std::string{typeName<int*>()});
REQUIRE("const int" == std::string{typeName<int const>()});
REQUIRE("int *const &" == std::string{typeName<int* const&>()});
}
TEST_CASE("strTypes") {
REQUIRE("" == strTypes());
REQUIRE("int" == strTypes<int>());
REQUIRE("int" == strTypes<>(0));
REQUIRE("char, int" == strTypes<char>(0));
}
#elif defined(__GNUC__)
TEST_CASE("typeName") {
REQUIRE("void" == std::string{typeName<void>()});
REQUIRE("int&" == std::string{typeName<int&>()});
REQUIRE("int*" == std::string{typeName<int*>()});
REQUIRE("const int" == std::string{typeName<int const>()});
REQUIRE("int* const&" == std::string{typeName<int* const&>()});
}
TEST_CASE("strTypes") {
REQUIRE("" == strTypes());
REQUIRE("int" == strTypes<int>());
REQUIRE("int" == strTypes<>(0));
REQUIRE("char, int" == strTypes<char>(0));
}
#elif defined(__MSC_VER)
TEST_CASE("typeName") {}
TEST_CASE("strTypes") {}
#endif

2
tests/main.cpp Normal file
View File

@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include <catch.hpp>

154
tests/pack.cpp Normal file
View File

@ -0,0 +1,154 @@
#include "catch_tmp.h"
#include <pack.h>
using namespace tmp;
template<typename...> struct MyPack {};
TEST_CASE("PackHead") {
using P = Pack<void>;
REQUIRE_SAME(void, PackHead<P>);
}
TEST_CASE("PackTrail") {
SECTION("empty trail") {
using P = Pack<void>;
REQUIRE_SAME(Pack<>, PackTrail<P>);
}
SECTION("general case") {
using P = Pack<void, bool, char, int>;
using Expected = Pack<bool, char, int>;
REQUIRE_SAME(Expected, PackTrail<P>);
}
}
TEST_CASE("PackGet") {
using P = Pack<void, bool, char, int>;
using P0 = PackGet<P, 0>;
using P1 = PackGet<P, 1>;
using P2 = PackGet<P, 2>;
using P3 = PackGet<P, 3>;
REQUIRE_SAME(void, P0);
REQUIRE_SAME(bool, P1);
REQUIRE_SAME(char, P2);
REQUIRE_SAME(int, P3);
}
TEST_CASE("PackPushFront") {
SECTION("empty pack") {
using Result = PackPushFront<Pack<>, void>;
REQUIRE_SAME(Pack<void>, Result);
}
SECTION("general case") {
using Input = Pack<bool, char>;
using Result = PackPushFront<Input, void>;
using Expected = Pack<void, bool, char>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("PackPushBack") {
SECTION("empty pack") {
using Result = PackPushBack<Pack<>, void>;
REQUIRE_SAME(Pack<void>, Result);
}
SECTION("general case") {
using Input = Pack<bool, char>;
using Result = PackPushBack<Input, void>;
using Expected = Pack<bool, char, void>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("PackCat") {
SECTION("empty input") {
using Result = PackCat<Pack<>, Pack<>>;
REQUIRE_SAME(Pack<>, Result);
}
SECTION("empty lhs") {
using Result = PackCat<Pack<>, Pack<void>>;
REQUIRE_SAME(Pack<void>, Result);
}
SECTION("empty rhs") {
using Result = PackCat<Pack<void>, Pack<>>;
REQUIRE_SAME(Pack<void>, Result);
}
SECTION("general case") {
using Result = PackCat<Pack<void, char>, Pack<int, int, int>>;
using Expected = Pack<void, char, int, int, int>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("PackReverse") {
SECTION("empty input") {
using Result = PackReverse<Pack<>>;
REQUIRE_SAME(Pack<>, Result);
}
SECTION("one element") {
using Result = PackReverse<Pack<void>>;
REQUIRE_SAME(Pack<void>, Result);
}
SECTION("general case") {
using Result = PackReverse<Pack<void, char, int, int, int>>;
using Expected = Pack<int, int, int, char, void>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("PackReplace") {
SECTION("empty pack") {
using Result = PackReplace<Pack<>, void, bool>;
REQUIRE_SAME(Pack<>, Result);
}
SECTION("general case") {
using Input = Pack<void, bool, char, void, char, void>;
using Result = PackReplace<Input, void, bool>;
using Expected = Pack<bool, bool, char, bool, char, bool>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("Repack") {
SECTION("empty pack") {
using Result = Repack<MyPack, Pack<>>;
REQUIRE_SAME(MyPack<>, Result);
}
SECTION("general case") {
using Input = Pack<void, void, void>;
using Result = Repack<MyPack, Input>;
using Expected = MyPack<void, void, void>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("AsPack") {
SECTION("empty pack") {
using Result = Repack<Pack, MyPack<>>;
REQUIRE_SAME(Pack<>, Result);
}
SECTION("general case") {
using Input = MyPack<void, void, void>;
using Result = Repack<Pack, Input>;
using Expected = Pack<void, void, void>;
REQUIRE_SAME(Expected, Result);
}
}

149
tests/packalgo.cpp Normal file
View File

@ -0,0 +1,149 @@
#include "catch_tmp.h"
#include <algorithm.h>
using namespace tmp;
namespace {
template<unsigned N = 0> struct UInt { static constexpr unsigned value = N; };
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<typename T> struct SizeofImpl { using type = UInt<sizeof(T)>; };
template<typename T> using Sizeof = typename SizeofImpl<T>::type;
template<typename P0, typename P1> using Merge = PackCat<P0, P1>;
template<typename U0, typename U1> struct USumImpl { using type = UInt<U0::value+U1::value>; };
template<typename U0, typename U1> using USum = typename USumImpl<U0, U1>::type;
template<typename T> struct IsEven: std::integral_constant<bool, not(T::value & 1)> {};
}
TEST_CASE("Transform") {
SECTION("empty input") {
using Result = Transform<Pack<>, Identity>;
REQUIRE_SAME(Pack<>, Result);
}
using Input0 = Pack<Pack<char>, Pack<float>, Pack<int>>;
using Input1 = Pack<bool, char, short, int, long, long long>;
SECTION("Identity") {
REQUIRE(std::is_same<Input0, Transform<Input0, Identity>>{});
REQUIRE(std::is_same<Input1, Transform<Input1, Identity>>{});
}
SECTION("Unpack") {
using Expected = Pack<char, float, int>;
using Result = Transform<Input0, Unpack>;
REQUIRE_SAME(Expected, Result);
}
SECTION("Sizeof") {
using Expected = Pack<UInt<sizeof(bool)>, UInt<sizeof(char)>, UInt<sizeof(short)>, UInt<sizeof(int)>, UInt<sizeof(long)>, UInt<sizeof(long long)>>;
using Result = Transform<Input1, Sizeof>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("Accumulate") {
SECTION("empty input") {
using Result = Accumulate<Pack<>, PackCat, void>;
REQUIRE_SAME(void, Result);
}
using Input0 = Pack<Pack<char>, Pack<float>, Pack<int>>;
using Input1 = Pack<bool, char, short, int, long, long long>;
SECTION("PackCat") {
using Expected = Pack<char, float, int>;
using Result = Accumulate<Input0, PackCat, Pack<>>;
REQUIRE_SAME(Expected, Result);
}
SECTION("USum") {
using Expected = UInt<sizeof(bool)+sizeof(char)+sizeof(short)+sizeof(int)+sizeof(long)+sizeof(long long)>;
using Result = Accumulate<Transform<Input1, Sizeof>, USum, UInt<>>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("Filter") {
SECTION("empty input") {
using Expected = Pack<>;
using Result = Filter<Pack<>, IsEven>;
REQUIRE_SAME(Expected, Result);
}
SECTION("empty output") {
using Input = Pack<UInt<1>, UInt<3>, UInt<3>, UInt<5>, UInt<5>, UInt<7>>;
using Expected = Pack<>;
using Result = Filter<Input, IsEven>;
REQUIRE_SAME(Expected, Result);
}
SECTION("general case") {
using Input = Pack<UInt<1>, UInt<2>, UInt<3>, UInt<4>, UInt<5>, UInt<6>>;
using Expected = Pack<UInt<2>, UInt<4>, UInt<6>>;
using Result = Filter<Input, IsEven>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("Cut") {
SECTION("empty input") {
using Expected = Pack<Pack<>, Pack<>>;
using Result = Cut<Pack<>, IsEven>;
REQUIRE_SAME(Expected, Result);
}
SECTION("empty left output") {
using Input = Pack<UInt<1>, UInt<3>, UInt<3>, UInt<5>, UInt<5>, UInt<7>>;
using Expected = Pack<Pack<>, Input>;
using Result = Cut<Input, IsEven>;
REQUIRE_SAME(Expected, Result);
}
SECTION("empty right output") {
using Input = Pack<UInt<2>, UInt<4>, UInt<4>, UInt<6>, UInt<6>, UInt<8>>;
using Expected = Pack<Input, Pack<>>;
using Result = Cut<Input, IsEven>;
REQUIRE_SAME(Expected, Result);
}
SECTION("general case") {
using Input = Pack<UInt<2>, UInt<2>, UInt<3>, UInt<3>, UInt<5>, UInt<7>>;
using Expected = Pack<Pack<UInt<2>, UInt<2>>, Pack<UInt<3>, UInt<3>, UInt<5>, UInt<7>>>;
using Result = Cut<Input, IsEven>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("Reverse") {
SECTION("empty input") {
REQUIRE_SAME(Pack<>, Reverse<Pack<>>);
}
SECTION("one element") {
REQUIRE_SAME(Pack<void>, Reverse<Pack<void>>);
}
SECTION("general case") {
using Input = Pack<bool, char, short, int, long>;
using Expected = Pack<long, int, short, char, bool>;
using Result = Reverse<Input>;
REQUIRE_SAME(Expected, Result);
}
}

74
tests/traits.cpp Normal file
View File

@ -0,0 +1,74 @@
#include "catch_tmp.h"
#include <traits.h>
using namespace tmp;
TEST_CASE("void_t") {}
TEST_CASE("Void") {}
TEST_CASE("ReturnType") {
REQUIRE_SAME(void, ReturnType<void()>);
REQUIRE_SAME(void, ReturnType<void(int)>);
REQUIRE_SAME(bool, ReturnType<bool()>);
REQUIRE_SAME(bool&, ReturnType<bool&()>);
REQUIRE_SAME(bool const&, ReturnType<bool const&()>);
REQUIRE_SAME(void*, ReturnType<void*()>);
REQUIRE_SAME(void const*, ReturnType<void const*()>);
REQUIRE_SAME(void const*&, ReturnType<void const*&()>);
REQUIRE_SAME(void const* const&, ReturnType<void const* const&()>);
}
TEST_CASE("Parameters") {
REQUIRE_SAME(Pack<>, Parameters<void()>);
SECTION("single parameter") {
REQUIRE_SAME(Pack<int>, Parameters<void(int)>);
REQUIRE_SAME(Pack<int>, Parameters<void(int const)>);
REQUIRE_SAME(Pack<int&>, Parameters<void(int&)>);
REQUIRE_SAME(Pack<int const&>, Parameters<void(int const&)>);
REQUIRE_SAME(Pack<int*>, Parameters<void(int*)>);
REQUIRE_SAME(Pack<int const*>, Parameters<void(int const*)>);
}
SECTION("multiple parameters") {
using Input = void(void*, char, bool, int);
using Result = Parameters<Input>;
using Expected = Pack<void*, char, bool, int>;
REQUIRE_SAME(Expected, Result);
}
}
TEST_CASE("invoke_result_t") {}
TEST_CASE("FunctionCat") {
SECTION("empty lhs and rhs") {
using Result = FunctionCat<void(), void()>;
using Expected = void();
REQUIRE_SAME(Expected, Result);
}
SECTION("empty lhs") {
using Result = FunctionCat<void(), void(char)>;
using Expected = void(char);
REQUIRE_SAME(Expected, Result);
}
SECTION("empty rhs") {
using Result = FunctionCat<void(char), void()>;
using Expected = void(char);
REQUIRE_SAME(Expected, Result);
}
SECTION("general case") {
using Result = FunctionCat<void(char, int), void(bool, char)>;
using Expected = void(char, int, bool, char);
REQUIRE_SAME(Expected, Result);
}
}

57
tests/tree.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "catch_tmp.h"
#include <tree.h>
using namespace tmp;
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("NLR") {
using P0 = Pack<>;
using P1 = Pack<TreeRoot<A, TreeNodeType::Leaf>>;
using P2 = Pack<TreeRoot<A>, TreeLeaf<1, B>, TreeLeaf<1, C>>;
using P3 = Pack<
TreeRoot<A>,
TreeBranch<1, B>, TreeLeaf<2, C>, TreeLeaf<2, D>, TreeLeaf<2, E>,
TreeBranch<1, F>, TreeLeaf<2, G>
>;
using P4 = Pack<
TreeRoot<A>,
TreeBranch<1, B>, TreeBranch<2, C>, TreeLeaf<3, D>, TreeLeaf<3, E>,
TreeBranch<1, F>, TreeBranch<2, G>, TreeLeaf<3, H>,
TreeLeaf<1, I>
>;
SECTION("PackFromTree") {
REQUIRE_SAME(P0, PackFromTreeNLR<T0>);
REQUIRE_SAME(P1, PackFromTreeNLR<T1>);
REQUIRE_SAME(P2, PackFromTreeNLR<T2>);
REQUIRE_SAME(P3, PackFromTreeNLR<T3>);
REQUIRE_SAME(P4, PackFromTreeNLR<T4>);
}
SECTION("TreeFromPack") {
REQUIRE_SAME(T0, TreeFromPackNLR<P0>);
REQUIRE_SAME(T1, TreeFromPackNLR<P1>);
REQUIRE_SAME(T2, TreeFromPackNLR<P2>);
REQUIRE_SAME(T3, TreeFromPackNLR<P3>);
REQUIRE_SAME(T4, TreeFromPackNLR<P4>);
}
}

122
tests/treealgo.cpp Normal file
View File

@ -0,0 +1,122 @@
#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);
}
}