Search code examples
c++metaprogrammingboost-hana

Handle partial type with Boost Hana


What I call a partial type here is something like that:

template < template <typename ...> typename Skeleton,
           template <typename ...> typename WrapperType,
           typename ... Pölicies >
struct MetaStorage {

  template < typename ... Ts >
  struct With_Type {

    using type = Skeleton<WrapperType<Ts...>, Policies...>;
  };
};

using partialType = MetaStorage<Sk, Wt, P1, P2, P3>;
using finalType = partialType::With_Type<T1, T2>;

I don't think it fits well with hana philosophy and it's not readable if I want to split the type more than this.

So what is the efficient way of doing this with Boost Hana?

Edit :

By that I mean, a way to allow user to create the final type in several steps. Like that they can use some partial type to generate every final type. But with the usual syntax and hana::type.


Solution

  • With Boost.Hana you can lift types to values with hana::type and the same with templates using hana::template_. With that you can do the following:

    #include <boost/hana.hpp>
    
    namespace hana = boost::hana;
    
    
    template <typename ...X> struct skeleton_t { };
    constexpr auto skeleton = hana::template_<skeleton_t>;
    template <typename ...X> struct wrapper_t { };
    constexpr auto wrapper = hana::template_<wrapper_t>;
    template <int i> struct policy_t { };
    template <int i> constexpr auto policy = hana::type_c<policy_t<i>>;
    template <int i> struct foo_t { };
    template <int i> constexpr auto foo = hana::type_c<foo_t<i>>;
    
    int main() {
      auto meta_storage = [](auto s, auto w, auto ...policies) {
        return [=](auto ...ts) {
          return s(w(ts...), policies...);
        };
      };
    
      auto partial = meta_storage(skeleton, wrapper, policy<1>, policy<2>);
    
      auto final_ = partial(foo<1>, foo<2>);
    
      skeleton_t<wrapper_t<foo_t<1>, foo_t<2>>, policy_t<1>, policy_t<2>> check
        = typename decltype(final_)::type{};
    }
    

    Personally I prefer to not bother with hana::template_ in the cases where I can just use a function. I also use a macro to create a tag type along with its corresponding hana::type value to reduce some of the setup you see above the main function.