Boost logo

Boost Users :

Subject: [Boost-users] [traits, fusion, mpl] Basic question about is_base_of and template ancestors
From: Rindeberg Magnus (magnus.rindeberg_at_[hidden])
Date: 2012-08-30 09:10:21


Hello List!

I have an issue understanding how to combine CRTP with the "is_base_of" trait when iterating over a fusion vector. I have tried to illustrate my problem in the test program below. The idea is to first "do stuff" to all instances of types derived from A and then "do stuff" to the ones derived from B. I just don't know what to write instead of "WHAT_GOES_HERE?" below. I have tried to use "::boost::mpl::_" in different ways to get the "type" type of B but failed miserably every time.

I'm also curious about how to negate the "is_base_of" predicate. I tried using "not_<>" but that didn't work at all...

Very thankful for any and all help!

// Magnus

P.S. Sorry if this question has been answered already! I have looked at the documentation, searched archives and the web but couldn't find the solution. Maybe I searched using the wrong keywords...

#include <boost/type_traits.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/container.hpp>
#include <boost/fusion/include/at_key.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/filter_if.hpp>

struct dostuff
{
  template<typename T>
    void
    operator()(T const & x) const
    {
      // Do stuff here!
    }
};

template<class D>
  struct A
  {
  };

template<class D, typename T>
  struct B
  {
    typedef T type;
  };

struct derived_from_A : public A<derived_from_A>
{
};

struct derived_from_B : public B<derived_from_B, int>
{
};

typedef ::boost::mpl::vector<derived_from_A, derived_from_B>::type typelist_type;

::boost::fusion::result_of::as_set<typelist_type>::type typeset_;

int
main(int argc, char ** argv)
{
  dostuff ds;

  // This seems to be working!
  ::boost::fusion::for_each(
    ::boost::fusion::filter_if
    < ::boost::is_base_of<A< ::boost::mpl::_>, ::boost::mpl::_>
> (typeset_), ds);

#if(0)
  // Don't know how to do this! Preferably I'd like to check for inheritance from B.
  // If that isn't possible I'll settle for "not inheriting from A".
  ::boost::fusion::for_each(
    ::boost::fusion::filter_if
    < ::boost::is_base_of<B< ::boost::mpl::_, WHAT_GOES_HERE? >, ::boost::mpl::_>
> (typeset_), ds);
#endif
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net