#ifndef TMP_TREE_H #define TMP_TREE_H #include "bind.h" #include "pack.h" #include "packalgo.h" #include "utility.h" namespace tmp { /** * Tree */ template struct Tree; template struct Tree { using node = N; using children = Pack; }; template<> struct Tree<> {}; /** * TreeNode * * for use in flat tree representations */ enum class TreeNodeType { Branch, Leaf }; template struct TreeNode { static constexpr Depth depth = D; using type = T; static constexpr TreeNodeType nodeType = N; }; template using TreeRoot = TreeNode<0, T, NT>; template using TreeBranch = TreeNode; template using TreeLeaf = TreeNode; /** * TreeIsLeaf */ template struct TreeIsLeafImpl: std::true_type {}; template struct TreeIsLeafImpl>: std::false_type {}; template constexpr bool TreeIsLeaf = TreeIsLeafImpl::value; /** * PackFromTreeNLR * * creates a pack from a tree using NLR * tree traversal algorithm */ template struct PackFromTreeNLRImpl; template struct PackFromTreeNLRImpl, D> { using type = PackPushFront< PackCat::type...>, TreeBranch >; }; template struct PackFromTreeNLRImpl, D> { using type = Pack>; }; template struct PackFromTreeNLRImpl, D> { using type = Pack<>; }; template using PackFromTreeNLR = typename PackFromTreeNLRImpl::type; /** * TreeFromPackNLR * * creates a tree from a pack * reverses PackFromTreeNLR */ namespace detail { template using PartialTree = Pack, T>; template struct GreaterThan { template struct CmpImpl; template struct CmpImpl>: std::integral_constant LIM)> {}; template struct CmpImpl: std::true_type {}; template using Cmp = CmpImpl; }; } /* property: * one block either groups future blocks or * has a bigger or equal depth than following * * property: * the list of depths when building is always * decreasing (quite easy to demonstrate) */ template struct TreeFromPackNLRImpl; template struct TreeFromPackNLRImpl, Ns...>, std::enable_if_t> { using next = typename TreeFromPackNLRImpl>::subtree; using cutd = Cut::template Cmp>; using children = Transform, Bind2ndV::template F1>; using siblings = PackGet; using part = detail::PartialTree>>; using subtree = PackPushFront; using type = Repack; }; template struct TreeFromPackNLRImpl, Ns...>> { using next = typename TreeFromPackNLRImpl>::subtree; using children = Transform::template F1>; using subtree = PackPushFront; using type = Repack; }; template struct TreeFromPackNLRImpl, Ns...>, std::enable_if_t> { using part = detail::PartialTree>; using subtree = PackPushFront>::subtree, part>; using type = Repack; }; template<> struct TreeFromPackNLRImpl> { using subtree = Pack<>; using type = Repack; }; template using TreeFromPackNLR = typename TreeFromPackNLRImpl

::type; } #endif