Open PiotrNycz opened 3 years ago
While types derived from mpl::vector<>
and fusion::vector<>
are also MPL sequences (whether accidentally or by design, I'm not quite sure), types derived from mp_list
aren't. See f.ex. https://godbolt.org/z/71sGzP4zj. Only mp_list<>
itself is an MPL sequence. So using
(or typedef
) is correct.
I also don't know why the MSM examples use inheritance.
It seems that boost::mp11:mp_list
is simple type defined as:
template <typename ...T> struct mp_list {};
while both fusion and mpl vectors are types referring to itself - in mp_list it could be something as:
template <typename ...T> struct mp_list {
using mp_list_type = mp_list;
};
thus it would be possible to define mpl adapters working also with types derived from type-list type.
I also found in fusion-mpl adapters, that it is also required some inner-type for tag used in mpl adapters, in our example something like this:
struct mp_list_mpl_tag;
template <typename ...T> struct mp_list {
using mp_list_type = mp_list;
using mp_list_tag = ::boost::mp11::mp_list_mpl_tag;
};
I also tried at build-bench.com whether inheritance is somehow faster in compilation - and it is really faster but almost impossible to notice the difference, it is so small - see https://build-bench.com/b/kslOjZyqZVmCm6qrMEgf1ptanbM
namespace some
{
struct type_list_tag;
template <typename ...T>
struct type_list
{
using type = type_list;
using tag = type_list_tag;
};
template <typename T>
struct front_impl;
template <template <class...> class TL, typename T1, typename ...T>
struct front_impl<TL<T1, T...>>
{
using type = T1;
};
template <typename T>
struct front
{
using type = typename front_impl<typename T::type>::type;
};
template <typename T>
using front_t = typename front<T>::type;
template <typename T>
struct pop_front_impl;
template <template <class...> class TL, typename T1, typename ...T>
struct pop_front_impl<TL<T1, T...>>
{
using type = TL<T...>;
};
template <typename T>
struct pop_front
{
using type = typename pop_front_impl<typename T::type>::type;
};
template <typename T>
using pop_front_t = typename pop_front<T>::type;
}
#if USE_INHERITANCE
struct test : some::type_list<int,float,int,float,int,float> {};
#else
using test = some::type_list<int,float,int,float,int,float>;
#endif
int main() {
using namespace some;
front_t<pop_front_t<pop_front_t<test>>> a = 5;
front_t<pop_front_t<pop_front_t<pop_front_t<test>>>> b = 4;
return a + b;
}
Maybe the best solution to this problem would be to create boost::mp11::mp_list2
just to be used (with inheritance) in boost::msm transition table.
PoC is here https://wandbox.org/permlink/ciX5jWNdWTPLnGVF
The idea in short:
namespace boost::mp11 {
namespace aux { struct mp11_tag2; }
template <typename ...T>
struct mp_list2
{
using tag = aux::mp11_tag2; // mpl will catch this nested tag (see boost::mpl::sequence_tag generic impl)
using base = mp_list<T...>; // this will be accessible from derived classes
// the below line is not really needed - we can use aux::mp11_tag instead
// I just added it -- in case someone invents idea to have different tags for different type packs
using base_tag = typename ::boost::mpl::sequence_tag<base>::type;
};
}
And just forward all mpl operations/algorithms to base mp_list
namespace boost::mpl
{
// at
template<> struct at_impl<::boost::mp11::aux::mp11_tag2>
{
template<class L, class I>
struct apply
{
using type = typename at_impl<typename L::base_tag>
::template apply<typename L::base, I>
::type;
};
};
// back
//...
I just wanted to modernize my code - and try to use
boost::mp11::mp_list
instead ofboost::mpl::vector
in my FSM definitions.Simplified code is as follows:
It compiles, but produces unexpected output:
While - with original version (just replacing mp11::mp_list with mpl::vector) it works as expected:
It also works as expected with
boost::fusion::vector
.I found one workaround - when using type-alias for defining transition table it works as expected:
With type-alias it also works for other types boost::mpl::vector and boost::fustion::vector.
I am not sure what this inheritance is for, but all examples from boost::msm defines this transition tables that way.
The problem with
boost::mp11::mp_list
is probably here <boost/mp11/mpl.hpp> - but I am not sure that.I asked the question about that on SO: https://stackoverflow.com/questions/68195912/boostmp11mp-list-cant-define-proper-transition-table-for-fsm-based-on-boost - but not get much attention.
You can play with the problem on compiler explorer: https://godbolt.org/z/jTEnxPMTj
The problem is not related to version of boost or compiler.