I have a task:

A sequence of types is given. Check that they are all classes and arrange them in such a way that derived classes are earlier than their base classes. For the sequence obtained, check that all classes are derived from the latter.

Implementing the solution is necessary with the help of boost :: mpl. At the moment I have Swap, which swaps 2 elements in a sequence, for example in mpl :: vector:

template< typename Seq, typename First, typename Second > struct swap { private: typedef typename begin<Seq>::type begin; typedef typename end<Seq>::type end; typedef typename clear<Seq>::type empty_container; // Insert values from begin to first typedef typename copy< iterator_range< begin, First >, back_inserter< empty_container > >::type prefix; // Insert second value typedef typename push_back< prefix, typename deref< Second >::type >::type prefixSecond; // Insert values from first+1 to second typedef typename copy< iterator_range< typename next< First >::type, Second >, back_inserter< prefixSecond > >::type prefixSecondMiddle; // Insert first value typedef typename push_back< prefixSecondMiddle, typename deref< First >::type >::type prefixSecondMiddleFirst; // Insert values from second+1 to end typedef typename copy< iterator_range< typename next< Second >::type, end >, back_inserter< prefixSecondMiddleFirst > >::type prefixSecondMiddleFirstSuffix; public: typedef prefixSecondMiddleFirstSuffix type; }; 

Here is an example of use:

 typedef typename boost::mpl::next<myvector::begin>::type first; typedef typename boost::mpl::next<first>::type second; typedef swap<myvector, first, second>::type res; 

And a predicate that verifies that the first element is the parent of the second:

 template< typename T1, typename T2 > struct compare_two{ static const bool value = is_base_of<T1, T2>::value; }; 

Now let's say we have a list of types:

 class base1 {}; class child1 : base1 {}; class child2 : child1 {}; class child3 : child2 {}; typedef vector<child2, child1, base1, child3> vec; 

It is necessary that after applying the meta-function it turned out: child3, child2, child1, base1

As I understand it, you just have to sort the vector, changing the corresponding types of places, if the first is the ancestor of the second. Tell me how to implement this means Boost MPL?

    1 answer 1

    Something like this:

     #include <boost/mpl/sort.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/size.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/count_if.hpp> #include <boost/mpl/equal.hpp> #include <boost/type_traits.hpp> namespace mpl = boost::mpl; struct A {}; struct B: A {}; struct C: B {}; struct D: A {}; struct E: C, D {}; // Функция сревнения - базовый класс меньше наседника struct is_base_of_fn{ template <class Base, class Derived> struct apply{ using type = boost::is_base_of<Base, Derived>; }; }; struct is_class_fn{ template <class T> struct apply{ using type = boost::is_class<T>; }; }; template <class Seq> using is_seq_of_class = mpl::bool_<mpl::count_if<Seq, is_class_fn>::type::value == mpl::size<Seq>::value>; using input_type_set = mpl::vector<E,B,D,C,A>; static_assert(is_seq_of_class<input_type_set>::value, ""); using outpur_type_set = typename mpl::sort<input_type_set, is_base_of_fn>::type; static_assert(mpl::equal<outpur_type_set, mpl::vector<A,B,D,C,E>>::value, ""); 

    PS I recommend to read this article (about meproprogramming, not about mpl)

    • Yes, exactly what you need! Thanks for the reply and the article. Still, this is a very cerebrally destructive topic) - Anton Maksimovich