Skip to content

Since 1.85 - flag_list can't be defined with boost::mp11::mp_list #88

@PiotrNycz

Description

@PiotrNycz

boost::mp11::mp_list is mpl-compatible type-list and we have habit to use it for big state machines (20+ transitions).
It is really not necessary, but folks in my project use this mp_list also for other things - like initial_state or flag_list.

When we switched to 1.86 - flag_list defined with mp_list stops compiling with this errors

In file included from /app/boost/include/boost/mp11/utility.hpp:14,
from /app/boost/include/boost/parameter/aux_/result_of0.hpp:14,
from /app/boost/include/boost/parameter/aux_/arg_list.hpp:51,
from /app/boost/include/boost/parameter/parameters.hpp:22,
from /app/boost/include/boost/parameter.hpp:11,
from /app/boost/include/boost/msm/back/state_machine.hpp:54,
from :1:
/app/boost/include/boost/mp11/detail/mp_front.hpp: In substitution of 'template using boost::mp11::mp_front = typename boost::mp11::detail::mp_front_impl::type [with L = boost::mp11::mp_list<>]':
/app/boost/include/boost/mp11/list.hpp:149:25: required by substitution of 'template using boost::mp11::mp_first = boost::mp11::mp_front [with L = boost::mp11::mp_list<>]'
149 | template using mp_first = mp_front;
| ^~~~~~~~
/app/boost/include/boost/mp11/detail/mpl_common.hpp:30:11: required from 'struct boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> >'
30 | using type = mp11::mp_first;
| ^~~~
/app/boost/include/boost/fusion/adapted/mpl/mpl_iterator.hpp:23:12: required from 'struct boost::fusion::mpl_iterator<boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> > >'
23 | struct mpl_iterator
| ^~~~~~~~~~~~
/app/boost/include/boost/type_traits/is_base_and_derived.hpp:226:5: required from 'const bool boost::detail::is_base_and_derived_impl<boost::fusion::iterator_root, boost::fusion::mpl_iterator<boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> > > >::value'
226 | BOOST_STATIC_CONSTANT(bool, value = (BOOST_IS_BASE_OF(B,D) && ! ::boost::is_same<ncvB,ncvD>::value));
| ^~~~~~~~~~~~~~~~
/app/boost/include/boost/type_traits/is_base_of.hpp:24:11: required from 'const bool boost::detail::is_base_of_imp<boost::fusion::iterator_root, boost::fusion::mpl_iterator<boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> > > >::value'
24 | BOOST_STATIC_CONSTANT(bool, value = (
| ^~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/type_traits/is_base_of.hpp:30:48: [ skipping 7 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/app/boost/include/boost/mpl/for_each.hpp:78:26: required from 'static void boost::mpl::aux::for_each_impl::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::s_iter<boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > >, boost::mpl::s_item<State1, boost::mpl::set0<> > >; LastIterator = boost::mpl::s_iter<boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > >, boost::mpl::set0<> >; TransformFunc = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine::init_flags]'
78 | aux::unwrap(f, 0)(boost::get(x));
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/app/boost/include/boost/mpl/for_each.hpp:82:22: required from 'static void boost::mpl::aux::for_each_impl::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::s_iter<boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > >, boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > > >; LastIterator = boost::mpl::s_iter<boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > >, boost::mpl::set0<> >; TransformFunc = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine::init_flags]'
81 | for_each_impl<boost::is_same<iter,LastIterator>::value>
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
82 | ::execute( static_cast<iter*>(0), static_cast<LastIterator*>(0), static_cast<TransformFunc*>(0), f);
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/mpl/for_each.hpp:105:18: required from 'void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = s_item<State<2>, s_item<State1, set0<> > >; TransformOp = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine::init_flags]'
104 | aux::for_each_impl< boost::is_same<first,last>::value >
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105 | ::execute(static_cast<first*>(0), static_cast<last*>(0), static_cast<TransformOp*>(0), f);
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/msm/back/state_machine.hpp:2386:29: required from 'bool (** boost::msm::back::state_machine<A0, A1, A2, A3, A4>::get_entries_for_flag() const)(const library_sm&) [with Flag = Flag1; A0 = Front; A1 = boost::parameter::void_; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_; flag_handler = bool (*)(const boost::msm::back::state_machine&)]'
2385 | (::boost::mpl::for_each<state_list, boost::msm::wrap< ::boost::mpl::placeholders::1> >
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2386 | (init_flags(flags_entries)),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/msm/back/state_machine.hpp:1518:95: required from 'bool boost::msm::back::state_machine<A0, A1, A2, A3, A4>::is_flag_active() const [with Flag = Flag1; A0 = Front; A1 = boost::parameter::void
; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_]'
1518 | return FlagHelper<Flag,(nr_regions::value>1)>::helper(*this,get_entries_for_flag());
| ~~~~~~~~~~~~~~~~~~~~~~~~~~^~

:42:43: required from here

42 | std::cout << fsm.is_flag_active();
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~
/app/boost/include/boost/mp11/detail/mp_front.hpp:45:25: error: no type named 'type' in 'struct boost::mp11::detail::mp_front_impl<boost::mp11::mp_list<> >'
45 | template using mp_front = typename detail::mp_front_impl::type;
| ^~~~~~~~
In file included from /app/boost/include/boost/mp11/mpl_list.hpp:11,
from :6:
/app/boost/include/boost/mp11/detail/mpl_common.hpp: In instantiation of 'struct boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> >':
/app/boost/include/boost/fusion/adapted/mpl/mpl_iterator.hpp:23:12: required from 'struct boost::fusion::mpl_iterator<boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> > >'
23 | struct mpl_iterator
| ^~~~~~~~~~~~
/app/boost/include/boost/type_traits/is_base_and_derived.hpp:226:5: required from 'const bool boost::detail::is_base_and_derived_impl<boost::fusion::iterator_root, boost::fusion::mpl_iterator<boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> > > >::value'
226 | BOOST_STATIC_CONSTANT(bool, value = (BOOST_IS_BASE_OF(B,D) && ! ::boost::is_same<ncvB,ncvD>::value));
| ^~~~~~~~~~~~~~~~
/app/boost/include/boost/type_traits/is_base_of.hpp:24:11: required from 'const bool boost::detail::is_base_of_imp<boost::fusion::iterator_root, boost::fusion::mpl_iterator<boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> > > >::value'
24 | BOOST_STATIC_CONSTANT(bool, value = (
| ^~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/type_traits/is_base_of.hpp:30:48: required from 'struct boost::is_base_of<boost::fusion::iterator_root, boost::fusion::mpl_iterator<boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> > > >'
30 | template <class Base, class Derived> struct is_base_of
| ^~~~~~~~~~
/app/boost/include/boost/fusion/support/is_iterator.hpp:18:12: required from 'struct boost::fusion::is_fusion_iterator<boost::fusion::mpl_iterator<boost::mpl::aux::mp11_iterator<boost::mp11::mp_list<> > > >'
18 | struct is_fusion_iterator : is_base_of<iterator_root, T> {};
| ^~~~~~~~~~~~~~~~~~
/app/boost/include/boost/mpl/if.hpp:63:11: [ skipping 5 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/app/boost/include/boost/mpl/for_each.hpp:78:26: required from 'static void boost::mpl::aux::for_each_impl::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::s_iter<boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > >, boost::mpl::s_item<State1, boost::mpl::set0<> > >; LastIterator = boost::mpl::s_iter<boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > >, boost::mpl::set0<> >; TransformFunc = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine::init_flags]'
78 | aux::unwrap(f, 0)(boost::get(x));
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
/app/boost/include/boost/mpl/for_each.hpp:82:22: required from 'static void boost::mpl::aux::for_each_impl::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::s_iter<boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > >, boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > > >; LastIterator = boost::mpl::s_iter<boost::mpl::s_item<State<2>, boost::mpl::s_item<State1, boost::mpl::set0<> > >, boost::mpl::set0<> >; TransformFunc = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine::init_flags]'
81 | for_each_impl<boost::is_same<iter,LastIterator>::value>
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
82 | ::execute( static_cast<iter*>(0), static_cast<LastIterator*>(0), static_cast<TransformFunc*>(0), f);
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/mpl/for_each.hpp:105:18: required from 'void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = s_item<State<2>, s_item<State1, set0<> > >; TransformOp = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine::init_flags]'
104 | aux::for_each_impl< boost::is_same<first,last>::value >
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105 | ::execute(static_cast<first*>(0), static_cast<last*>(0), static_cast<TransformOp*>(0), f);
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/msm/back/state_machine.hpp:2386:29: required from 'bool (** boost::msm::back::state_machine<A0, A1, A2, A3, A4>::get_entries_for_flag() const)(const library_sm&) [with Flag = Flag1; A0 = Front; A1 = boost::parameter::void_; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_; flag_handler = bool (*)(const boost::msm::back::state_machine&)]'
2385 | (::boost::mpl::for_each<state_list, boost::msm::wrap< ::boost::mpl::placeholders::1> >
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2386 | (init_flags(flags_entries)),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/msm/back/state_machine.hpp:1518:95: required from 'bool boost::msm::back::state_machine<A0, A1, A2, A3, A4>::is_flag_active() const [with Flag = Flag1; A0 = Front; A1 = boost::parameter::void
; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_]'
1518 | return FlagHelper<Flag,(nr_regions::value>1)>::helper(*this,get_entries_for_flag());
| ~~~~~~~~~~~~~~~~~~~~~~~~~~^~

:42:43: required from here 42 | std::cout << fsm.is_flag_active(); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~ /app/boost/include/boost/mp11/detail/mpl_common.hpp:31:11: error: no type named 'type' in 'struct boost::mp11::detail::mp_pop_front_impl >' 31 | using next = mp11_iterator>; | ^~~~

The code:

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/mpl_list.hpp>

#include <iostream>

template <auto I> struct Event {};
template <auto I> struct Action{
    void operator()(auto&& ...) {}
};
template <int I>
struct State: boost::msm::front::state<> 
{
};
struct Flag1{};
struct State1 : State<1>
{
    using flag_list = boost::mp11::mp_list<Flag1>;
    // all these definition below works - so WA is easy
    // using flag_list = boost::mpl::vector<Flag1>;
    // using flag_list = boost::mpl::vector1<Flag1>;
    // using flag_list = boost::fusion::vector<Flag1>;
};

struct Front : boost::msm::front::state_machine_def<Front> 
{
    struct transition_table : boost::mpl::vector<
        boost::msm::front::Row<State1, Event<1>, State<2>, Action<12>>
    > {};

    using initial_state = boost::mpl::vector<State1>;
};

int main() {
    using Fsm = boost::msm::back::state_machine<Front>;
    Fsm fsm;
    
    fsm.start();
    std::cout << fsm.is_flag_active<Flag1>();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions