template struct List; struct Nil { template using Append = List<_NValue, Nil>; }; template struct List { private: template struct _AppendHelper; template struct _AppendHelper<_NValue, List<_CurValue, _CurNext>> { using Next = List< _CurValue, typename _AppendHelper<_NValue, _CurNext>::Next >; }; template struct _AppendHelper<_NValue, Nil> { using Next = List<_NValue, Nil>; }; template struct _NthHelper; template struct _NthHelper<_Remain, List<_CurValue, _CurNext>> { static constexpr int value = _NthHelper<_Remain - 1, _CurNext>::value; }; template struct _NthHelper<0, List<_CurValue, _CurNext>> { static constexpr int value = _CurValue; }; public: using Next = _Next; static constexpr int value = _Value; template using Append = List<_NValue, typename _AppendHelper<_NValue, _Next>::Next>; template static constexpr int nth = _NthHelper<_Pos, List<_Value, _Next>>::value; }; template struct MakeMaxCache { private: template struct _Helper; template struct _Helper<_MaxValue, _Cache, List<_CurValue, _CurNext>> { static constexpr int current_max = _MaxValue > _CurValue ? _MaxValue : _CurValue; using Result = _Helper< current_max, typename _Cache::template Append, _CurNext >::Result; }; template struct _Helper<_MaxValue, _Cache, Nil> { using Result = _Cache; }; public: using Result = typename _Helper<0, List<0, Nil>, Lst>::Result::Next; }; template struct Trap { private: using LeftMaxHeights = MakeMaxCache::Result; template struct _Helper; template struct _Helper<0, _LeftMaxHeights, List<_CurValue, _CurNext>> { using NextState = _Helper<1, _LeftMaxHeights, _CurNext>; static constexpr int trapped = NextState::trapped; }; template struct _Helper<_Index, _LeftMaxHeights, List<_CurValue, _CurNext>> { using NextState = _Helper<_Index + 1, _LeftMaxHeights, _CurNext>; static constexpr int right_max_height = NextState::max_height; static constexpr int max_height = _CurValue > right_max_height ? _CurValue : right_max_height; static constexpr int min_wall_height = _LeftMaxHeights::template nth<_Index - 1> > right_max_height ? right_max_height : _LeftMaxHeights::template nth<_Index - 1>; static constexpr int this_trapped = _CurValue < min_wall_height ? (min_wall_height - _CurValue) : 0; static constexpr int trapped = NextState::trapped + this_trapped; }; template struct _Helper<_Index, _LeftMaxHeights, List<_CurValue, Nil>> { static constexpr int max_height = _CurValue; static constexpr int trapped = 0; }; public: static constexpr int result = _Helper<0, LeftMaxHeights, Input>::trapped; }; using Input1 = List<0, List<1, List<0, List<2, List<1, List<0, List<1, List<3, List<2, List<1, List<2, List<1, Nil>>>>>>>>>>>>; using Input2 = List<4, List<2, List<0, List<3, List<2, List<5, Nil>>>>>>; static_assert(Trap::result == 6); static_assert(Trap::result == 9); // To make the linker happy. int main(int argc, const char *argv[]) { return 0; }