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
 |