My Project
processor_container.hpp
Go to the documentation of this file.
1 #ifndef BOOST_STATECHART_PROCESSOR_CONTAINER_HPP_INCLUDED
2 #define BOOST_STATECHART_PROCESSOR_CONTAINER_HPP_INCLUDED
3 // Copyright 2002-2008 Andreas Huber Doenni
5 // Distributed under the Boost Software License, Version 1.0. (See accompany-
6 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 
9 
10 
13 
14 #include <boost/assert.hpp>
15 #include <boost/ref.hpp>
16 #include <boost/noncopyable.hpp>
17 #include <boost/intrusive_ptr.hpp>
18 #include <boost/shared_ptr.hpp>
19 #include <boost/weak_ptr.hpp>
20 #include <boost/bind.hpp>
21 #include <boost/config.hpp> // BOOST_INTEL
22 
23 #include <boost/detail/workaround.hpp>
24 #include <boost/detail/allocator_utilities.hpp>
25 
26 #include <set>
27 #include <memory> // std::allocator, std::unique_ptr
28 
29 
30 
31 namespace boost
32 {
33 namespace statechart
34 {
35 namespace detail
36 {
37  template<bool IsReferenceWrapper>
38  struct unwrap_impl
39  {
40  template< typename T >
41  struct apply { typedef T type; };
42  };
43 
44  template<>
45  struct unwrap_impl<true>
46  {
47  template< typename T >
48  struct apply { typedef typename T::type & type; };
49  };
50 
51  template<typename T>
52  struct unwrap
53  {
54  typedef typename unwrap_impl<
55  is_reference_wrapper< T >::value >::template apply< T >::type type;
56  };
57 }
58 
59 
60 template<
61  class Scheduler,
62  class WorkItem,
63  class Allocator = std::allocator< none > >
64 class processor_container : noncopyable
65 {
67 #ifdef BOOST_NO_AUTO_PTR
68  typedef std::unique_ptr< processor_base_type > processor_holder_type;
69 #else
70  typedef std::auto_ptr< processor_base_type > processor_holder_type;
71 #endif
72  typedef shared_ptr< processor_holder_type > processor_holder_ptr_type;
73 
74  public:
76  typedef weak_ptr< processor_holder_type > processor_handle;
77 
79  {
81  Scheduler & scheduler, const processor_handle & handle
82  ) :
83  scheduler_( scheduler ),
84  handle_( handle )
85  {
86  }
87 
88  #if BOOST_WORKAROUND( BOOST_INTEL, BOOST_TESTED_AT( 800 ) )
89  public:
90  // for some reason Intel 8.0 seems to think that the following functions
91  // are inaccessible from event_processor<>::event_processor
92  #endif
93 
94  Scheduler & my_scheduler() const { return scheduler_; }
95  const processor_handle & my_handle() const { return handle_; }
96 
97  #if BOOST_WORKAROUND( BOOST_INTEL, BOOST_TESTED_AT( 800 ) )
98  private:
99  #endif
100 
101  // avoids C4512 (assignment operator could not be generated)
102  processor_context & operator=( const processor_context & );
103 
104  Scheduler & scheduler_;
105  const processor_handle handle_;
106 
107  friend class processor_container;
108  friend class event_processor< Scheduler >;
109  };
110 
111  template< class Processor >
112  WorkItem create_processor( processor_handle & handle, Scheduler & scheduler )
113  {
114  processor_holder_ptr_type pProcessor = make_processor_holder();
115  handle = pProcessor;
116  typedef void ( processor_container::*impl_fun_ptr )(
117  const processor_holder_ptr_type &, const processor_context & );
118  impl_fun_ptr pImpl =
119  &processor_container::template create_processor_impl0< Processor >;
120  return WorkItem(
121  boost::bind( pImpl, this, pProcessor,
122  processor_context( scheduler, handle ) ),
123  Allocator() );
124  }
125 
126  template< class Processor, typename Arg1 >
128  processor_handle & handle, Scheduler & scheduler, Arg1 arg1 )
129  {
130  processor_holder_ptr_type pProcessor = make_processor_holder();
131  handle = pProcessor;
132  typedef typename detail::unwrap< Arg1 >::type arg1_type;
133  typedef void ( processor_container::*impl_fun_ptr )(
134  const processor_holder_ptr_type &, const processor_context &,
135  arg1_type );
136  impl_fun_ptr pImpl =
137  &processor_container::template create_processor_impl1<
138  Processor, arg1_type >;
139  return WorkItem(
140  boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
141  arg1 ),
142  Allocator() );
143  }
144 
145  template< class Processor, typename Arg1, typename Arg2 >
147  processor_handle & handle, Scheduler & scheduler, Arg1 arg1, Arg2 arg2 )
148  {
149  processor_holder_ptr_type pProcessor = make_processor_holder();
150  handle = pProcessor;
151  typedef typename detail::unwrap< Arg1 >::type arg1_type;
152  typedef typename detail::unwrap< Arg2 >::type arg2_type;
153  typedef void ( processor_container::*impl_fun_ptr )(
154  const processor_holder_ptr_type &, const processor_context &,
155  arg1_type, arg2_type );
156  impl_fun_ptr pImpl =
157  &processor_container::template create_processor_impl2<
158  Processor, arg1_type, arg2_type >;
159  return WorkItem(
160  boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
161  arg1, arg2 ),
162  Allocator() );
163  }
164 
165  template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
167  processor_handle & handle, Scheduler & scheduler,
168  Arg1 arg1, Arg2 arg2, Arg3 arg3 )
169  {
170  processor_holder_ptr_type pProcessor = make_processor_holder();
171  handle = pProcessor;
172  typedef typename detail::unwrap< Arg1 >::type arg1_type;
173  typedef typename detail::unwrap< Arg2 >::type arg2_type;
174  typedef typename detail::unwrap< Arg3 >::type arg3_type;
175  typedef void ( processor_container::*impl_fun_ptr )(
176  const processor_holder_ptr_type &, const processor_context &,
177  arg1_type, arg2_type, arg3_type );
178  impl_fun_ptr pImpl =
179  &processor_container::template create_processor_impl3<
180  Processor, arg1_type, arg2_type, arg3_type >;
181  return WorkItem(
182  boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
183  arg1, arg2, arg3 ),
184  Allocator() );
185  }
186 
187  template<
188  class Processor, typename Arg1, typename Arg2,
189  typename Arg3, typename Arg4 >
191  processor_handle & handle, Scheduler & scheduler,
192  Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
193  {
194  processor_holder_ptr_type pProcessor = make_processor_holder();
195  handle = pProcessor;
196  typedef typename detail::unwrap< Arg1 >::type arg1_type;
197  typedef typename detail::unwrap< Arg2 >::type arg2_type;
198  typedef typename detail::unwrap< Arg3 >::type arg3_type;
199  typedef typename detail::unwrap< Arg4 >::type arg4_type;
200  typedef void ( processor_container::*impl_fun_ptr )(
201  const processor_holder_ptr_type &, const processor_context &,
202  arg1_type, arg2_type, arg3_type, arg4_type );
203  impl_fun_ptr pImpl =
204  &processor_container::template create_processor_impl4<
205  Processor, arg1_type, arg2_type, arg3_type, arg4_type >;
206  return WorkItem(
207  boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
208  arg1, arg2, arg3, arg4 ),
209  Allocator() );
210  }
211 
212  template<
213  class Processor, typename Arg1, typename Arg2,
214  typename Arg3, typename Arg4, typename Arg5 >
216  processor_handle & handle, Scheduler & scheduler,
217  Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
218  {
219  processor_holder_ptr_type pProcessor = make_processor_holder();
220  handle = pProcessor;
221  typedef typename detail::unwrap< Arg1 >::type arg1_type;
222  typedef typename detail::unwrap< Arg2 >::type arg2_type;
223  typedef typename detail::unwrap< Arg3 >::type arg3_type;
224  typedef typename detail::unwrap< Arg4 >::type arg4_type;
225  typedef typename detail::unwrap< Arg5 >::type arg5_type;
226  typedef void ( processor_container::*impl_fun_ptr )(
227  const processor_holder_ptr_type &, const processor_context &,
228  arg1_type, arg2_type, arg3_type, arg4_type, arg5_type );
229  impl_fun_ptr pImpl =
230  &processor_container::template create_processor_impl5<
231  Processor, arg1_type, arg2_type, arg3_type, arg4_type, arg5_type >;
232  return WorkItem(
233  boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
234  arg1, arg2, arg3, arg4, arg5 ),
235  Allocator() );
236  }
237 
238  template<
239  class Processor, typename Arg1, typename Arg2,
240  typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
242  processor_handle & handle, Scheduler & scheduler,
243  Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
244  {
245  processor_holder_ptr_type pProcessor = make_processor_holder();
246  handle = pProcessor;
247  typedef typename detail::unwrap< Arg1 >::type arg1_type;
248  typedef typename detail::unwrap< Arg2 >::type arg2_type;
249  typedef typename detail::unwrap< Arg3 >::type arg3_type;
250  typedef typename detail::unwrap< Arg4 >::type arg4_type;
251  typedef typename detail::unwrap< Arg5 >::type arg5_type;
252  typedef typename detail::unwrap< Arg6 >::type arg6_type;
253  typedef void ( processor_container::*impl_fun_ptr )(
254  const processor_holder_ptr_type &, const processor_context &,
255  arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type );
256  impl_fun_ptr pImpl =
257  &processor_container::template create_processor_impl6<
258  Processor,
259  arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type >;
260  return WorkItem(
261  boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
262  arg1, arg2, arg3, arg4, arg5, arg6 ),
263  Allocator() );
264  }
265 
266  WorkItem destroy_processor( const processor_handle & processor )
267  {
268  return WorkItem(
269  boost::bind( &processor_container::destroy_processor_impl, this, processor ),
270  Allocator() );
271  }
272 
273  WorkItem initiate_processor( const processor_handle & processor )
274  {
275  return WorkItem(
276  boost::bind( &processor_container::initiate_processor_impl, this,
277  processor ),
278  Allocator() );
279  }
280 
281  WorkItem terminate_processor( const processor_handle & processor )
282  {
283  return WorkItem(
284  boost::bind( &processor_container::terminate_processor_impl, this,
285  processor ),
286  Allocator() );
287  }
288 
289  typedef intrusive_ptr< const event_base > event_ptr_type;
290 
291  WorkItem queue_event(
292  const processor_handle & processor, const event_ptr_type & pEvent )
293  {
294  BOOST_ASSERT( pEvent.get() != 0 );
295 
296  return WorkItem(
297  boost::bind( &processor_container::queue_event_impl, this, processor,
298  pEvent ),
299  Allocator() );
300  }
301 
302  private:
304  processor_holder_ptr_type make_processor_holder()
305  {
306  return processor_holder_ptr_type( new processor_holder_type() );
307  }
308 
309  template< class Processor >
310  void create_processor_impl0(
311  const processor_holder_ptr_type & pProcessor,
312  const processor_context & context )
313  {
314  processorSet_.insert( pProcessor );
315  *pProcessor = processor_holder_type( new Processor( context ) );
316  }
317 
318  template< class Processor, typename Arg1 >
319  void create_processor_impl1(
320  const processor_holder_ptr_type & pProcessor,
321  const processor_context & context, Arg1 arg1 )
322  {
323  processorSet_.insert( pProcessor );
324  *pProcessor = processor_holder_type( new Processor( context, arg1 ) );
325  }
326 
327  template< class Processor, typename Arg1, typename Arg2 >
328  void create_processor_impl2(
329  const processor_holder_ptr_type & pProcessor,
330  const processor_context & context, Arg1 arg1, Arg2 arg2 )
331  {
332  processorSet_.insert( pProcessor );
333  *pProcessor = processor_holder_type( new Processor( context, arg1, arg2 ) );
334  }
335 
336  template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
337  void create_processor_impl3(
338  const processor_holder_ptr_type & pProcessor,
339  const processor_context & context, Arg1 arg1, Arg2 arg2, Arg3 arg3 )
340  {
341  processorSet_.insert( pProcessor );
342  *pProcessor = processor_holder_type( new Processor( context, arg1, arg2, arg3 ) );
343  }
344 
345  template<
346  class Processor, typename Arg1, typename Arg2,
347  typename Arg3, typename Arg4 >
348  void create_processor_impl4(
349  const processor_holder_ptr_type & pProcessor,
350  const processor_context & context,
351  Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
352  {
353  processorSet_.insert( pProcessor );
354  *pProcessor = processor_holder_type( new Processor( context, arg1, arg2, arg3, arg4 ) );
355  }
356 
357  template<
358  class Processor, typename Arg1, typename Arg2,
359  typename Arg3, typename Arg4, typename Arg5 >
360  void create_processor_impl5(
361  const processor_holder_ptr_type & pProcessor,
362  const processor_context & context,
363  Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
364  {
365  processorSet_.insert( pProcessor );
366  *pProcessor = processor_holder_type( new Processor( context, arg1, arg2, arg3, arg4, arg5 ) );
367  }
368 
369  template<
370  class Processor, typename Arg1, typename Arg2,
371  typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
372  void create_processor_impl6(
373  const processor_holder_ptr_type & pProcessor,
374  const processor_context & context,
375  Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
376  {
377  processorSet_.insert( pProcessor );
378  *pProcessor = processor_holder_type( new Processor( context, arg1, arg2, arg3, arg4, arg5, arg6 ) );
379  }
380 
381  void destroy_processor_impl( const processor_handle & processor )
382  {
383  const processor_holder_ptr_type pProcessor = processor.lock();
384 
385  if ( pProcessor != 0 )
386  {
387  processorSet_.erase( pProcessor );
388  }
389  }
390 
391  void initiate_processor_impl( const processor_handle & processor )
392  {
393  const processor_holder_ptr_type pProcessor = processor.lock();
394 
395  if ( pProcessor != 0 )
396  {
397  ( *pProcessor )->initiate();
398  }
399  }
400 
401  void terminate_processor_impl( const processor_handle & processor )
402  {
403  const processor_holder_ptr_type pProcessor = processor.lock();
404 
405  if ( pProcessor != 0 )
406  {
407  ( *pProcessor )->terminate();
408  }
409  }
410 
411  void queue_event_impl(
412  const processor_handle & processor, const event_ptr_type & pEvent )
413  {
414  const processor_holder_ptr_type pProcessor = processor.lock();
415 
416  if ( pProcessor != 0 )
417  {
418  ( *pProcessor )->process_event( *pEvent );
419  }
420  }
421 
422  typedef std::set<
423  processor_holder_ptr_type,
424  std::less< processor_holder_ptr_type >,
425  typename boost::detail::allocator::rebind_to<
426  Allocator, processor_holder_ptr_type >::type
427  > event_processor_set_type;
428 
429  event_processor_set_type processorSet_;
430 };
431 
432 
433 } // namespace statechart
434 } // namespace boost
435 
436 
437 
438 #endif
event_base.hpp
boost::statechart::processor_container::queue_event
WorkItem queue_event(const processor_handle &processor, const event_ptr_type &pEvent)
Definition: processor_container.hpp:291
boost::statechart::detail::unwrap_impl::apply
Definition: processor_container.hpp:41
boost::statechart::event_processor
Definition: event_processor.hpp:25
boost::statechart::processor_container::initiate_processor
WorkItem initiate_processor(const processor_handle &processor)
Definition: processor_container.hpp:273
boost::statechart::processor_container::terminate_processor
WorkItem terminate_processor(const processor_handle &processor)
Definition: processor_container.hpp:281
boost
Definition: asynchronous_state_machine.hpp:20
boost::statechart::processor_container::create_processor
WorkItem create_processor(processor_handle &handle, Scheduler &scheduler, Arg1 arg1)
Definition: processor_container.hpp:127
boost::statechart::processor_container::create_processor
WorkItem create_processor(processor_handle &handle, Scheduler &scheduler)
Definition: processor_container.hpp:112
boost::statechart::processor_container::create_processor
WorkItem create_processor(processor_handle &handle, Scheduler &scheduler, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
Definition: processor_container.hpp:190
boost::statechart::processor_container::create_processor
WorkItem create_processor(processor_handle &handle, Scheduler &scheduler, Arg1 arg1, Arg2 arg2, Arg3 arg3)
Definition: processor_container.hpp:166
boost::statechart::processor_container
Definition: processor_container.hpp:65
boost::statechart::processor_container::processor_handle
weak_ptr< processor_holder_type > processor_handle
Definition: processor_container.hpp:76
boost::statechart::processor_container::create_processor
WorkItem create_processor(processor_handle &handle, Scheduler &scheduler, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6)
Definition: processor_container.hpp:241
boost::statechart::detail::unwrap_impl
Definition: processor_container.hpp:39
boost::statechart::detail::unwrap_impl< true >::apply::type
T::type & type
Definition: processor_container.hpp:48
boost::statechart::processor_container::event_ptr_type
intrusive_ptr< const event_base > event_ptr_type
Definition: processor_container.hpp:289
boost::statechart::processor_container::destroy_processor
WorkItem destroy_processor(const processor_handle &processor)
Definition: processor_container.hpp:266
boost::statechart::processor_container::processor_context
Definition: processor_container.hpp:79
event_processor.hpp
boost::statechart::detail::unwrap
Definition: processor_container.hpp:53
boost::statechart::detail::unwrap::type
unwrap_impl< is_reference_wrapper< T >::value >::template apply< T >::type type
Definition: processor_container.hpp:55
boost::statechart::processor_container::create_processor
WorkItem create_processor(processor_handle &handle, Scheduler &scheduler, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
Definition: processor_container.hpp:215
boost::statechart::detail::unwrap_impl::apply::type
T type
Definition: processor_container.hpp:41
boost::statechart::processor_container::create_processor
WorkItem create_processor(processor_handle &handle, Scheduler &scheduler, Arg1 arg1, Arg2 arg2)
Definition: processor_container.hpp:146