Saturday, December 3, 2016

fold.cpp recursion with compile time constant

(1) boost variant size =20, JSONValue variant=6
(2) v.which() = index
(3) using =typedef and decltype is to get typeinfo
(4) (n,N) recursion, Compile constant N=0, N+1 force n recurs 1 more time to get to n=N  
(5) have not see example Max,Max get called

#pragma once
#include <string>
#include <boost\variant.hpp>
#include "render.hpp"
#include "get2.hpp"

using namespace std;

template<size_t N, size_t Max>
struct apply_at
{
 template<typename R, typename T, typename F, typename...Fs>
 static string apply(T&& t, size_t n, F&& f, Fs&&... fs)
 {
  if (n == N)
  {
    return forward<F>(f)(get2<N>(boost::forward<T>(t)));
  }
  else
  {
   return apply_at<N + 1, Max>::template apply<R, T, Fs...>(
    boost::forward<T>(t),
    n,
    forward<Fs>(fs)...);
  }
 }
};

template<size_t Max>
struct apply_at<Max, Max>
{
 template<typename R, typename T, typename...Fs>
 static string apply(T, size_t, Fs...)
 {
  return R();
 }
};

template<typename T,typename F, typename...Fs>
static string fold_at(T&& t, size_t n, F&& f, Fs&&... fs)
{
  using R = decltype(f(get2<0>(t)));
  return apply_at<0, sizeof...(Fs)+1>::template apply<R,T, F, Fs...>(
   boost::forward<T>(t),
   n,
   forward<F>(f),
   forward<Fs>(fs)...
   );
};

template <typename... Ts, typename... Fs>
string fold(const boost::variant<Ts...>& v, Fs&&... fs)
{
 // size boost::variant=60, JSONValue=6, so assert fail
 //static_assert(sizeof...(Ts) == sizeof...(Fs), "# of fun and variant not matching.");
 return fold_at(
  v, v.which(), forward<Fs>(fs)...
 );
};

No comments:

Post a Comment