2

boost msm ライブラリを使用して有限状態マシンを作成しました。イベントとその遷移は、コンパイル時に宣言的に定義されます。ただし、実行時には、入力データに基づいて適切なイベントを選択するコードが必要です。現在、コードは次のようになっています。

enum : unsigned {
    fin = (1 << 0),
    syn = (1 << 1),
    ack = (1 << 4)
    // etc...
};

// events
struct receive_syn {};
struct receive_syn_ack {};
struct receive_fin {};
struct receive_fin_ack {};
struct receive_ack {};
// etc..

void receive(const Segment& segment)
{
    switch (segment.getFlags())
    {
        case syn|ack: state_machine.process_event(receive_syn_ack{}); break;
        case syn:     state_machine.process_event(receive_syn{}); break;
        case fin|ack: state_machine.process_event(receive_fin_ack{}); break;
        case fin:     state_machine.process_event(receive_fin{}); break;
        case ack:     state_machine.process_event(receive_ack{}); break;
        // etc..
    }
}

それは動作し、おそらく高速です。しかし、これはもっと宣言的なスタイルで書かれるべきだと思います。

追加のランタイム オーバーヘッドを導入することなく、より高いレベルのプログラミング スタイルでこれを実装するにはどうすればよいでしょうか?

参考までに、boost::msm の例を次に示します。

4

2 に答える 2

2

以下は機能するはずです (テストされていないコード)。フラグが多すぎなくても非常に効率的です — O(log n) ですが、反復処理は高速です。

// your enum
enum: unsigned
{
  fin = (1 << 0),
  syn = (1 << 1),
  ack = (1 << 4)
  // etc...
};

// this is used for the magic:
unsigned all = fin|syn|ack|...;

// this replaces your individual receive types:
template<unsigned> struct receive {};

// this is the magic translation to compile time
template<unsigned bit = 1, unsigned mask = all, unsigned value = 0> struct call
{
  void process(state_machine_type& state_machine, unsigned flags)
  {
    if (flags & bit)
      call<(bit << 1), mask & ~bit, value | bit>::process(state_machine, flags);
    else
      call<(bit << 1), mask & ~bit, value>::process(state_machine, flags);
  }
};

template<unsigned bit, unsigned value> struct call<bit, 0, value>
{
  void process(state_machine_type& state_machine, unsigned)
  {
    state_machine.process_event(receive<value>{});
  }
};

// the rewrite of your receive function
void receive(const Segment& segment)
{
  call<>::process(state_machine, segment.getFlags());
}
于 2013-06-05T21:12:59.403 に答える