106 lines
2.6 KiB
C++
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
|