Current Projects

Recent Posts
stencet v0.1.16
release
01 April 2013
rikitiki v0.1.67
release
01 April 2013
Working with tuples part II
blog
27 March 2013
stencet v0.0.6
release
24 March 2013

All Posts...

A cleaner way to do tuple iteration

14 March 2013 -
By

In my previous post I gave examples on how to iterate over a tuple via recursive instantiations. It became a bit of an annoyance to keep doing this, so I played around until I found something better. Assuming library code exists somewhere that looks a little like so:

namespace tupleExt {
template <typename F>
struct With {
  template <std::size_t N = 0, typename... Args, typename... FArgs>
    static inline typename std::enable_if<N == sizeof...(Args), void>::type
    iterate(const std::tuple<Args...>& t, FArgs&...){ }
    
    template <std::size_t N = 0, typename... Args, typename... FArgs>
    static inline typename std::enable_if<N < sizeof...(Args), void>::type
    iterate(const std::tuple<Args...>& t, FArgs&... fargs){
      F::evaluate( std::get<N>(t), fargs... );
      iterate<N+1, Args...>(t, fargs...);
    }
};
}

Each iterator then needs to just look like so:

  struct Set {
    template <typename T, typename S>
      static void evaluate( const Field_<T, S>& field, Json::Value& jv, T& t){
        jv[field.name] = t.*(field.field);
    }
  };

  template <typename T>
    static Json::Value& operator<<(Json::Value& jv, T& t) {
    tupleExt::With<Set>::iterate( MetaClass_<T>::fields(), jv, t);
    return jv;
  }

It's the same basic mechanism, except generalized out some. I like this approach for a few reasons. First, every template type that could be inferred, is. Second, even if you don't know what variadic templates are, you can get a sense for what the code is doing in this case. It also has the nice aspect that it is about as minimal an implementation as you can get.

Note that you can't, in general, pass a function into a tuple iteration scheme like this if that functions execution at all depends on parameters to be pulled out of the tuple type. The behind the scenes detail here is that we are forcing a new 'evaluate' all to be created for every unique type in a given tuple at compile time (and then hopefully inlined).

The only thing I don't really like is that the inner function has to be named 'evaluate' or whatever the library uses. I'd be interested if anyone has a better idea for a name that is more in line with the standard library.

comments powered by Disqus