alsk/inc/tmp/treealgo.h

106 lines
2.6 KiB
C++

#ifndef TMP_TREEALGO_H
#define TMP_TREEALGO_H
#include "packalgo.h"
#include "tree.h"
#include "utility.h"
namespace tmp {
/**
* TreeTransform
*/
template<typename, template<typename> class> struct TreeTransformImpl;
template<typename T, typename... Ts, template<typename> class F>
struct TreeTransformImpl<Tree<T, Ts...>, F> {
using type = Tree<F<T>, typename TreeTransformImpl<Ts, F>::type...>;
};
template<template<typename> class F>
struct TreeTransformImpl<Tree<>, F> {
using type = Tree<>;
};
template<typename T, template<typename> class F>
using TreeTransform = typename TreeTransformImpl<T, F>::type;
/**
* TreeAccumulate
*/
template<typename, template<typename, typename...> class, typename> struct TreeAccumulateImpl;
template<typename T, typename... Ts, template<typename, typename...> class F, typename A>
struct TreeAccumulateImpl<Tree<T, Ts...>, F, A> {
using type = F<T, typename TreeAccumulateImpl<Ts, F, A>::type...>;
};
template<typename T, template<typename, typename...> class F, typename A>
struct TreeAccumulateImpl<Tree<T>, F, A> {
using type = F<T, A>;
};
template<template<typename, typename...> class F, typename A>
struct TreeAccumulateImpl<Tree<>, F, A> {
using type = A;
};
template<typename T, template<typename, typename...> class F, typename A>
using TreeAccumulate = typename TreeAccumulateImpl<T, F, A>::type;
/**
* TreeNLRAccumulate
*/
template<typename T, template<typename, typename> class F, typename A>
using TreeNLRAccumulate = Accumulate<Transform<PackFromTreeNLR<T>, GetType>, F, A>;
/**
* TreeHeight
*/
template<typename T>
struct TreeHeightImpl {
template<typename, typename... Ts>
using CalcHeight = std::integral_constant<Depth, 1 + detail::Max<Ts::type::value...>>;
using CalcHeightDefault = std::integral_constant<Depth, -1>;
static constexpr Depth value = TreeAccumulate<T, CalcHeight, CalcHeightDefault>::value;
};
template<typename T>
constexpr Depth TreeHeight = TreeHeightImpl<T>::value;
/**
* TreeAllRTLPaths
*/
namespace detail {
template<typename T>
struct PackPushFronter {
template<typename P>
using Do = PackPushFront<P, T>;
};
}
template<typename> struct TreeAllRTLPathsImpl;
template<typename N, typename... Cs>
struct TreeAllRTLPathsImpl<Tree<N, Cs...>> {
using type = PackCat<Transform<typename TreeAllRTLPathsImpl<Cs>::type, Bind2nd<PackPushFront, N>::template F1>...>;
};
template<typename N>
struct TreeAllRTLPathsImpl<Tree<N>> {
using type = Pack<Pack<N>>;
};
template<>
struct TreeAllRTLPathsImpl<Tree<>> {
using type = Pack<>;
};
template<typename T>
using TreeAllRTLPaths = typename TreeAllRTLPathsImpl<T>::type;
}
#endif