boostorg / boostorg/mp11

boost::mp11::mp_list can't be used as base class for transition table within msm::front::state_machine_def

Open
#63 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
291
Forks
97
PR merge metrics
No merged PRs in 30d

Description

I just wanted to modernize my code - and try to use `boost::mp11::mp_list` instead of `boost::mpl::vector` in my FSM definitions.

Simplified code is as follows:

```
#include
#include
#include

#include
#include
#include

namespace msm = boost::msm;

namespace test_fsm
{
struct play {};
struct stop {};
struct player_ : public msm::front::state_machine_def
{
typedef int no_exception_thrown;
typedef int no_message_queue;

struct Empty : public msm::front::state<>
{
template void on_entry(Event const&,FSM& ) { std::cout << "entering: Empty" << std::endl; }
template void on_exit(Event const&,FSM& ) { std::cout << "leaving: Empty" << std::endl; }
};
struct Playing : public msm::front::state<>
{
template void on_entry(Event const&,FSM& ) { std::cout << "entering: Playing" << std::endl; }
template void on_exit(Event const&,FSM& ) { std::cout << "leaving: Playing" << std::endl; }
};

typedef Empty initial_state;

// transition actions
void playing(play const&) { }
void stop_playing(stop const&) { }

typedef player_ p;

struct transition_table : boost::mp11::mp_list<
_row < Empty , play , Playing >,
_row < Playing , stop , Empty >
> {};

// Replaces the default no-transition response.
template
void no_transition(Event const& e, FSM&,int state)
{
std::cout << "no transition from state " << state
<< " on event " << typeid(e).name() << std::endl;
}

typedef msm::back::state_machine player;

//
// Testing utilities.
//
static char const* const state_names[] = { "Empty", "Playing" };

void pstate(player const& p)
{
std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
}
};

}

int main()
{
test_fsm::player p2;
p2.start();
p2.process_event(test_fsm::play());
p2.process_event(test_fsm::stop());
return 0;
}

```

It compiles, but produces unexpected output:

```
entering: Empty
no transition from state 0 on event N8test_fsm4playE
no transition from state 0 on event N8test_fsm4stopE

```

While - with original version (just replacing mp11::mp_list with mpl::vector) it works as expected:

```
entering: Empty
leaving: Empty
entering: Playing
leaving: Playing
entering: Empty

```

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:

```
using transition_table = boost::mp11::mp_list<
_row < Empty , play , Playing >,
_row < Playing , stop , Empty >
> ;

```

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 - 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.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.