title: Why does my use of context<State>().method() violate statechart assertion?
body: <p>I've developed some concept code for a project that I will be working on shortly.  The project lends itself to a state machine design and I think boost::statechart will do a good job.  I hit a roadblock when I tried to use context() however.  Here's a sample (I'm happy to put more code up, but I think this is the relevant part):</p>
  
  <pre><code>struct Wait : fsm::simple_state&lt; Wait, Active &gt; {
  
    typedef mpl::list&lt;fsm::transition&lt; UnderflowEvent, Exec&gt; &gt; reactions;
  
   public:
    Wait()
      : m_wait_op() {
      std::cout &lt;&lt; "entering wait state." &lt;&lt; std::endl;
      wait();
    }
    ~Wait() { std::cout &lt;&lt; "exiting wait state." &lt;&lt; std::endl; }
  
   private:
    default_wait m_wait_op;
    fsm::result wait() {
      if(context&lt;Active&gt;().underflow_condition()) {
        m_wait_op();
        return transit&lt;Wait&gt;();
      }
      else if(context&lt;Active&gt;().overflow_condition()) {
        return transit&lt;Exec&gt;();
      }
      else {
        // undefined - keep waiting                                                                                                                                                
      }
    }
  
  };
  </code></pre>
  
  <p>The state Active has methods called "[over|under]flow_condition" which just return true at this point.  Problems with my design aside, I am getting the following assertion failure when I instantiate thusly:</p>
  
  <pre><code>int main(void) {
  
    Throttler my_throttler;
  
    my_throttler.initiate();
  
    return 0;
  
  }
  </code></pre>
  
  <p>and here's the assertion:</p>
  
  <blockquote>
    <p>assertion "get_pointer( stt.pContext_
    ) != 0" failed</p>
  </blockquote>
  
  <p>I looked this assertion up in file "/usr/include/boost/statechart/simple_state.hpp", line 689 (boost 1.45) and the comments say that it is there to prevent simple_state from using contexts.  This puzzled me when I revisited the stopwatch example and saw that the example was doing the very thing I was trying to do.  So I compiled it and this assertion is not violated by the stopwatch code unsurprisingly.  Am I missing something?  Maybe there's something elsewhere in the code that I missed?  Here's the entire header (please remember it's concept code...  I'm not releasing this into the wild until it's been thoroughly genericized):</p>
  
  <pre><code>    #ifndef _THROTTLER_H_
  #define _THROTTLER_H_
  
  #include&lt;queue&gt;
  #include&lt;vector&gt;
  #include&lt;ctime&gt;
  
  #include&lt;boost/statechart/event.hpp&gt;
  #include&lt;boost/statechart/transition.hpp&gt;
  #include&lt;boost/statechart/state_machine.hpp&gt;
  #include&lt;boost/statechart/simple_state.hpp&gt;
  
  #include&lt;boost/mpl/list.hpp&gt;
  
  #include&lt;iostream&gt;
  
  
  namespace mpl = boost::mpl;
  namespace fsm = boost::statechart;
  
  namespace {
  
    unsigned int DEFAULT_WAIT_TIME(1000);
  
  }
  
  struct noop {
  public:
  
    noop() { m_priority = (1 &lt;&lt; sizeof(int)); }
    noop(unsigned int priority) { m_priority = priority; }
    virtual ~noop() {}
  
    bool operator()(void) {
      return true;
    }
    friend bool operator&lt;(noop a, noop b);
  
  private:
    unsigned int m_priority;
  };
  
  
  
  bool operator&lt;(noop a, noop b) {
    return a.m_priority &lt; b.m_priority;
  }
  
  struct compare_noops {
    bool operator()(noop a, noop b) {
    }
  };
  
  
  struct default_wait {
    void operator()(unsigned long msecs = DEFAULT_WAIT_TIME) {
      std::clock_t endtime =
        std::clock() + (msecs*1000*CLOCKS_PER_SEC);
      while(clock() &lt; endtime);
    }
  };
  
  
  
  struct OverflowEvent : fsm::event&lt; OverflowEvent &gt; {};
  struct UnderflowEvent : fsm::event&lt; UnderflowEvent &gt; {};
  struct ResetEvent : fsm::event&lt; ResetEvent &gt; {};
  
  struct Active;
  struct Throttler : fsm::state_machine&lt; Throttler, Active &gt; {};
  
  struct Wait;
  struct Active : fsm::simple_state&lt; Active, Throttler, Wait &gt; {
  
   public:
  
    typedef mpl::list&lt;fsm::transition&lt; ResetEvent, Active&gt; &gt; reactions;
  
    bool overflow_condition(void) { return true; }
    bool underflow_condition(void) { return true; }
  
    void queue_operation(noop op) {
      m_operation_queue.push(op);
    }
    void perform_operation(void) {
      noop op(m_operation_queue.top());
      if(op())
        m_operation_queue.pop();
      else
        throw;
    }
  
   private:
  
    std::priority_queue&lt;noop, std::vector&lt;noop&gt;, compare_noops &gt; m_operation_queue;
   private:
  
    std::priority_queue&lt;noop, std::vector&lt;noop&gt;, compare_noops &gt; m_operation_queue;
  
  };
  
  struct Exec : fsm::simple_state&lt; Exec, Active &gt; {
  
    typedef mpl::list&lt;fsm::transition&lt; OverflowEvent, Wait&gt; &gt; reactions;
  
    Exec() { std::cout &lt;&lt; "entering exec state." &lt;&lt; std::endl; }
    ~Exec() { std::cout &lt;&lt; "exiting exec state." &lt;&lt; std::endl; }
  
  };
  
  struct Wait : fsm::simple_state&lt; Wait, Active &gt; {
  
    typedef mpl::list&lt;fsm::transition&lt; UnderflowEvent, Exec&gt; &gt; reactions;
  
   public:
    Wait()
      : m_wait_op() {
      std::cout &lt;&lt; "entering wait state." &lt;&lt; std::endl;
      wait();
    }
    ~Wait() { std::cout &lt;&lt; "exiting wait state." &lt;&lt; std::endl; }
  
   private:
    default_wait m_wait_op;
    fsm::result wait() {
      if(context&lt;Active&gt;().underflow_condition()) {
        m_wait_op();
        return transit&lt;Wait&gt;();
      }
      else if(context&lt;Active&gt;().overflow_condition()) {
        return transit&lt;Exec&gt;();
      }
      else {
        // undefined - keep waiting                                                                                                                                                
      }
    }
  
  };
  
  
  #endif
  </code></pre>