使用boost msm状态机处理超过50个转换的问题

3

MSM的状态转换表使用mpl::vector。默认最大大小为20。可以通过以下方式更改其大小:

#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
#define BOOST_MPL_LIMIT_VECTOR_SIZE 50                
#define BOOST_MPL_LIMIT_MAP_SIZE 50 

允许大小达到50。根据文档(https://www.boost.org/doc/libs/1_80_0/libs/msm/doc/HTML/ch05.html),通过添加(例如60)mpl/vector60.hpp和mpl/map60.hpp可以进一步增加大小。

在boost/mpl/vector中,我找到了vector50_c.hpp和vector50.hpp文件。vector50.hpp的内容为:

#ifndef BOOST_MPL_VECTOR_VECTOR50_HPP_INCLUDED
#define BOOST_MPL_VECTOR_VECTOR50_HPP_INCLUDED

// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under the Boost Software License, Version 1.0. 
// (See accompanying file LICENSE_1_0.txt or copy at 
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/mpl for documentation.

// $Id$
// $Date$
// $Revision$

#if !defined(BOOST_MPL_PREPROCESSING_MODE)
#   include <boost/mpl/vector/vector40.hpp>
#endif

#include <boost/mpl/aux_/config/use_preprocessed.hpp>

#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
    && !defined(BOOST_MPL_PREPROCESSING_MODE)

#   define BOOST_MPL_PREPROCESSED_HEADER vector50.hpp
#   include <boost/mpl/vector/aux_/include_preprocessed.hpp>

#else

#   include <boost/mpl/aux_/config/typeof.hpp>
#   include <boost/mpl/aux_/config/ctps.hpp>
#   include <boost/preprocessor/iterate.hpp>

namespace boost { namespace mpl {

#   define BOOST_PP_ITERATION_PARAMS_1 \
    (3,(41, 50, <boost/mpl/vector/aux_/numbered.hpp>))
#   include BOOST_PP_ITERATE()

}}

#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS

#endif // BOOST_MPL_VECTOR_VECTOR50_HPP_INCLUDED
  1. 我需要添加一个vector60_c.hpp和vector60.hpp文件吗?(这两个文件有什么区别?)
  2. 我应该把它们放在哪里?在boost/mpl/vector内部吗?
  3. 我需要如何修改这个文件?

对于编写vector60.hpp的第一个猜测是:

#ifndef BOOST_MPL_VECTOR_VECTOR60_HPP_INCLUDED
#define BOOST_MPL_VECTOR_VECTOR60_HPP_INCLUDED

// Copyright Aleksey Gurtovoy 2000-2004
//
// Distributed under the Boost Software License, Version 1.0. 
// (See accompanying file LICENSE_1_0.txt or copy at 
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/mpl for documentation.

// $Id$
// $Date$
// $Revision$

#if !defined(BOOST_MPL_PREPROCESSING_MODE)
#   include <boost/mpl/vector/vector50.hpp>
#endif

#include <boost/mpl/aux_/config/use_preprocessed.hpp>

#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
    && !defined(BOOST_MPL_PREPROCESSING_MODE)

#   define BOOST_MPL_PREPROCESSED_HEADER vector60.hpp
#   include <boost/mpl/vector/aux_/include_preprocessed.hpp>

#else

#   include <boost/mpl/aux_/config/typeof.hpp>
#   include <boost/mpl/aux_/config/ctps.hpp>
#   include <boost/preprocessor/iterate.hpp>

namespace boost { namespace mpl {

#   define BOOST_PP_ITERATION_PARAMS_1 \
    (3,(51, 60, <boost/mpl/vector/aux_/numbered.hpp>))
#   include BOOST_PP_ITERATE()

}}

#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS

#endif // BOOST_MPL_VECTOR_VECTOR60_HPP_INCLUDED

编辑: 我正在尝试运行的最小示例

#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
#define BOOST_MPL_LIMIT_VECTOR_SIZE 60
#include <boost/mpl/vector.hpp>

int main() {

    typedef boost::mpl::vector<
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int,
                int
            > vector_51;

    return 0;
}

目前产生了错误

/usr/include/boost/mpl/vector.hpp:36:1: fatal error: boost/mpl/vector/vector60.hpp: No such file or directory
   36 | #   include BOOST_PP_STRINGIZE(boost/mpl/vector/AUX778076_VECTOR_HEADER)

我希望的解决方案是在包含文件之前添加一些代码,以便在编译时生成代码。但让我的示例能够与自己编写的文件一起工作将是一个好的第一步。

2个回答

1
你可以使用boost::mp11::mp_list来替换boost::mpl::vector。 这个boost::mp11库是现代的C++11库(就像它的名字一样),并且它没有限制 - 它只使用可变参数模板。
对于转移表 - 你需要记住它不支持继承 - 所以你需要进行如下替换:
// old mpl::vector way - limitation of 50
struct transition_table : boost::mpl::vector < rows.... >;

// new mp11 way - no limitations
using transition_table = boost::mp11::mp_list<rows...>;

您还需要包含<boost/mp11/mpl.hpp>,以便所有boost::mpl“算法”都可以在boost::mp11上工作。


0
我需要添加文件vector60_c.hpp和vector60.hpp吗?(两者之间有什么区别?)
这取决于MSM是否使用vector或vector_c。区别在于:https://www.boost.org/doc/libs/1_80_0/libs/mpl/doc/refmanual/vector-c.html 你可以在preprocessed/README.txt中找到生成缺失文件的方法。
在我的旧Ubuntu盒子上,我可以:
cd ~/custom/superboost/libs/mpl
python2.7 ./preprocessed/boost_mpl_preprocess.py 

它生成了文件,并修改了许多现有的头文件,例如aux_/preprocessed/plain/vector.hpp,该文件现在包含

template<
      typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na
    , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na
    , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na
    , typename T12 = na, typename T13 = na, typename T14 = na
    , typename T15 = na, typename T16 = na, typename T17 = na
    , typename T18 = na, typename T19 = na, typename T20 = na
    , typename T21 = na, typename T22 = na, typename T23 = na
    , typename T24 = na, typename T25 = na, typename T26 = na
    , typename T27 = na, typename T28 = na, typename T29 = na
    , typename T30 = na, typename T31 = na, typename T32 = na
    , typename T33 = na, typename T34 = na, typename T35 = na
    , typename T36 = na, typename T37 = na, typename T38 = na
    , typename T39 = na, typename T40 = na, typename T41 = na
    , typename T42 = na, typename T43 = na, typename T44 = na
    , typename T45 = na, typename T46 = na, typename T47 = na
    , typename T48 = na, typename T49 = na, typename T50 = na
    , typename T51 = na, typename T52 = na, typename T53 = na
    , typename T54 = na, typename T55 = na, typename T56 = na
    , typename T57 = na, typename T58 = na, typename T59 = na
    , typename T60 = na, typename T61 = na, typename T62 = na
    , typename T63 = na, typename T64 = na, typename T65 = na
    , typename T66 = na, typename T67 = na, typename T68 = na
    , typename T69 = na, typename T70 = na, typename T71 = na
    , typename T72 = na, typename T73 = na, typename T74 = na
    , typename T75 = na, typename T76 = na, typename T77 = na
    , typename T78 = na, typename T79 = na, typename T80 = na
    , typename T81 = na, typename T82 = na, typename T83 = na
    , typename T84 = na, typename T85 = na, typename T86 = na
    , typename T87 = na, typename T88 = na, typename T89 = na
    , typename T90 = na, typename T91 = na, typename T92 = na
    , typename T93 = na, typename T94 = na, typename T95 = na
    , typename T96 = na, typename T97 = na, typename T98 = na
    , typename T99 = na
    >
struct vector;

与之前相比

template<
      typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na
    , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na
    , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na
    , typename T12 = na, typename T13 = na, typename T14 = na
    , typename T15 = na, typename T16 = na, typename T17 = na
    , typename T18 = na, typename T19 = na
    >
struct vector;

我正在使用安装了boost版本1.71的Ubuntu 20.04。我只能找到/usr/include/boost/mpl,其中不包含脚本,而且据我所知也不是执行此操作的正确位置。 这是否适用于已安装的boost版本,如果是,我应该在哪里执行脚本?还是我必须自己构建库? - Darragh
1
它不会在已安装的版本上运行。你至少需要下载tar-ball。MPL只有头文件,所以无需安装它:只需将其放在包含路径中的某个“早期”位置即可。我建议使用boost的操作系统包版本。或者,您可以构建所需的库并安装它们,而不是使用系统软件包。除此之外,您可以质疑您的设计。在<=10个状态内进行如此多的转换似乎相对奇怪。 - sehe
也许相关 https://twitter.com/krisjusiak/status/1575456353946148864 - sehe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接