]> rtime.felk.cvut.cz Git - eurobot/public.git/blob - src/boost/boost/statechart/processor_container.hpp
Add subset of boost library headers needed for compilation on PowerPC
[eurobot/public.git] / src / boost / boost / statechart / processor_container.hpp
1 #ifndef BOOST_STATECHART_PROCESSOR_CONTAINER_HPP_INCLUDED
2 #define BOOST_STATECHART_PROCESSOR_CONTAINER_HPP_INCLUDED
3 //////////////////////////////////////////////////////////////////////////////
4 // 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)
7 //////////////////////////////////////////////////////////////////////////////
8
9
10
11 #include <boost/statechart/event_base.hpp>
12 #include <boost/statechart/event_processor.hpp>
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::auto_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< void > >
64 class processor_container : noncopyable
65 {
66   typedef event_processor< Scheduler > processor_base_type;
67   typedef std::auto_ptr< processor_base_type > processor_holder_type;
68   typedef shared_ptr< processor_holder_type > processor_holder_ptr_type;
69
70   public:
71     //////////////////////////////////////////////////////////////////////////
72     typedef weak_ptr< processor_holder_type > processor_handle;
73
74     class processor_context
75     {
76         processor_context(
77           Scheduler & scheduler, const processor_handle & handle
78         ) :
79           scheduler_( scheduler ),
80           handle_( handle )
81         {
82         }
83
84       #if BOOST_WORKAROUND( BOOST_INTEL, BOOST_TESTED_AT( 800 ) )
85       public:
86       // for some reason Intel 8.0 seems to think that the following functions
87       // are inaccessible from event_processor<>::event_processor
88       #endif
89
90         Scheduler & my_scheduler() const { return scheduler_; }
91         const processor_handle & my_handle() const { return handle_; }
92
93       #if BOOST_WORKAROUND( BOOST_INTEL, BOOST_TESTED_AT( 800 ) )
94       private:
95       #endif
96
97         // avoids C4512 (assignment operator could not be generated)
98         processor_context & operator=( const processor_context & );
99
100         Scheduler & scheduler_;
101         const processor_handle handle_;
102
103         friend class processor_container;
104         friend class event_processor< Scheduler >;
105     };
106
107     template< class Processor >
108     WorkItem create_processor( processor_handle & handle, Scheduler & scheduler )
109     {
110       processor_holder_ptr_type pProcessor = make_processor_holder();
111       handle = pProcessor;
112       typedef void ( processor_container::*impl_fun_ptr )(
113         const processor_holder_ptr_type &, const processor_context & );
114       impl_fun_ptr pImpl =
115         &processor_container::template create_processor_impl0< Processor >;
116       return WorkItem(
117         boost::bind( pImpl, this, pProcessor,
118           processor_context( scheduler, handle ) ),
119         Allocator() );
120     }
121
122     template< class Processor, typename Arg1 >
123     WorkItem create_processor(
124       processor_handle & handle, Scheduler & scheduler, Arg1 arg1 )
125     {
126       processor_holder_ptr_type pProcessor = make_processor_holder();
127       handle = pProcessor;
128       typedef typename detail::unwrap< Arg1 >::type arg1_type;
129       typedef void ( processor_container::*impl_fun_ptr )(
130         const processor_holder_ptr_type &, const processor_context &,
131         arg1_type );
132       impl_fun_ptr pImpl =
133         &processor_container::template create_processor_impl1<
134           Processor, arg1_type >;
135       return WorkItem(
136         boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
137           arg1 ),
138         Allocator() );
139     }
140
141     template< class Processor, typename Arg1, typename Arg2 >
142     WorkItem create_processor(
143       processor_handle & handle, Scheduler & scheduler, Arg1 arg1, Arg2 arg2 )
144     {
145       processor_holder_ptr_type pProcessor = make_processor_holder();
146       handle = pProcessor;
147       typedef typename detail::unwrap< Arg1 >::type arg1_type;
148       typedef typename detail::unwrap< Arg2 >::type arg2_type;
149       typedef void ( processor_container::*impl_fun_ptr )(
150         const processor_holder_ptr_type &, const processor_context &,
151          arg1_type, arg2_type );
152       impl_fun_ptr pImpl =
153         &processor_container::template create_processor_impl2<
154           Processor, arg1_type, arg2_type >;
155       return WorkItem(
156         boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
157           arg1, arg2 ),
158         Allocator() );
159     }
160
161     template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
162     WorkItem create_processor(
163       processor_handle & handle, Scheduler & scheduler,
164       Arg1 arg1, Arg2 arg2, Arg3 arg3 )
165     {
166       processor_holder_ptr_type pProcessor = make_processor_holder();
167       handle = pProcessor;
168       typedef typename detail::unwrap< Arg1 >::type arg1_type;
169       typedef typename detail::unwrap< Arg2 >::type arg2_type;
170       typedef typename detail::unwrap< Arg3 >::type arg3_type;
171       typedef void ( processor_container::*impl_fun_ptr )(
172         const processor_holder_ptr_type &, const processor_context &,
173         arg1_type, arg2_type, arg3_type );
174       impl_fun_ptr pImpl =
175         &processor_container::template create_processor_impl3<
176           Processor, arg1_type, arg2_type, arg3_type >;
177       return WorkItem(
178         boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
179           arg1, arg2, arg3 ),
180         Allocator() );
181     }
182
183     template<
184       class Processor, typename Arg1, typename Arg2,
185       typename Arg3, typename Arg4 >
186     WorkItem create_processor(
187       processor_handle & handle, Scheduler & scheduler,
188       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
189     {
190       processor_holder_ptr_type pProcessor = make_processor_holder();
191       handle = pProcessor;
192       typedef typename detail::unwrap< Arg1 >::type arg1_type;
193       typedef typename detail::unwrap< Arg2 >::type arg2_type;
194       typedef typename detail::unwrap< Arg3 >::type arg3_type;
195       typedef typename detail::unwrap< Arg4 >::type arg4_type;
196       typedef void ( processor_container::*impl_fun_ptr )(
197         const processor_holder_ptr_type &, const processor_context &,
198         arg1_type, arg2_type, arg3_type, arg4_type );
199       impl_fun_ptr pImpl =
200         &processor_container::template create_processor_impl4<
201           Processor, arg1_type, arg2_type, arg3_type, arg4_type >;
202       return WorkItem(
203         boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
204           arg1, arg2, arg3, arg4 ),
205         Allocator() );
206     }
207
208     template<
209       class Processor, typename Arg1, typename Arg2,
210       typename Arg3, typename Arg4, typename Arg5 >
211     WorkItem create_processor(
212       processor_handle & handle, Scheduler & scheduler,
213       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
214     {
215       processor_holder_ptr_type pProcessor = make_processor_holder();
216       handle = pProcessor;
217       typedef typename detail::unwrap< Arg1 >::type arg1_type;
218       typedef typename detail::unwrap< Arg2 >::type arg2_type;
219       typedef typename detail::unwrap< Arg3 >::type arg3_type;
220       typedef typename detail::unwrap< Arg4 >::type arg4_type;
221       typedef typename detail::unwrap< Arg5 >::type arg5_type;
222       typedef void ( processor_container::*impl_fun_ptr )(
223         const processor_holder_ptr_type &, const processor_context &,
224         arg1_type, arg2_type, arg3_type, arg4_type, arg5_type );
225       impl_fun_ptr pImpl =
226         &processor_container::template create_processor_impl5<
227           Processor, arg1_type, arg2_type, arg3_type, arg4_type, arg5_type >;
228       return WorkItem(
229         boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
230           arg1, arg2, arg3, arg4, arg5 ),
231         Allocator() );
232     }
233
234     template<
235       class Processor, typename Arg1, typename Arg2,
236       typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
237     WorkItem create_processor(
238       processor_handle & handle, Scheduler & scheduler,
239       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
240     {
241       processor_holder_ptr_type pProcessor = make_processor_holder();
242       handle = pProcessor;
243       typedef typename detail::unwrap< Arg1 >::type arg1_type;
244       typedef typename detail::unwrap< Arg2 >::type arg2_type;
245       typedef typename detail::unwrap< Arg3 >::type arg3_type;
246       typedef typename detail::unwrap< Arg4 >::type arg4_type;
247       typedef typename detail::unwrap< Arg5 >::type arg5_type;
248       typedef typename detail::unwrap< Arg6 >::type arg6_type;
249       typedef void ( processor_container::*impl_fun_ptr )(
250         const processor_holder_ptr_type &, const processor_context &,
251         arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type );
252       impl_fun_ptr pImpl =
253         &processor_container::template create_processor_impl6<
254           Processor,
255           arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type >;
256       return WorkItem(
257         boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
258           arg1, arg2, arg3, arg4, arg5, arg6 ),
259         Allocator() );
260     }
261
262     WorkItem destroy_processor( const processor_handle & processor )
263     {
264       return WorkItem(
265         boost::bind( &processor_container::destroy_processor_impl, this, processor ),
266         Allocator() );
267     }
268
269     WorkItem initiate_processor( const processor_handle & processor )
270     {
271       return WorkItem(
272         boost::bind( &processor_container::initiate_processor_impl, this,
273           processor ),
274         Allocator() );
275     }
276
277     WorkItem terminate_processor( const processor_handle & processor )
278     {
279       return WorkItem(
280         boost::bind( &processor_container::terminate_processor_impl, this,
281           processor ),
282         Allocator() );
283     }
284
285     typedef intrusive_ptr< const event_base > event_ptr_type;
286
287     WorkItem queue_event(
288       const processor_handle & processor, const event_ptr_type & pEvent )
289     {
290       BOOST_ASSERT( pEvent.get() != 0 );
291
292       return WorkItem(
293         boost::bind( &processor_container::queue_event_impl, this, processor,
294           pEvent ),
295         Allocator() );
296     }
297
298   private:
299     //////////////////////////////////////////////////////////////////////////
300     processor_holder_ptr_type make_processor_holder()
301     {
302       return processor_holder_ptr_type( new processor_holder_type() );
303     }
304
305     template< class Processor >
306     void create_processor_impl0(
307       const processor_holder_ptr_type & pProcessor,
308       const processor_context & context )
309     {
310       processorSet_.insert( pProcessor );
311       processor_holder_type holder( new Processor( context ) );
312       *pProcessor = holder;
313     }
314
315     template< class Processor, typename Arg1 >
316     void create_processor_impl1(
317       const processor_holder_ptr_type & pProcessor,
318       const processor_context & context, Arg1 arg1 )
319     {
320       processorSet_.insert( pProcessor );
321       processor_holder_type holder( new Processor( context, arg1 ) );
322       *pProcessor = holder;
323     }
324
325     template< class Processor, typename Arg1, typename Arg2 >
326     void create_processor_impl2(
327       const processor_holder_ptr_type & pProcessor,
328       const processor_context & context, Arg1 arg1, Arg2 arg2 )
329     {
330       processorSet_.insert( pProcessor );
331       processor_holder_type holder( new Processor( context, arg1, arg2 ) );
332       *pProcessor = holder;
333     }
334
335     template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
336     void create_processor_impl3(
337       const processor_holder_ptr_type & pProcessor,
338       const processor_context & context, Arg1 arg1, Arg2 arg2, Arg3 arg3 )
339     {
340       processorSet_.insert( pProcessor );
341       processor_holder_type holder(
342         new Processor( context, arg1, arg2, arg3 ) );
343       *pProcessor = holder;
344     }
345
346     template<
347       class Processor, typename Arg1, typename Arg2,
348       typename Arg3, typename Arg4 >
349     void create_processor_impl4(
350       const processor_holder_ptr_type & pProcessor,
351       const processor_context & context,
352       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
353     {
354       processorSet_.insert( pProcessor );
355       processor_holder_type holder(
356         new Processor( context, arg1, arg2, arg3, arg4 ) );
357       *pProcessor = holder;
358     }
359
360     template<
361       class Processor, typename Arg1, typename Arg2,
362       typename Arg3, typename Arg4, typename Arg5 >
363     void create_processor_impl5(
364       const processor_holder_ptr_type & pProcessor,
365       const processor_context & context,
366       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
367     {
368       processorSet_.insert( pProcessor );
369       processor_holder_type holder(
370         new Processor( context, arg1, arg2, arg3, arg4, arg5 ) );
371       *pProcessor = holder;
372     }
373
374     template<
375       class Processor, typename Arg1, typename Arg2,
376       typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
377     void create_processor_impl6(
378       const processor_holder_ptr_type & pProcessor,
379       const processor_context & context,
380       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
381     {
382       processorSet_.insert( pProcessor );
383       processor_holder_type holder(
384         new Processor( context, arg1, arg2, arg3, arg4, arg5, arg6 ) );
385       *pProcessor = holder;
386     }
387
388     void destroy_processor_impl( const processor_handle & processor )
389     {
390       const processor_holder_ptr_type pProcessor = processor.lock();
391
392       if ( pProcessor != 0 )
393       {
394         processorSet_.erase( pProcessor );
395       }
396     }
397
398     void initiate_processor_impl( const processor_handle & processor )
399     {
400       const processor_holder_ptr_type pProcessor = processor.lock();
401
402       if ( pProcessor != 0 )
403       {
404         ( *pProcessor )->initiate();
405       }
406     }
407
408     void terminate_processor_impl( const processor_handle & processor )
409     {
410       const processor_holder_ptr_type pProcessor = processor.lock();
411
412       if ( pProcessor != 0 )
413       {
414         ( *pProcessor )->terminate();
415       }
416     }
417
418     void queue_event_impl(
419       const processor_handle & processor, const event_ptr_type & pEvent )
420     {
421       const processor_holder_ptr_type pProcessor = processor.lock();
422
423       if ( pProcessor != 0 )
424       {
425         ( *pProcessor )->process_event( *pEvent );
426       }
427     }
428
429     typedef std::set< 
430       processor_holder_ptr_type, 
431       std::less< processor_holder_ptr_type >,
432       typename boost::detail::allocator::rebind_to<
433         Allocator, processor_holder_ptr_type >::type
434     > event_processor_set_type;
435
436     event_processor_set_type processorSet_;
437 };
438
439
440 } // namespace statechart
441 } // namespace boost
442
443
444
445 #endif