include/deal.II/base/thread_management.h

00001 //---------------------------------------------------------------------------
00002 //    @f$Id: thread_management.h 25345 2012-03-31 08:37:04Z bangerth @f$
00003 //
00004 //    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by the deal.II authors
00005 //
00006 //    This file is subject to QPL and may not be  distributed
00007 //    without copyright and license information. Please refer
00008 //    to the file deal.II/doc/license.html for the  text  and
00009 //    further information on this license.
00010 //
00011 //---------------------------------------------------------------------------
00012 #ifndef __deal2__thread_management_h
00013 #define __deal2__thread_management_h
00014 
00015 
00016 #include <deal.II/base/config.h>
00017 #include <deal.II/base/exceptions.h>
00018 #include <deal.II/base/template_constraints.h>
00019 #include <deal.II/base/std_cxx1x/tuple.h>
00020 #include <deal.II/base/std_cxx1x/function.h>
00021 #include <deal.II/base/std_cxx1x/shared_ptr.h>
00022 #include <deal.II/base/std_cxx1x/bind.h>
00023 
00024 #if (DEAL_II_USE_MT == 1)
00025 #  include <deal.II/base/std_cxx1x/thread.h>
00026 #  include <deal.II/base/std_cxx1x/mutex.h>
00027 #  include <deal.II/base/std_cxx1x/condition_variable.h>
00028 #endif
00029 
00030 #include <iterator>
00031 #include <vector>
00032 #include <list>
00033 #include <utility>
00034 
00035 
00036 #if DEAL_II_USE_MT == 1
00037 #  if defined(DEAL_II_USE_MT_POSIX)
00038 #    include <pthread.h>
00039 #  endif
00040 #  include <tbb/task.h>
00041 #endif
00042 
00043 
00044 
00045 DEAL_II_NAMESPACE_OPEN
00046 
00049 
00050 
00059 namespace Threads
00060 {
00074   class DummyThreadMutex
00075   {
00076     public:
00110       class ScopedLock
00111       {
00112         public:
00119           ScopedLock (DummyThreadMutex &) {}
00120 
00127           ~ScopedLock () {}
00128       };
00129 
00137       inline void acquire () const {}
00138 
00146       inline void release () const {}
00147   };
00148 
00149 
00150 
00169   class DummyThreadCondition
00170   {
00171     public:
00181       inline void signal () const {}
00182 
00192       inline void broadcast () const {}
00193 
00208       inline void wait (DummyThreadMutex &) const {}
00209   };
00210 
00211 
00212 
00228   class DummyBarrier
00229   {
00230     public:
00241       DummyBarrier (const unsigned int  count,
00242                     const char         *name = 0,
00243                     void               *arg  = 0);
00244 
00253       int wait () const { return 0; }
00254 
00259       void dump () const {}
00260 
00267       DeclException1 (ExcBarrierSizeNotUseful,
00268                       int,
00269                       << "In single-thread mode, other barrier sizes than 1 are not "
00270                       << "useful. You gave " << arg1);
00271 
00273   };
00274 
00275 
00276 #if DEAL_II_USE_MT == 1
00277 
00306   class Mutex
00307   {
00308     public:
00342       class ScopedLock
00343       {
00344         public:
00349           ScopedLock (Mutex &m) : mutex(m) { mutex.acquire(); }
00350 
00357           ~ScopedLock () { mutex.release (); }
00358 
00359         private:
00364           Mutex &mutex;
00365       };
00366 
00370       Mutex ()
00371         {}
00372 
00380       Mutex (const Mutex &)
00381                       :
00382                       mutex()
00383         {}
00384 
00385 
00389       inline void acquire () { mutex.lock(); }
00390 
00394       inline void release () { mutex.unlock(); }
00395 
00396     private:
00401       std_cxx1x::mutex mutex;
00402 
00408       friend class ConditionVariable;
00409   };
00410 
00411 
00421   class ConditionVariable
00422   {
00423     public:
00430       inline void signal () { condition_variable.notify_one(); }
00431 
00438       inline void broadcast () { condition_variable.notify_all(); }
00439 
00455       inline void wait (Mutex &mutex)
00456         {
00457           std_cxx1x::unique_lock<std_cxx1x::mutex> lock(mutex.mutex,
00458                                                         std_cxx1x::adopt_lock);
00459           condition_variable.wait (lock);
00460         }
00461 
00462     private:
00467       std_cxx1x::condition_variable condition_variable;
00468   };
00469 
00470 
00499   class PosixThreadBarrier
00500   {
00501     public:
00507       PosixThreadBarrier (const unsigned int  count,
00508                           const char         *name = 0,
00509                           void               *arg  = 0);
00510 
00515       ~PosixThreadBarrier ();
00516 
00529       int wait ();
00530 
00531     private:
00537 #ifndef DEAL_II_USE_MT_POSIX_NO_BARRIERS
00538       pthread_barrier_t barrier;
00539 #else
00540       unsigned int count;
00541 #endif
00542   };
00543 
00544 
00553   typedef Mutex     ThreadMutex;
00554 
00563   typedef ConditionVariable ThreadCondition;
00564 
00571   typedef PosixThreadBarrier   Barrier;
00572 
00573 #else
00574 
00583   typedef DummyThreadMutex     Mutex;
00584   typedef DummyThreadMutex     ThreadMutex;
00585 
00595   typedef DummyThreadCondition ConditionVariable;
00596   typedef DummyThreadCondition ThreadCondition;
00597 
00607   typedef DummyBarrier         Barrier;
00608 #endif
00609 
00610 }
00611 
00612 
00613 namespace Threads
00614 {
00615 
00673   unsigned int n_existing_threads ();
00674 
00692   unsigned int this_thread_id ();
00693 
00717   template <typename ForwardIterator>
00718   std::vector<std::pair<ForwardIterator,ForwardIterator> >
00719   split_range (const ForwardIterator &begin,
00720                const ForwardIterator &end,
00721                const unsigned int n_intervals);
00722 
00734   std::vector<std::pair<unsigned int,unsigned int> >
00735   split_interval (const unsigned int begin,
00736                   const unsigned int end,
00737                   const unsigned int n_intervals);
00738 
00753   namespace internal
00754   {
00785     void handle_std_exception (const std::exception &exc);
00786 
00795     void handle_unknown_exception ();
00796 
00807     void register_thread ();
00808 
00819     void deregister_thread ();
00820   }
00821 
00826 }   // end declarations of namespace Threads
00827 
00828 /* ----------- implementation of functions in namespace Threads ---------- */
00829 #ifndef DOXYGEN
00830 namespace Threads
00831 {
00832   template <typename ForwardIterator>
00833   std::vector<std::pair<ForwardIterator,ForwardIterator> >
00834   split_range (const ForwardIterator &begin,
00835                const ForwardIterator &end,
00836                const unsigned int     n_intervals)
00837   {
00838     typedef std::pair<ForwardIterator,ForwardIterator> IteratorPair;
00839 
00840                                      // in non-multithreaded mode, we
00841                                      // often have the case that this
00842                                      // function is called with
00843                                      // n_intervals==1, so have a
00844                                      // shortcut here to handle that
00845                                      // case efficiently
00846 
00847     if (n_intervals==1)
00848       return (std::vector<IteratorPair>
00849               (1, IteratorPair(begin, end)));
00850 
00851                                      // if more than one interval
00852                                      // requested, do the full work
00853     const unsigned int n_elements              = std::distance (begin, end);
00854     const unsigned int n_elements_per_interval = n_elements / n_intervals;
00855     const unsigned int residual                = n_elements % n_intervals;
00856 
00857     std::vector<IteratorPair> return_values (n_intervals);
00858 
00859     return_values[0].first = begin;
00860     for (unsigned int i=0; i<n_intervals; ++i)
00861       {
00862         if (i != n_intervals-1)
00863           {
00864             return_values[i].second = return_values[i].first;
00865                                              // note: the cast is
00866                                              // performed to avoid a
00867                                              // warning of gcc that in
00868                                              // the library `dist>=0'
00869                                              // is checked (dist has a
00870                                              // template type, which
00871                                              // here is unsigned if no
00872                                              // cast is performed)
00873             std::advance (return_values[i].second,
00874                           static_cast<signed int>(n_elements_per_interval));
00875                                              // distribute residual in
00876                                              // division equally among
00877                                              // the first few
00878                                              // subintervals
00879             if (i < residual)
00880               ++return_values[i].second;
00881 
00882             return_values[i+1].first = return_values[i].second;
00883           }
00884         else
00885           return_values[i].second = end;
00886       }
00887     return return_values;
00888   }
00889 }
00890 
00891 #endif // DOXYGEN
00892 
00893 namespace Threads
00894 {
00895   namespace internal
00896   {
00907     template <typename RT> struct return_value
00908     {
00909       private:
00910         RT value;
00911       public:
00912         inline return_value () : value() {}
00913 
00914         inline RT get () const { return value; }
00915         inline void set (RT v) { value = v; }
00916     };
00917 
00918 
00932     template <typename RT> struct return_value<RT &>
00933     {
00934       private:
00935         RT * value;
00936       public:
00937         inline return_value () : value(0) {}
00938 
00939         inline RT & get () const { return *value; }
00940         inline void set (RT & v) { value = &v; }
00941     };
00942 
00943 
00956     template <> struct return_value<void>
00957     {
00958         static inline void get () {}
00959     };
00960   }
00961 
00962 
00963 
00964   namespace internal
00965   {
00966     template <typename RT>
00967     inline void call (const std_cxx1x::function<RT ()> &function,
00968                       internal::return_value<RT> &ret_val)
00969     {
00970       ret_val.set (function());
00971     }
00972 
00973 
00974     inline void call (const std_cxx1x::function<void ()> &function,
00975                       internal::return_value<void> &)
00976     {
00977       function();
00978     }
00979   }
00980 
00981 
00982 
00983   namespace internal
00984   {
00998     template <typename RT, typename ArgList,
00999               int length = std_cxx1x::tuple_size<ArgList>::value>
01000     struct fun_ptr_helper;
01001 
01002 
01010     template <typename RT, typename ArgList>
01011     struct fun_ptr_helper<RT, ArgList, 0>
01012     {
01013         typedef RT (type) ();
01014     };
01015 
01016 
01024     template <typename RT, typename ArgList>
01025     struct fun_ptr_helper<RT, ArgList, 1>
01026     {
01027         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type);
01028     };
01029 
01030 
01038     template <typename RT, typename ArgList>
01039     struct fun_ptr_helper<RT, ArgList, 2>
01040     {
01041         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01042                            typename std_cxx1x::tuple_element<1,ArgList>::type);
01043     };
01044 
01045 
01053     template <typename RT, typename ArgList>
01054     struct fun_ptr_helper<RT, ArgList, 3>
01055     {
01056         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01057                            typename std_cxx1x::tuple_element<1,ArgList>::type,
01058                            typename std_cxx1x::tuple_element<2,ArgList>::type);
01059     };
01060 
01061 
01069     template <typename RT, typename ArgList>
01070     struct fun_ptr_helper<RT, ArgList, 4>
01071     {
01072         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01073                            typename std_cxx1x::tuple_element<1,ArgList>::type,
01074                            typename std_cxx1x::tuple_element<2,ArgList>::type,
01075                            typename std_cxx1x::tuple_element<3,ArgList>::type);
01076     };
01077 
01078 
01086     template <typename RT, typename ArgList>
01087     struct fun_ptr_helper<RT, ArgList, 5>
01088     {
01089         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01090                            typename std_cxx1x::tuple_element<1,ArgList>::type,
01091                            typename std_cxx1x::tuple_element<2,ArgList>::type,
01092                            typename std_cxx1x::tuple_element<3,ArgList>::type,
01093                            typename std_cxx1x::tuple_element<4,ArgList>::type);
01094     };
01095 
01096 
01104     template <typename RT, typename ArgList>
01105     struct fun_ptr_helper<RT, ArgList, 6>
01106     {
01107         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01108                            typename std_cxx1x::tuple_element<1,ArgList>::type,
01109                            typename std_cxx1x::tuple_element<2,ArgList>::type,
01110                            typename std_cxx1x::tuple_element<3,ArgList>::type,
01111                            typename std_cxx1x::tuple_element<4,ArgList>::type,
01112                            typename std_cxx1x::tuple_element<5,ArgList>::type);
01113     };
01114 
01115 
01123     template <typename RT, typename ArgList>
01124     struct fun_ptr_helper<RT, ArgList, 7>
01125     {
01126         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01127                            typename std_cxx1x::tuple_element<1,ArgList>::type,
01128                            typename std_cxx1x::tuple_element<2,ArgList>::type,
01129                            typename std_cxx1x::tuple_element<3,ArgList>::type,
01130                            typename std_cxx1x::tuple_element<4,ArgList>::type,
01131                            typename std_cxx1x::tuple_element<5,ArgList>::type,
01132                            typename std_cxx1x::tuple_element<6,ArgList>::type);
01133     };
01134 
01135 
01143     template <typename RT, typename ArgList>
01144     struct fun_ptr_helper<RT, ArgList, 8>
01145     {
01146         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01147                            typename std_cxx1x::tuple_element<1,ArgList>::type,
01148                            typename std_cxx1x::tuple_element<2,ArgList>::type,
01149                            typename std_cxx1x::tuple_element<3,ArgList>::type,
01150                            typename std_cxx1x::tuple_element<4,ArgList>::type,
01151                            typename std_cxx1x::tuple_element<5,ArgList>::type,
01152                            typename std_cxx1x::tuple_element<6,ArgList>::type,
01153                            typename std_cxx1x::tuple_element<7,ArgList>::type);
01154     };
01155 
01156 
01164     template <typename RT, typename ArgList>
01165     struct fun_ptr_helper<RT, ArgList, 9>
01166     {
01167         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01168                            typename std_cxx1x::tuple_element<1,ArgList>::type,
01169                            typename std_cxx1x::tuple_element<2,ArgList>::type,
01170                            typename std_cxx1x::tuple_element<3,ArgList>::type,
01171                            typename std_cxx1x::tuple_element<4,ArgList>::type,
01172                            typename std_cxx1x::tuple_element<5,ArgList>::type,
01173                            typename std_cxx1x::tuple_element<6,ArgList>::type,
01174                            typename std_cxx1x::tuple_element<7,ArgList>::type,
01175                            typename std_cxx1x::tuple_element<8,ArgList>::type);
01176     };
01177 
01178 
01179 
01187     template <typename RT, typename ArgList>
01188     struct fun_ptr_helper<RT, ArgList, 10>
01189     {
01190         typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
01191                            typename std_cxx1x::tuple_element<1,ArgList>::type,
01192                            typename std_cxx1x::tuple_element<2,ArgList>::type,
01193                            typename std_cxx1x::tuple_element<3,ArgList>::type,
01194                            typename std_cxx1x::tuple_element<4,ArgList>::type,
01195                            typename std_cxx1x::tuple_element<5,ArgList>::type,
01196                            typename std_cxx1x::tuple_element<6,ArgList>::type,
01197                            typename std_cxx1x::tuple_element<7,ArgList>::type,
01198                            typename std_cxx1x::tuple_element<8,ArgList>::type,
01199                            typename std_cxx1x::tuple_element<9,ArgList>::type);
01200     };
01201 
01202 
01203 
01221     template <typename RT, typename ArgList>
01222     struct fun_ptr
01223     {
01224         typedef typename fun_ptr_helper<RT,ArgList>::type type;
01225     };
01226   }
01227 
01228 
01229 
01230   namespace internal
01231   {
01232 #if (DEAL_II_USE_MT == 1)
01233 
01272     template <typename RT>
01273     struct ThreadDescriptor : public std_cxx1x::enable_shared_from_this<ThreadDescriptor<RT> >
01274     {
01286         std_cxx1x::shared_ptr<ThreadDescriptor<RT> > self;
01287 
01292         std_cxx1x::thread thread;
01293 
01299         return_value<RT> ret_val;
01300 
01347         bool thread_is_active;
01348 
01352         ThreadDescriptor ()
01353                         :
01354                         thread_is_active (false)
01355           {}
01356 
01357 
01384         void start (const std_cxx1x::function<RT ()> &function)
01385           {
01386                                              // set the self pointer
01387                                              // and then start the
01388                                              // thread
01389             self = this->shared_from_this ();
01390             thread_is_active = true;
01391             thread = std_cxx1x::thread (thread_entry_point, function, this);
01392           }
01393 
01394 
01398         void join ()
01399           {
01400                                              // see if the thread hasn't been
01401                                              // joined yet. if it has, then
01402                                              // join() is a no-op
01403             if (thread_is_active == true)
01404               {
01405                 Assert (thread.joinable(), ExcInternalError());
01406                 thread.join ();
01407                 thread_is_active = false;
01408               }
01409           }
01410 
01411       private:
01412 
01417         static
01418         void thread_entry_point (const std_cxx1x::function<RT ()> function,
01419                                  ThreadDescriptor<RT> *descriptor)
01420           {
01421                                              // call the function
01422                                              // in question. since an
01423                                              // exception that is
01424                                              // thrown from one of the
01425                                              // called functions will
01426                                              // not propagate to the
01427                                              // main thread, it will
01428                                              // kill the program if
01429                                              // not treated here
01430                                              // before we return to
01431                                              // the operating system's
01432                                              // thread library
01433             internal::register_thread ();
01434             try
01435               {
01436                 call (function, descriptor->ret_val);
01437               }
01438             catch (const std::exception &exc)
01439               {
01440                 internal::handle_std_exception (exc);
01441               }
01442             catch (...)
01443               {
01444                 internal::handle_unknown_exception ();
01445               }
01446             internal::deregister_thread ();
01447 
01448                                              // once we are done,
01449                                              // we can release our
01450                                              // hold on the thread
01451                                              // descriptor
01452                                              // object. if all
01453                                              // Threads::Thread
01454                                              // object that
01455                                              // pointed here
01456                                              // should have gone
01457                                              // out of scope
01458                                              // already, then this
01459                                              // will trigger
01460                                              // destruction of the
01461                                              // descriptor object
01462             Assert (descriptor->self.use_count () > 0,
01463                     ExcInternalError());
01464             descriptor->self.reset ();
01465           }
01466     };
01467 
01468 #else
01469 
01481     template <typename RT>
01482     struct ThreadDescriptor
01483     {
01489         return_value<RT> ret_val;
01490 
01496         void start (const std_cxx1x::function<RT ()> &function)
01497           {
01498             call (function, ret_val);
01499           }
01500 
01504         void join ()
01505           {}
01506     };
01507 
01508 #endif
01509   }
01510 
01511 
01549   template <typename RT = void>
01550   class Thread
01551   {
01552     public:
01557       Thread (const std_cxx1x::function<RT ()> &function)
01558                       :
01559                       thread_descriptor (new internal::ThreadDescriptor<RT>())
01560         {
01561                                            // in a second step, start
01562                                            // the thread. this needs
01563                                            // to be done in two steps
01564                                            // because inside the start
01565                                            // function we call
01566                                            // enable_shared_from_this::shared_from_this
01567                                            // which requires that
01568                                            // there is already a
01569                                            // shared_ptr that owns the
01570                                            // object
01571           thread_descriptor->start (function);
01572         }
01573 
01583       Thread () {}
01584 
01593       void join () const
01594         {
01595           if (thread_descriptor)
01596             thread_descriptor->join ();
01597         }
01598 
01607       RT return_value ()
01608         {
01609           join ();
01610           return thread_descriptor->ret_val.get();
01611         }
01612 
01620       bool valid () const
01621         {
01622           return static_cast<bool>(thread_descriptor);
01623         }
01624 
01625 
01635       bool operator == (const Thread &t)
01636         {
01637           return thread_descriptor == t.thread_descriptor;
01638         }
01639 
01640     private:
01675       std_cxx1x::shared_ptr<internal::ThreadDescriptor<RT> > thread_descriptor;
01676   };
01677 
01678 
01679   namespace internal
01680   {
01690     template <typename T>
01691     struct maybe_make_ref
01692     {
01693         static T act (T &t)
01694           {
01695             return t;
01696           }
01697     };
01698 
01699 
01700 
01710     template <typename T>
01711     struct maybe_make_ref<T &>
01712     {
01713         static std_cxx1x::reference_wrapper<T> act (T &t)
01714           {
01715             return std_cxx1x::ref(t);
01716           }
01717     };
01718   }
01719 
01720 
01721 
01722   namespace internal
01723   {
01748     template <typename RT, typename ArgList, int length>
01749     class fun_encapsulator;
01750 
01751 
01752 // ----------- encapsulators for function objects
01753 
01759     template <typename RT, typename ArgList>
01760     class fun_encapsulator<RT, ArgList, 0>
01761     {
01762       public:
01763         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
01764                         : function (*function)
01765           {}
01766 
01767         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
01768                         : function (function)
01769           {}
01770 
01771         inline
01772         Thread<RT>
01773         operator() ()
01774           {
01775             return Thread<RT> (function);
01776           }
01777 
01778       private:
01779         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
01780     };
01781 
01787     template <typename RT, typename ArgList>
01788     class fun_encapsulator<RT, ArgList, 1>
01789     {
01790       public:
01791         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
01792                         : function (*function)
01793           {}
01794 
01795         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
01796                         : function (function)
01797           {}
01798 
01799         inline
01800         Thread<RT>
01801         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1)
01802           {
01803             return
01804               Thread<RT>
01805               (std_cxx1x::bind (function,
01806                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1)));
01807           }
01808 
01809       private:
01810         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
01811     };
01812 
01818     template <typename RT, typename ArgList>
01819     class fun_encapsulator<RT, ArgList, 2>
01820     {
01821       public:
01822         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
01823                         : function (*function)
01824           {}
01825 
01826         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
01827                         : function (function)
01828           {}
01829 
01830         inline
01831         Thread<RT>
01832         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
01833                     typename std_cxx1x::tuple_element<1,ArgList>::type arg2)
01834           {
01835             return
01836               Thread<RT>
01837               (std_cxx1x::bind (function,
01838                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
01839                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2)));
01840           }
01841 
01842       private:
01843         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
01844     };
01845 
01851     template <typename RT, typename ArgList>
01852     class fun_encapsulator<RT, ArgList, 3>
01853     {
01854       public:
01855         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
01856                         : function (*function)
01857           {}
01858 
01859         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
01860                         : function (function)
01861           {}
01862 
01863         inline
01864         Thread<RT>
01865         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
01866                     typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
01867                     typename std_cxx1x::tuple_element<2,ArgList>::type arg3)
01868           {
01869             return
01870               Thread<RT>
01871               (std_cxx1x::bind (function,
01872                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
01873                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
01874                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3)));
01875           }
01876 
01877       private:
01878         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
01879     };
01880 
01886     template <typename RT, typename ArgList>
01887     class fun_encapsulator<RT, ArgList, 4>
01888     {
01889       public:
01890         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
01891                         : function (*function)
01892           {}
01893 
01894         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
01895                         : function (function)
01896           {}
01897 
01898         inline
01899         Thread<RT>
01900         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
01901                     typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
01902                     typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
01903                     typename std_cxx1x::tuple_element<3,ArgList>::type arg4)
01904           {
01905             return
01906               Thread<RT>
01907               (std_cxx1x::bind (function,
01908                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
01909                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
01910                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
01911                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4)));
01912           }
01913 
01914       private:
01915         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
01916     };
01917 
01923     template <typename RT, typename ArgList>
01924     class fun_encapsulator<RT, ArgList, 5>
01925     {
01926       public:
01927         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
01928                         : function (*function)
01929           {}
01930 
01931         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
01932                         : function (function)
01933           {}
01934 
01935         inline
01936         Thread<RT>
01937         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
01938                     typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
01939                     typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
01940                     typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
01941                     typename std_cxx1x::tuple_element<4,ArgList>::type arg5)
01942           {
01943             return
01944               Thread<RT>
01945               (std_cxx1x::bind (function,
01946                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
01947                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
01948                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
01949                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
01950                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5)));
01951           }
01952 
01953       private:
01954         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
01955     };
01956 
01962     template <typename RT, typename ArgList>
01963     class fun_encapsulator<RT, ArgList, 6>
01964     {
01965       public:
01966         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
01967                         : function (*function)
01968           {}
01969 
01970         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
01971                         : function (function)
01972           {}
01973 
01974         inline
01975         Thread<RT>
01976         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
01977                     typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
01978                     typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
01979                     typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
01980                     typename std_cxx1x::tuple_element<4,ArgList>::type arg5,
01981                     typename std_cxx1x::tuple_element<5,ArgList>::type arg6)
01982           {
01983             return
01984               Thread<RT>
01985               (std_cxx1x::bind (function,
01986                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
01987                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
01988                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
01989                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
01990                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5),
01991                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<5,ArgList>::type>::act(arg6)));
01992           }
01993 
01994       private:
01995         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
01996     };
01997 
02003     template <typename RT, typename ArgList>
02004     class fun_encapsulator<RT, ArgList, 7>
02005     {
02006       public:
02007         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
02008                         : function (*function)
02009           {}
02010 
02011         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
02012                         : function (function)
02013           {}
02014 
02015         inline
02016         Thread<RT>
02017         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
02018                     typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
02019                     typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
02020                     typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
02021                     typename std_cxx1x::tuple_element<4,ArgList>::type arg5,
02022                     typename std_cxx1x::tuple_element<5,ArgList>::type arg6,
02023                     typename std_cxx1x::tuple_element<6,ArgList>::type arg7)
02024           {
02025             return
02026               Thread<RT>
02027               (std_cxx1x::bind (function,
02028                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
02029                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
02030                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
02031                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
02032                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5),
02033                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<5,ArgList>::type>::act(arg6),
02034                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<6,ArgList>::type>::act(arg7)));
02035           }
02036 
02037       private:
02038         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
02039     };
02040 
02046     template <typename RT, typename ArgList>
02047     class fun_encapsulator<RT, ArgList, 8>
02048     {
02049       public:
02050         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
02051                         : function (*function)
02052           {}
02053 
02054         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
02055                         : function (function)
02056           {}
02057 
02058         inline
02059         Thread<RT>
02060         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
02061                     typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
02062                     typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
02063                     typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
02064                     typename std_cxx1x::tuple_element<4,ArgList>::type arg5,
02065                     typename std_cxx1x::tuple_element<5,ArgList>::type arg6,
02066                     typename std_cxx1x::tuple_element<6,ArgList>::type arg7,
02067                     typename std_cxx1x::tuple_element<7,ArgList>::type arg8)
02068           {
02069             return
02070               Thread<RT>
02071               (std_cxx1x::bind (function,
02072                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
02073                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
02074                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
02075                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
02076                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5),
02077                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<5,ArgList>::type>::act(arg6),
02078                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<6,ArgList>::type>::act(arg7),
02079                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<7,ArgList>::type>::act(arg8)));
02080           }
02081 
02082       private:
02083         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
02084     };
02085 
02091     template <typename RT, typename ArgList>
02092     class fun_encapsulator<RT, ArgList, 9>
02093     {
02094       public:
02095         fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
02096                         : function (*function)
02097           {}
02098 
02099         fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
02100                         : function (function)
02101           {}
02102 
02103         inline
02104         Thread<RT>
02105         operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
02106                     typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
02107                     typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
02108                     typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
02109                     typename std_cxx1x::tuple_element<4,ArgList>::type arg5,
02110                     typename std_cxx1x::tuple_element<5,ArgList>::type arg6,
02111                     typename std_cxx1x::tuple_element<6,ArgList>::type arg7,
02112                     typename std_cxx1x::tuple_element<7,ArgList>::type arg8,
02113                     typename std_cxx1x::tuple_element<8,ArgList>::type arg9)
02114           {
02115             return
02116               Thread<RT>
02117               (std_cxx1x::bind (function,
02118                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
02119                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
02120                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
02121                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
02122                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5),
02123                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<5,ArgList>::type>::act(arg6),
02124                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<6,ArgList>::type>::act(arg7),
02125                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<7,ArgList>::type>::act(arg8),
02126                             internal::maybe_make_ref<typename std_cxx1x::tuple_element<8,ArgList>::type>::act(arg9)));
02127           }
02128 
02129       private:
02130         std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
02131     };
02132   }
02133 
02134 
02135 
02136 
02137 // ----------- encapsulators for functions not taking any parameters
02138 
02146   template <typename RT>
02147   inline
02148   internal::fun_encapsulator<RT,std_cxx1x::tuple<>,0>
02149   spawn (RT (*fun_ptr)())
02150   {
02151     return fun_ptr;
02152   }
02153 
02154 
02162   template <typename RT, typename C>
02163   inline
02164   internal::fun_encapsulator<RT,std_cxx1x::tuple<>,0>
02165   spawn (C &c, RT (C::*fun_ptr)())
02166   {
02167     return
02168       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<> >::type>
02169       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c)));
02170   }
02171 
02179   template <typename RT, typename C>
02180   inline
02181   internal::fun_encapsulator<RT,std_cxx1x::tuple<>,0>
02182   spawn (const C &c, RT (C::*fun_ptr)() const)
02183   {
02184     return
02185       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<> >::type>
02186       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c)));
02187   }
02188 
02189 
02190 
02191 
02192 // ----------- encapsulators for unary functions
02193 
02201   template <typename RT, typename Arg1>
02202   inline
02203   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1>,1>
02204   spawn (RT (*fun_ptr)(Arg1))
02205   {
02206     return fun_ptr;
02207   }
02208 
02209 
02210 
02218   template <typename RT, typename C, typename Arg1>
02219   inline
02220   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1>,1>
02221   spawn (C &c, RT (C::*fun_ptr)(Arg1))
02222   {
02223     return
02224       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1> >::type>
02225       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1));
02226   }
02227 
02235   template <typename RT, typename C, typename Arg1>
02236   inline
02237   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1>,1>
02238   spawn (const C &c, RT (C::*fun_ptr)(Arg1) const)
02239   {
02240     return
02241       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1> >::type>
02242       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1));
02243   }
02244 
02245 
02246 // ----------- encapsulators for binary functions
02247 
02255   template <typename RT, typename Arg1, typename Arg2>
02256   inline
02257   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2>,2>
02258   spawn (RT (*fun_ptr)(Arg1,Arg2))
02259   {
02260     return fun_ptr;
02261   }
02262 
02263 
02264 
02272   template <typename RT, typename C, typename Arg1, typename Arg2>
02273   inline
02274   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2>,2>
02275   spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2))
02276   {
02277     return
02278       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1,Arg2> >::type>
02279       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2));
02280   }
02281 
02289   template <typename RT, typename C, typename Arg1, typename Arg2>
02290   inline
02291   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2>,2>
02292   spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2) const)
02293   {
02294     return
02295       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1,Arg2> >::type>
02296       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2));
02297   }
02298 
02299 
02300 // ----------- encapsulators for ternary functions
02301 
02309   template <typename RT,
02310             typename Arg1, typename Arg2, typename Arg3>
02311   inline
02312   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3>,3>
02313   spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3))
02314   {
02315     return fun_ptr;
02316   }
02317 
02318 
02319 
02327   template <typename RT, typename C,
02328             typename Arg1, typename Arg2, typename Arg3>
02329   inline
02330   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3>,3>
02331   spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3))
02332   {
02333     return
02334       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1,Arg2,Arg3> >::type>
02335       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3));
02336   }
02337 
02345   template <typename RT, typename C,
02346             typename Arg1, typename Arg2, typename Arg3>
02347   inline
02348   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3>,3>
02349   spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const)
02350   {
02351     return
02352       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1,Arg2,Arg3> >::type>
02353       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3));
02354   }
02355 
02356 
02357 
02358 // ----------- encapsulators for functions with 4 arguments
02359 
02367   template <typename RT,
02368             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
02369   inline
02370   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4>,4>
02371   spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4))
02372   {
02373     return fun_ptr;
02374   }
02375 
02376 
02377 
02385   template <typename RT, typename C,
02386             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
02387   inline
02388   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4>,4>
02389   spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4))
02390   {
02391     return
02392       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4> >::type>
02393       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4));
02394   }
02395 
02403   template <typename RT, typename C,
02404             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
02405   inline
02406   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4>,4>
02407   spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const)
02408   {
02409     return
02410       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4> >::type>
02411       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4));
02412   }
02413 
02414 
02415 // ----------- encapsulators for functions with 5 arguments
02416 
02424   template <typename RT,
02425             typename Arg1, typename Arg2, typename Arg3,
02426             typename Arg4, typename Arg5>
02427   inline
02428   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>,5>
02429   spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5))
02430   {
02431     return fun_ptr;
02432   }
02433 
02434 
02435 
02443   template <typename RT, typename C,
02444             typename Arg1, typename Arg2, typename Arg3,
02445             typename Arg4, typename Arg5>
02446   inline
02447   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>,5>
02448   spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5))
02449   {
02450     return
02451       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >::type>
02452       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5));
02453   }
02454 
02462   template <typename RT, typename C,
02463             typename Arg1, typename Arg2, typename Arg3,
02464             typename Arg4, typename Arg5>
02465   inline
02466   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>,5>
02467   spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const)
02468   {
02469     return
02470       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >::type>
02471       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5));
02472   }
02473 
02474 
02475 // ----------- encapsulators for functions with 6 arguments
02476 
02484   template <typename RT,
02485             typename Arg1, typename Arg2, typename Arg3,
02486             typename Arg4, typename Arg5, typename Arg6>
02487   inline
02488   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>,6>
02489   spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6))
02490   {
02491     return fun_ptr;
02492   }
02493 
02494 
02495 
02503   template <typename RT, typename C,
02504             typename Arg1, typename Arg2, typename Arg3,
02505             typename Arg4, typename Arg5, typename Arg6>
02506   inline
02507   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>,6>
02508   spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6))
02509   {
02510     return
02511       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >::type>
02512       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5, std_cxx1x::_6));
02513   }
02514 
02522   template <typename RT, typename C,
02523             typename Arg1, typename Arg2, typename Arg3,
02524             typename Arg4, typename Arg5, typename Arg6>
02525   inline
02526   internal::fun_encapsulator<RT,
02527                              std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>,6>
02528   spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const)
02529   {
02530     return
02531       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >::type>
02532       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5, std_cxx1x::_6));
02533   }
02534 
02535 
02536 // ----------- encapsulators for functions with 7 arguments
02537 
02545   template <typename RT,
02546             typename Arg1, typename Arg2, typename Arg3,
02547             typename Arg4, typename Arg5, typename Arg6,
02548             typename Arg7>
02549   inline
02550   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
02551                                              Arg4, Arg5, Arg6, Arg7>,7>
02552   spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7))
02553   {
02554     return fun_ptr;
02555   }
02556 
02557 
02558 
02566   template <typename RT, typename C,
02567             typename Arg1, typename Arg2, typename Arg3,
02568             typename Arg4, typename Arg5, typename Arg6,
02569             typename Arg7>
02570   inline
02571   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
02572                                              Arg4, Arg5, Arg6, Arg7>,7>
02573   spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7))
02574   {
02575     return
02576       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7> >::type>
02577       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5, std_cxx1x::_6, std_cxx1x::_7));
02578   }
02579 
02587   template <typename RT, typename C,
02588             typename Arg1, typename Arg2, typename Arg3,
02589             typename Arg4, typename Arg5, typename Arg6,
02590             typename Arg7>
02591   inline
02592   internal::fun_encapsulator<RT,
02593                              std_cxx1x::tuple<Arg1, Arg2, Arg3,
02594                                           Arg4, Arg5, Arg6, Arg7>,7>
02595   spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const)
02596   {
02597     return
02598       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7> >::type>
02599       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5, std_cxx1x::_6, std_cxx1x::_7));
02600   }
02601 
02602 
02603 // ----------- encapsulators for functions with 8 arguments
02604 
02612   template <typename RT,
02613             typename Arg1, typename Arg2, typename Arg3,
02614             typename Arg4, typename Arg5, typename Arg6,
02615             typename Arg7, typename Arg8>
02616   inline
02617   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
02618                                              Arg4, Arg5, Arg6,
02619                                              Arg7, Arg8>,8>
02620   spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
02621                        Arg6,Arg7,Arg8))
02622   {
02623     return fun_ptr;
02624   }
02625 
02626 
02627 
02635   template <typename RT, typename C,
02636             typename Arg1, typename Arg2, typename Arg3,
02637             typename Arg4, typename Arg5, typename Arg6,
02638             typename Arg7, typename Arg8>
02639   inline
02640   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
02641                                              Arg4, Arg5, Arg6,
02642                                              Arg7, Arg8>,8>
02643   spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
02644                                 Arg6,Arg7,Arg8))
02645   {
02646     return
02647       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> >::type>
02648       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5, std_cxx1x::_6, std_cxx1x::_7, std_cxx1x::_8));
02649   }
02650 
02658   template <typename RT, typename C,
02659             typename Arg1, typename Arg2, typename Arg3,
02660             typename Arg4, typename Arg5, typename Arg6,
02661             typename Arg7, typename Arg8>
02662   inline
02663   internal::fun_encapsulator<RT,
02664                              std_cxx1x::tuple<Arg1, Arg2, Arg3,
02665                                           Arg4, Arg5, Arg6,
02666                                           Arg7, Arg8>,8>
02667   spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
02668                                       Arg6,Arg7,Arg8) const)
02669   {
02670     return
02671       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> >::type>
02672       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5, std_cxx1x::_6, std_cxx1x::_7, std_cxx1x::_8));
02673   }
02674 
02675 
02676 // ----------- encapsulators for functions with 9 arguments
02677 
02685   template <typename RT,
02686             typename Arg1, typename Arg2, typename Arg3,
02687             typename Arg4, typename Arg5, typename Arg6,
02688             typename Arg7, typename Arg8, typename Arg9>
02689   inline
02690   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
02691                                              Arg4, Arg5, Arg6,
02692                                              Arg7, Arg8, Arg9>,9>
02693   spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
02694                        Arg6,Arg7,Arg8,Arg9))
02695   {
02696     return fun_ptr;
02697   }
02698 
02699 
02700 
02708   template <typename RT, typename C,
02709             typename Arg1, typename Arg2, typename Arg3,
02710             typename Arg4, typename Arg5, typename Arg6,
02711             typename Arg7, typename Arg8, typename Arg9>
02712   inline
02713   internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
02714                                              Arg4, Arg5, Arg6,
02715                                              Arg7, Arg8, Arg9>,9>
02716   spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
02717                                 Arg6,Arg7,Arg8,Arg9))
02718   {
02719     return
02720       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> >::type>
02721       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5, std_cxx1x::_6, std_cxx1x::_7, std_cxx1x::_8, std_cxx1x::_9));
02722   }
02723 
02731   template <typename RT, typename C,
02732             typename Arg1, typename Arg2, typename Arg3,
02733             typename Arg4, typename Arg5, typename Arg6,
02734             typename Arg7, typename Arg8, typename Arg9>
02735   inline
02736   internal::fun_encapsulator<RT,
02737                              std_cxx1x::tuple<Arg1, Arg2, Arg3,
02738                                           Arg4, Arg5, Arg6,
02739                                           Arg7, Arg8, Arg9>,9>
02740   spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
02741                                       Arg6,Arg7,Arg8,Arg9) const)
02742   {
02743     return
02744       std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> >::type>
02745       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5, std_cxx1x::_6, std_cxx1x::_7, std_cxx1x::_8, std_cxx1x::_9));
02746   }
02747 
02748 
02749 
02750 // ----------- thread starters for functions not taking any parameters
02751 
02762   template <typename RT>
02763   inline
02764   Thread<RT>
02765   new_thread (const std_cxx1x::function<RT ()> &function)
02766   {
02767     return Thread<RT>(function);
02768   }
02769 
02777   template <typename RT>
02778   inline
02779   Thread<RT>
02780   new_thread (RT (*fun_ptr)())
02781   {
02782     return Thread<RT>(fun_ptr);
02783   }
02784 
02785 
02793   template <typename RT, typename C>
02794   inline
02795   Thread<RT>
02796   new_thread (RT (C::*fun_ptr)(),
02797               typename identity<C>::type &c)
02798   {
02799     return
02800       Thread<RT>
02801       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c)));
02802   }
02803 
02804 
02805 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
02806 
02813   template <typename RT, typename C>
02814   inline
02815   Thread<RT>
02816   new_thread (RT (C::*fun_ptr)() const,
02817               const typename identity<C>::type &c)
02818   {
02819     return
02820       Thread<RT>
02821       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c)));
02822   }
02823 #endif
02824 
02825 
02826 
02827 // ----------- thread starters for unary functions
02828 
02836   template <typename RT, typename Arg1>
02837   inline
02838   Thread<RT>
02839   new_thread (RT (*fun_ptr)(Arg1),
02840               typename identity<Arg1>::type arg1)
02841   {
02842     return
02843       Thread<RT>
02844       (std_cxx1x::bind(fun_ptr,
02845                    internal::maybe_make_ref<Arg1>::act(arg1)));
02846   }
02847 
02848 
02849 
02857   template <typename RT, typename C, typename Arg1>
02858   inline
02859   Thread<RT>
02860   new_thread (RT (C::*fun_ptr)(Arg1),
02861               typename identity<C>::type &c,
02862               typename identity<Arg1>::type arg1)
02863   {
02864     return
02865       Thread<RT>
02866       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
02867                    internal::maybe_make_ref<Arg1>::act(arg1)));
02868   }
02869 
02870 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
02871 
02878   template <typename RT, typename C, typename Arg1>
02879   inline
02880   Thread<RT>
02881   new_thread (RT (C::*fun_ptr)(Arg1) const,
02882               typename identity<const C>::type &c,
02883               typename identity<Arg1>::type arg1)
02884   {
02885     return
02886       Thread<RT>
02887       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
02888                    internal::maybe_make_ref<Arg1>::act(arg1)));
02889   }
02890 #endif
02891 
02892 // ----------- thread starters for binary functions
02893 
02901   template <typename RT, typename Arg1, typename Arg2>
02902   inline
02903   Thread<RT>
02904   new_thread (RT (*fun_ptr)(Arg1,Arg2),
02905               typename identity<Arg1>::type arg1,
02906               typename identity<Arg2>::type arg2)
02907   {
02908     return
02909       Thread<RT>
02910       (std_cxx1x::bind(fun_ptr,
02911                    internal::maybe_make_ref<Arg1>::act(arg1),
02912                    internal::maybe_make_ref<Arg2>::act(arg2)));
02913   }
02914 
02915 
02916 
02924   template <typename RT, typename C, typename Arg1, typename Arg2>
02925   inline
02926   Thread<RT>
02927   new_thread (RT (C::*fun_ptr)(Arg1,Arg2),
02928               typename identity<C>::type &c,
02929               typename identity<Arg1>::type arg1,
02930               typename identity<Arg2>::type arg2)
02931   {
02932     return
02933       Thread<RT>
02934       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
02935                    internal::maybe_make_ref<Arg1>::act(arg1),
02936                    internal::maybe_make_ref<Arg2>::act(arg2)));
02937   }
02938 
02939 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
02940 
02947   template <typename RT, typename C, typename Arg1, typename Arg2>
02948   inline
02949   Thread<RT>
02950   new_thread (RT (C::*fun_ptr)(Arg1,Arg2) const,
02951               typename identity<const C>::type &c,
02952               typename identity<Arg1>::type arg1,
02953               typename identity<Arg2>::type arg2)
02954   {
02955     return
02956       Thread<RT>
02957       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
02958                    internal::maybe_make_ref<Arg1>::act(arg1),
02959                    internal::maybe_make_ref<Arg2>::act(arg2)));
02960   }
02961 #endif
02962 
02963 // ----------- thread starters for ternary functions
02964 
02972   template <typename RT,
02973             typename Arg1, typename Arg2, typename Arg3>
02974   inline
02975   Thread<RT>
02976   new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3),
02977               typename identity<Arg1>::type arg1,
02978               typename identity<Arg2>::type arg2,
02979               typename identity<Arg3>::type arg3)
02980   {
02981     return
02982       Thread<RT>
02983       (std_cxx1x::bind(fun_ptr,
02984                    internal::maybe_make_ref<Arg1>::act(arg1),
02985                    internal::maybe_make_ref<Arg2>::act(arg2),
02986                    internal::maybe_make_ref<Arg3>::act(arg3)));
02987   }
02988 
02989 
02990 
02998   template <typename RT, typename C,
02999             typename Arg1, typename Arg2, typename Arg3>
03000   inline
03001   Thread<RT>
03002   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3),
03003               typename identity<C>::type &c,
03004               typename identity<Arg1>::type arg1,
03005               typename identity<Arg2>::type arg2,
03006               typename identity<Arg3>::type arg3)
03007   {
03008     return
03009       Thread<RT>
03010       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
03011                    internal::maybe_make_ref<Arg1>::act(arg1),
03012                    internal::maybe_make_ref<Arg2>::act(arg2),
03013                    internal::maybe_make_ref<Arg3>::act(arg3)));
03014   }
03015 
03016 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
03017 
03024   template <typename RT, typename C,
03025             typename Arg1, typename Arg2, typename Arg3>
03026   inline
03027   Thread<RT>
03028   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const,
03029               typename identity<const C>::type &c,
03030               typename identity<Arg1>::type arg1,
03031               typename identity<Arg2>::type arg2,
03032               typename identity<Arg3>::type arg3)
03033   {
03034     return
03035       Thread<RT>
03036       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
03037                    internal::maybe_make_ref<Arg1>::act(arg1),
03038                    internal::maybe_make_ref<Arg2>::act(arg2),
03039                    internal::maybe_make_ref<Arg3>::act(arg3)));
03040   }
03041 #endif
03042 
03043 
03044 // ----------- thread starters for functions with 4 arguments
03045 
03053   template <typename RT,
03054             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
03055   inline
03056   Thread<RT>
03057   new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
03058               typename identity<Arg1>::type arg1,
03059               typename identity<Arg2>::type arg2,
03060               typename identity<Arg3>::type arg3,
03061               typename identity<Arg4>::type arg4)
03062   {
03063     return
03064       Thread<RT>
03065       (std_cxx1x::bind(fun_ptr,
03066                    internal::maybe_make_ref<Arg1>::act(arg1),
03067                    internal::maybe_make_ref<Arg2>::act(arg2),
03068                    internal::maybe_make_ref<Arg3>::act(arg3),
03069                    internal::maybe_make_ref<Arg4>::act(arg4)));
03070   }
03071 
03072 
03073 
03081   template <typename RT, typename C,
03082             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
03083   inline
03084   Thread<RT>
03085   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
03086               typename identity<C>::type &c,
03087               typename identity<Arg1>::type arg1,
03088               typename identity<Arg2>::type arg2,
03089               typename identity<Arg3>::type arg3,
03090               typename identity<Arg4>::type arg4)
03091   {
03092     return
03093       Thread<RT>
03094       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
03095                    internal::maybe_make_ref<Arg1>::act(arg1),
03096                    internal::maybe_make_ref<Arg2>::act(arg2),
03097                    internal::maybe_make_ref<Arg3>::act(arg3),
03098                    internal::maybe_make_ref<Arg4>::act(arg4)));
03099   }
03100 
03101 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
03102 
03109   template <typename RT, typename C,
03110             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
03111   inline
03112   Thread<RT>
03113   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const,
03114               typename identity<const C>::type &c,
03115               typename identity<Arg1>::type arg1,
03116               typename identity<Arg2>::type arg2,
03117               typename identity<Arg3>::type arg3,
03118               typename identity<Arg4>::type arg4)
03119   {
03120     return
03121       Thread<RT>
03122       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
03123                    internal::maybe_make_ref<Arg1>::act(arg1),
03124                    internal::maybe_make_ref<Arg2>::act(arg2),
03125                    internal::maybe_make_ref<Arg3>::act(arg3),
03126                    internal::maybe_make_ref<Arg4>::act(arg4)));
03127   }
03128 #endif
03129 
03130 // ----------- thread starters for functions with 5 arguments
03131 
03139   template <typename RT,
03140             typename Arg1, typename Arg2, typename Arg3,
03141             typename Arg4, typename Arg5>
03142   inline
03143   Thread<RT>
03144   new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
03145               typename identity<Arg1>::type arg1,
03146               typename identity<Arg2>::type arg2,
03147               typename identity<Arg3>::type arg3,
03148               typename identity<Arg4>::type arg4,
03149               typename identity<Arg5>::type arg5)
03150   {
03151     return
03152       Thread<RT>
03153       (std_cxx1x::bind(fun_ptr,
03154                    internal::maybe_make_ref<Arg1>::act(arg1),
03155                    internal::maybe_make_ref<Arg2>::act(arg2),
03156                    internal::maybe_make_ref<Arg3>::act(arg3),
03157                    internal::maybe_make_ref<Arg4>::act(arg4),
03158                    internal::maybe_make_ref<Arg5>::act(arg5)));
03159   }
03160 
03161 
03162 
03170   template <typename RT, typename C,
03171             typename Arg1, typename Arg2, typename Arg3,
03172             typename Arg4, typename Arg5>
03173   inline
03174   Thread<RT>
03175   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
03176               typename identity<C>::type &c,
03177               typename identity<Arg1>::type arg1,
03178               typename identity<Arg2>::type arg2,
03179               typename identity<Arg3>::type arg3,
03180               typename identity<Arg4>::type arg4,
03181               typename identity<Arg5>::type arg5)
03182   {
03183     return
03184       Thread<RT>
03185       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
03186                    internal::maybe_make_ref<Arg1>::act(arg1),
03187                    internal::maybe_make_ref<Arg2>::act(arg2),
03188                    internal::maybe_make_ref<Arg3>::act(arg3),
03189                    internal::maybe_make_ref<Arg4>::act(arg4),
03190                    internal::maybe_make_ref<Arg5>::act(arg5)));
03191   }
03192 
03193 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
03194 
03201   template <typename RT, typename C,
03202             typename Arg1, typename Arg2, typename Arg3,
03203             typename Arg4, typename Arg5>
03204   inline
03205   Thread<RT>
03206   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const,
03207               typename identity<const C>::type &c,
03208               typename identity<Arg1>::type arg1,
03209               typename identity<Arg2>::type arg2,
03210               typename identity<Arg3>::type arg3,
03211               typename identity<Arg4>::type arg4,
03212               typename identity<Arg5>::type arg5)
03213   {
03214     return
03215       Thread<RT>
03216       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
03217                    internal::maybe_make_ref<Arg1>::act(arg1),
03218                    internal::maybe_make_ref<Arg2>::act(arg2),
03219                    internal::maybe_make_ref<Arg3>::act(arg3),
03220                    internal::maybe_make_ref<Arg4>::act(arg4),
03221                    internal::maybe_make_ref<Arg5>::act(arg5)));
03222   }
03223 #endif
03224 
03225 // ----------- thread starters for functions with 6 arguments
03226 
03234   template <typename RT,
03235             typename Arg1, typename Arg2, typename Arg3,
03236             typename Arg4, typename Arg5, typename Arg6>
03237   inline
03238   Thread<RT>
03239   new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
03240               typename identity<Arg1>::type arg1,
03241               typename identity<Arg2>::type arg2,
03242               typename identity<Arg3>::type arg3,
03243               typename identity<Arg4>::type arg4,
03244               typename identity<Arg5>::type arg5,
03245               typename identity<Arg6>::type arg6)
03246   {
03247     return
03248       Thread<RT>
03249       (std_cxx1x::bind(fun_ptr,
03250                    internal::maybe_make_ref<Arg1>::act(arg1),
03251                    internal::maybe_make_ref<Arg2>::act(arg2),
03252                    internal::maybe_make_ref<Arg3>::act(arg3),
03253                    internal::maybe_make_ref<Arg4>::act(arg4),
03254                    internal::maybe_make_ref<Arg5>::act(arg5),
03255                    internal::maybe_make_ref<Arg6>::act(arg6)));
03256   }
03257 
03258 
03259 
03267   template <typename RT, typename C,
03268             typename Arg1, typename Arg2, typename Arg3,
03269             typename Arg4, typename Arg5, typename Arg6>
03270   inline
03271   Thread<RT>
03272   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
03273               typename identity<C>::type &c,
03274               typename identity<Arg1>::type arg1,
03275               typename identity<Arg2>::type arg2,
03276               typename identity<Arg3>::type arg3,
03277               typename identity<Arg4>::type arg4,
03278               typename identity<Arg5>::type arg5,
03279               typename identity<Arg6>::type arg6)
03280   {
03281     return
03282       Thread<RT>
03283       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
03284                    internal::maybe_make_ref<Arg1>::act(arg1),
03285                    internal::maybe_make_ref<Arg2>::act(arg2),
03286                    internal::maybe_make_ref<Arg3>::act(arg3),
03287                    internal::maybe_make_ref<Arg4>::act(arg4),
03288                    internal::maybe_make_ref<Arg5>::act(arg5),
03289                    internal::maybe_make_ref<Arg6>::act(arg6)));
03290   }
03291 
03292 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
03293 
03300   template <typename RT, typename C,
03301             typename Arg1, typename Arg2, typename Arg3,
03302             typename Arg4, typename Arg5, typename Arg6>
03303   inline
03304   Thread<RT>
03305   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const,
03306               typename identity<const C>::type &c,
03307               typename identity<Arg1>::type arg1,
03308               typename identity<Arg2>::type arg2,
03309               typename identity<Arg3>::type arg3,
03310               typename identity<Arg4>::type arg4,
03311               typename identity<Arg5>::type arg5,
03312               typename identity<Arg6>::type arg6)
03313   {
03314     return
03315       Thread<RT>
03316       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
03317                    internal::maybe_make_ref<Arg1>::act(arg1),
03318                    internal::maybe_make_ref<Arg2>::act(arg2),
03319                    internal::maybe_make_ref<Arg3>::act(arg3),
03320                    internal::maybe_make_ref<Arg4>::act(arg4),
03321                    internal::maybe_make_ref<Arg5>::act(arg5),
03322                    internal::maybe_make_ref<Arg6>::act(arg6)));
03323   }
03324 #endif
03325 
03326 // ----------- thread starters for functions with 7 arguments
03327 
03335   template <typename RT,
03336             typename Arg1, typename Arg2, typename Arg3,
03337             typename Arg4, typename Arg5, typename Arg6,
03338             typename Arg7>
03339   inline
03340   Thread<RT>
03341   new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
03342               typename identity<Arg1>::type arg1,
03343               typename identity<Arg2>::type arg2,
03344               typename identity<Arg3>::type arg3,
03345               typename identity<Arg4>::type arg4,
03346               typename identity<Arg5>::type arg5,
03347               typename identity<Arg6>::type arg6,
03348               typename identity<Arg7>::type arg7)
03349   {
03350     return
03351       Thread<RT>
03352       (std_cxx1x::bind(fun_ptr,
03353                    internal::maybe_make_ref<Arg1>::act(arg1),
03354                    internal::maybe_make_ref<Arg2>::act(arg2),
03355                    internal::maybe_make_ref<Arg3>::act(arg3),
03356                    internal::maybe_make_ref<Arg4>::act(arg4),
03357                    internal::maybe_make_ref<Arg5>::act(arg5),
03358                    internal::maybe_make_ref<Arg6>::act(arg6),
03359                    internal::maybe_make_ref<Arg7>::act(arg7)));
03360   }
03361 
03362 
03363 
03371   template <typename RT, typename C,
03372             typename Arg1, typename Arg2, typename Arg3,
03373             typename Arg4, typename Arg5, typename Arg6,
03374             typename Arg7>
03375   inline
03376   Thread<RT>
03377   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
03378               typename identity<C>::type &c,
03379               typename identity<Arg1>::type arg1,
03380               typename identity<Arg2>::type arg2,
03381               typename identity<Arg3>::type arg3,
03382               typename identity<Arg4>::type arg4,
03383               typename identity<Arg5>::type arg5,
03384               typename identity<Arg6>::type arg6,
03385               typename identity<Arg7>::type arg7)
03386   {
03387     return
03388       Thread<RT>
03389       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
03390                    internal::maybe_make_ref<Arg1>::act(arg1),
03391                    internal::maybe_make_ref<Arg2>::act(arg2),
03392                    internal::maybe_make_ref<Arg3>::act(arg3),
03393                    internal::maybe_make_ref<Arg4>::act(arg4),
03394                    internal::maybe_make_ref<Arg5>::act(arg5),
03395                    internal::maybe_make_ref<Arg6>::act(arg6),
03396                    internal::maybe_make_ref<Arg7>::act(arg7)));
03397   }
03398 
03399 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
03400 
03407   template <typename RT, typename C,
03408             typename Arg1, typename Arg2, typename Arg3,
03409             typename Arg4, typename Arg5, typename Arg6,
03410             typename Arg7>
03411   inline
03412   Thread<RT>
03413   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const,
03414               typename identity<const C>::type &c,
03415               typename identity<Arg1>::type arg1,
03416               typename identity<Arg2>::type arg2,
03417               typename identity<Arg3>::type arg3,
03418               typename identity<Arg4>::type arg4,
03419               typename identity<Arg5>::type arg5,
03420               typename identity<Arg6>::type arg6,
03421               typename identity<Arg7>::type arg7)
03422   {
03423     return
03424       Thread<RT>
03425       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
03426                    internal::maybe_make_ref<Arg1>::act(arg1),
03427                    internal::maybe_make_ref<Arg2>::act(arg2),
03428                    internal::maybe_make_ref<Arg3>::act(arg3),
03429                    internal::maybe_make_ref<Arg4>::act(arg4),
03430                    internal::maybe_make_ref<Arg5>::act(arg5),
03431                    internal::maybe_make_ref<Arg6>::act(arg6),
03432                    internal::maybe_make_ref<Arg7>::act(arg7)));
03433   }
03434 #endif
03435 
03436 // ----------- thread starters for functions with 8 arguments
03437 
03445   template <typename RT,
03446             typename Arg1, typename Arg2, typename Arg3,
03447             typename Arg4, typename Arg5, typename Arg6,
03448             typename Arg7, typename Arg8>
03449   inline
03450   Thread<RT>
03451   new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
03452                             Arg6,Arg7,Arg8),
03453               typename identity<Arg1>::type arg1,
03454               typename identity<Arg2>::type arg2,
03455               typename identity<Arg3>::type arg3,
03456               typename identity<Arg4>::type arg4,
03457               typename identity<Arg5>::type arg5,
03458               typename identity<Arg6>::type arg6,
03459               typename identity<Arg7>::type arg7,
03460               typename identity<Arg8>::type arg8)
03461   {
03462     return
03463       Thread<RT>
03464       (std_cxx1x::bind(fun_ptr,
03465                    internal::maybe_make_ref<Arg1>::act(arg1),
03466                    internal::maybe_make_ref<Arg2>::act(arg2),
03467                    internal::maybe_make_ref<Arg3>::act(arg3),
03468                    internal::maybe_make_ref<Arg4>::act(arg4),
03469                    internal::maybe_make_ref<Arg5>::act(arg5),
03470                    internal::maybe_make_ref<Arg6>::act(arg6),
03471                    internal::maybe_make_ref<Arg7>::act(arg7),
03472                    internal::maybe_make_ref<Arg8>::act(arg8)));
03473   }
03474 
03475 
03476 
03484   template <typename RT, typename C,
03485             typename Arg1, typename Arg2, typename Arg3,
03486             typename Arg4, typename Arg5, typename Arg6,
03487             typename Arg7, typename Arg8>
03488   inline
03489   Thread<RT>
03490   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
03491                                Arg6,Arg7,Arg8),
03492               typename identity<C>::type &c,
03493               typename identity<Arg1>::type arg1,
03494               typename identity<Arg2>::type arg2,
03495               typename identity<Arg3>::type arg3,
03496               typename identity<Arg4>::type arg4,
03497               typename identity<Arg5>::type arg5,
03498               typename identity<Arg6>::type arg6,
03499               typename identity<Arg7>::type arg7,
03500               typename identity<Arg8>::type arg8)
03501   {
03502     return
03503       Thread<RT>
03504       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
03505                    internal::maybe_make_ref<Arg1>::act(arg1),
03506                    internal::maybe_make_ref<Arg2>::act(arg2),
03507                    internal::maybe_make_ref<Arg3>::act(arg3),
03508                    internal::maybe_make_ref<Arg4>::act(arg4),
03509                    internal::maybe_make_ref<Arg5>::act(arg5),
03510                    internal::maybe_make_ref<Arg6>::act(arg6),
03511                    internal::maybe_make_ref<Arg7>::act(arg7),
03512                    internal::maybe_make_ref<Arg8>::act(arg8)));
03513   }
03514 
03515 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
03516 
03523   template <typename RT, typename C,
03524             typename Arg1, typename Arg2, typename Arg3,
03525             typename Arg4, typename Arg5, typename Arg6,
03526             typename Arg7, typename Arg8>
03527   inline
03528   Thread<RT>
03529   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
03530                                Arg6,Arg7,Arg8) const,
03531               typename identity<const C>::type &c,
03532               typename identity<Arg1>::type arg1,
03533               typename identity<Arg2>::type arg2,
03534               typename identity<Arg3>::type arg3,
03535               typename identity<Arg4>::type arg4,
03536               typename identity<Arg5>::type arg5,
03537               typename identity<Arg6>::type arg6,
03538               typename identity<Arg7>::type arg7,
03539               typename identity<Arg8>::type arg8)
03540   {
03541     return
03542       Thread<RT>
03543       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
03544                    internal::maybe_make_ref<Arg1>::act(arg1),
03545                    internal::maybe_make_ref<Arg2>::act(arg2),
03546                    internal::maybe_make_ref<Arg3>::act(arg3),
03547                    internal::maybe_make_ref<Arg4>::act(arg4),
03548                    internal::maybe_make_ref<Arg5>::act(arg5),
03549                    internal::maybe_make_ref<Arg6>::act(arg6),
03550                    internal::maybe_make_ref<Arg7>::act(arg7),
03551                    internal::maybe_make_ref<Arg8>::act(arg8)));
03552   }
03553 #endif
03554 
03555 // ----------- thread starters for functions with 9 arguments
03556 
03564   template <typename RT,
03565             typename Arg1, typename Arg2, typename Arg3,
03566             typename Arg4, typename Arg5, typename Arg6,
03567             typename Arg7, typename Arg8, typename Arg9>
03568   inline
03569   Thread<RT>
03570   new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
03571                             Arg6,Arg7,Arg8,Arg9),
03572               typename identity<Arg1>::type arg1,
03573               typename identity<Arg2>::type arg2,
03574               typename identity<Arg3>::type arg3,
03575               typename identity<Arg4>::type arg4,
03576               typename identity<Arg5>::type arg5,
03577               typename identity<Arg6>::type arg6,
03578               typename identity<Arg7>::type arg7,
03579               typename identity<Arg8>::type arg8,
03580               typename identity<Arg9>::type arg9)
03581   {
03582     return
03583       Thread<RT>
03584       (std_cxx1x::bind(fun_ptr,
03585                    internal::maybe_make_ref<Arg1>::act(arg1),
03586                    internal::maybe_make_ref<Arg2>::act(arg2),
03587                    internal::maybe_make_ref<Arg3>::act(arg3),
03588                    internal::maybe_make_ref<Arg4>::act(arg4),
03589                    internal::maybe_make_ref<Arg5>::act(arg5),
03590                    internal::maybe_make_ref<Arg6>::act(arg6),
03591                    internal::maybe_make_ref<Arg7>::act(arg7),
03592                    internal::maybe_make_ref<Arg8>::act(arg8),
03593                    internal::maybe_make_ref<Arg9>::act(arg9)));
03594   }
03595 
03596 
03597 
03605   template <typename RT, typename C,
03606             typename Arg1, typename Arg2, typename Arg3,
03607             typename Arg4, typename Arg5, typename Arg6,
03608             typename Arg7, typename Arg8, typename Arg9>
03609   inline
03610   Thread<RT>
03611   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
03612                                Arg6,Arg7,Arg8,Arg9),
03613               typename identity<C>::type &c,
03614               typename identity<Arg1>::type arg1,
03615               typename identity<Arg2>::type arg2,
03616               typename identity<Arg3>::type arg3,
03617               typename identity<Arg4>::type arg4,
03618               typename identity<Arg5>::type arg5,
03619               typename identity<Arg6>::type arg6,
03620               typename identity<Arg7>::type arg7,
03621               typename identity<Arg8>::type arg8,
03622               typename identity<Arg9>::type arg9)
03623   {
03624     return
03625       Thread<RT>
03626       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
03627                    internal::maybe_make_ref<Arg1>::act(arg1),
03628                    internal::maybe_make_ref<Arg2>::act(arg2),
03629                    internal::maybe_make_ref<Arg3>::act(arg3),
03630                    internal::maybe_make_ref<Arg4>::act(arg4),
03631                    internal::maybe_make_ref<Arg5>::act(arg5),
03632                    internal::maybe_make_ref<Arg6>::act(arg6),
03633                    internal::maybe_make_ref<Arg7>::act(arg7),
03634                    internal::maybe_make_ref<Arg8>::act(arg8),
03635                    internal::maybe_make_ref<Arg9>::act(arg9)));
03636   }
03637 
03638 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
03639 
03646   template <typename RT, typename C,
03647             typename Arg1, typename Arg2, typename Arg3,
03648             typename Arg4, typename Arg5, typename Arg6,
03649             typename Arg7, typename Arg8, typename Arg9>
03650   inline
03651   Thread<RT>
03652   new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
03653                                Arg6,Arg7,Arg8,Arg9) const,
03654               typename identity<const C>::type &c,
03655               typename identity<Arg1>::type arg1,
03656               typename identity<Arg2>::type arg2,
03657               typename identity<Arg3>::type arg3,
03658               typename identity<Arg4>::type arg4,
03659               typename identity<Arg5>::type arg5,
03660               typename identity<Arg6>::type arg6,
03661               typename identity<Arg7>::type arg7,
03662               typename identity<Arg8>::type arg8,
03663               typename identity<Arg9>::type arg9)
03664   {
03665     return
03666       Thread<RT>
03667       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
03668                    internal::maybe_make_ref<Arg1>::act(arg1),
03669                    internal::maybe_make_ref<Arg2>::act(arg2),
03670                    internal::maybe_make_ref<Arg3>::act(arg3),
03671                    internal::maybe_make_ref<Arg4>::act(arg4),
03672                    internal::maybe_make_ref<Arg5>::act(arg5),
03673                    internal::maybe_make_ref<Arg6>::act(arg6),
03674                    internal::maybe_make_ref<Arg7>::act(arg7),
03675                    internal::maybe_make_ref<Arg8>::act(arg8),
03676                    internal::maybe_make_ref<Arg9>::act(arg9)));
03677   }
03678 #endif
03679 
03680 // ------------------------ ThreadGroup -------------------------------------
03681 
03693   template <typename RT = void>
03694   class ThreadGroup
03695   {
03696     public:
03701       ThreadGroup & operator += (const Thread<RT> &t)
03702         {
03703           threads.push_back (t);
03704           return *this;
03705         }
03706 
03719       void join_all () const {
03720         for (typename std::list<Thread<RT> >::const_iterator
03721                t=threads.begin(); t!=threads.end(); ++t)
03722           t->join ();
03723       }
03724 
03725     private:
03729       std::list<Thread<RT> > threads;
03730   };
03731 
03732 
03733   template <typename> class Task;
03734 
03735 
03736   namespace internal
03737   {
03738 #if (DEAL_II_USE_MT == 1)
03739 
03740     template <typename> struct TaskDescriptor;
03741 
03742 
03748     template <typename RT>
03749     struct TaskEntryPoint : public tbb::task
03750     {
03751         TaskEntryPoint (TaskDescriptor<RT> &task_descriptor)
03752                         :
03753                         task_descriptor (task_descriptor)
03754           {}
03755 
03756         virtual tbb::task * execute ()
03757           {
03758                                              // call the function object
03759                                              // and put the return value
03760                                              // into the proper place
03761             call (task_descriptor.function, task_descriptor.ret_val);
03762             return 0;
03763           }
03764 
03769         TaskDescriptor<RT> &task_descriptor;
03770     };
03771 
03812     template <typename RT>
03813     struct TaskDescriptor
03814     {
03815       private:
03820         std_cxx1x::function<RT ()> function;
03821 
03835         tbb::task *task;
03836 
03841         return_value<RT> ret_val;
03842 
03847         bool task_is_done;
03848 
03849       public:
03850 
03855         TaskDescriptor (const std_cxx1x::function<RT ()> &function);
03856 
03868         TaskDescriptor ();
03869 
03878         TaskDescriptor (const TaskDescriptor &);
03879 
03883         ~TaskDescriptor ();
03884 
03898         void queue_task ();
03899 
03909         void join ();
03910 
03911 
03912         template <typename> friend struct TaskEntryPoint;
03913         template <typename> friend struct Task;
03914     };
03915 
03916 
03917 
03918     template <typename RT>
03919     inline
03920     TaskDescriptor<RT>::TaskDescriptor (const std_cxx1x::function<RT ()> &function)
03921                     :
03922                     function (function),
03923                     task_is_done (false)
03924     {}
03925 
03926 
03927     template <typename RT>
03928     inline
03929     void
03930     TaskDescriptor<RT>::queue_task ()
03931     {
03932                                        // use the pattern described in
03933                                        // the TBB book on pages
03934                                        // 230/231 ("Start a large task
03935                                        // in parallel with the main
03936                                        // program)
03937       task = new (tbb::task::allocate_root()) tbb::empty_task;
03938       task->set_ref_count (2);
03939 
03940       tbb::task *worker = new (task->allocate_child()) TaskEntryPoint<RT>(*this);
03941       task->spawn (*worker);
03942     }
03943 
03944 
03945 
03946     template <typename RT>
03947     TaskDescriptor<RT>::TaskDescriptor ()
03948     {
03949       Assert (false, ExcInternalError());
03950     }
03951 
03952 
03953 
03954     template <typename RT>
03955     TaskDescriptor<RT>::TaskDescriptor (const TaskDescriptor &)
03956     {
03957       Assert (false, ExcInternalError());
03958     }
03959 
03960 
03961 
03962     template <typename RT>
03963     inline
03964     TaskDescriptor<RT>::~TaskDescriptor ()
03965     {
03966                                        // wait for the task to
03967                                        // complete for sure
03968       join ();
03969 
03970                                        // now destroy the empty task
03971                                        // structure. the book recommends to
03972                                        // spawn it as well and let the
03973                                        // scheduler destroy the object when
03974                                        // done, but this has the disadvantage
03975                                        // that the scheduler may not get to
03976                                        // actually finishing the task before
03977                                        // it goes out of scope (at the end of
03978                                        // the program, or if a thread is done
03979                                        // on which it was run) and then we
03980                                        // would get a hard-to-decipher warning
03981                                        // about unfinished tasks when the
03982                                        // scheduler "goes out of the
03983                                        // arena". rather, let's explicitly
03984                                        // destroy the empty task
03985                                        // object. before that, make sure that
03986                                        // the task has been shut down,
03987                                        // expressed by a zero reference count
03988       Assert (task != 0, ExcInternalError());
03989       Assert (task->ref_count()==0, ExcInternalError());
03990       task->destroy (*task);
03991     }
03992 
03993 
03994     template <typename RT>
03995     inline
03996     void
03997     TaskDescriptor<RT>::join ()
03998     {
03999                                        // if the task is already done, just
04000                                        // return. this makes sure we call
04001                                        // tbb::Task::wait_for_all() exactly
04002                                        // once, as required by TBB. we could
04003                                        // also get the reference count of task
04004                                        // for doing this, but that is usually
04005                                        // slower. note that this does not work
04006                                        // when the thread calling this
04007                                        // function is not the same as the one
04008                                        // that initialized the task.
04009                                        //
04010                                        // TODO: can we assert that no other
04011                                        // thread tries to end the task?
04012       if (task_is_done == true)
04013         return;
04014 
04015                                        // let TBB wait for the task to
04016                                        // complete.
04017       task_is_done = true;
04018       task->wait_for_all();
04019     }
04020 
04021 
04022 
04023 #else        // no threading enabled
04024 
04031     template <typename RT>
04032     struct TaskDescriptor
04033     {
04038         return_value<RT> ret_val;
04039 
04047         TaskDescriptor (const std_cxx1x::function<RT ()> &function)
04048           {
04049             call (function, ret_val);
04050           }
04057         static void join () {}
04058 
04066         static void queue_task () {}
04067     };
04068 
04069 #endif
04070 
04071   }
04072 
04073 
04074 
04088   template <typename RT = void>
04089   class Task
04090   {
04096     public:
04097       Task (const std_cxx1x::function<RT ()> &function_object)
04098         {
04099                                            // create a task descriptor and tell it
04100                                            // to queue itself up with the scheduling
04101                                            // system
04102           task_descriptor =
04103             std_cxx1x::shared_ptr<internal::TaskDescriptor<RT> >
04104             (new internal::TaskDescriptor<RT>(function_object));
04105           task_descriptor->queue_task ();
04106         }
04107 
04117       Task () {}
04118 
04129       void join () const
04130         {
04131           AssertThrow (task_descriptor !=
04132                        std_cxx1x::shared_ptr<internal::TaskDescriptor<RT> >(),
04133                        ExcNoTask());
04134           task_descriptor->join ();
04135         }
04136 
04145       RT return_value ()
04146         {
04147           join ();
04148           return task_descriptor->ret_val.get();
04149         }
04150 
04151 
04161       bool operator == (const Task &t)
04162         {
04163           AssertThrow (task_descriptor !=
04164                        std_cxx1x::shared_ptr<internal::TaskDescriptor<RT> >(),
04165                        ExcNoTask());
04166           return task_descriptor == t.task_descriptor;
04167         }
04168 
04175       DeclException0 (ExcNoTask);
04177     private:
04186       std_cxx1x::shared_ptr<internal::TaskDescriptor<RT> > task_descriptor;
04187   };
04188 
04189 
04190 
04201   template <typename RT>
04202   inline
04203   Task<RT>
04204   new_task (const std_cxx1x::function<RT ()> &function)
04205   {
04206     return Task<RT>(function);
04207   }
04208 
04216   template <typename RT>
04217   inline
04218   Task<RT>
04219   new_task (RT (*fun_ptr)())
04220   {
04221     return new_task<RT>(std_cxx1x::function<RT ()>(fun_ptr));
04222   }
04223 
04224 
04232   template <typename RT, typename C>
04233   inline
04234   Task<RT>
04235   new_task (RT (C::*fun_ptr)(),
04236             typename identity<C>::type &c)
04237   {
04238     return
04239       new_task<RT>
04240       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c)));
04241   }
04242 
04243 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04244 
04251   template <typename RT, typename C>
04252   inline
04253   Task<RT>
04254   new_task (RT (C::*fun_ptr)() const,
04255             const typename identity<C>::type &c)
04256   {
04257     return
04258       new_task<RT>
04259       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c)));
04260   }
04261 #endif
04262 
04263 
04264 
04265 // ----------- thread starters for unary functions
04266 
04274   template <typename RT, typename Arg1>
04275   inline
04276   Task<RT>
04277   new_task (RT (*fun_ptr)(Arg1),
04278             typename identity<Arg1>::type arg1)
04279   {
04280     return
04281       new_task<RT>
04282       (std_cxx1x::bind(fun_ptr,
04283                        internal::maybe_make_ref<Arg1>::act(arg1)));
04284   }
04285 
04286 
04287 
04295   template <typename RT, typename C, typename Arg1>
04296   inline
04297   Task<RT>
04298   new_task (RT (C::*fun_ptr)(Arg1),
04299             typename identity<C>::type &c,
04300             typename identity<Arg1>::type arg1)
04301   {
04302     return
04303       new_task<RT>
04304       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
04305                        internal::maybe_make_ref<Arg1>::act(arg1)));
04306   }
04307 
04308 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04309 
04316   template <typename RT, typename C, typename Arg1>
04317   inline
04318   Task<RT>
04319   new_task (RT (C::*fun_ptr)(Arg1) const,
04320             typename identity<const C>::type &c,
04321             typename identity<Arg1>::type arg1)
04322   {
04323     return
04324       new_task<RT>
04325       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
04326                        internal::maybe_make_ref<Arg1>::act(arg1)));
04327   }
04328 #endif
04329 
04330 // ----------- thread starters for binary functions
04331 
04339   template <typename RT, typename Arg1, typename Arg2>
04340   inline
04341   Task<RT>
04342   new_task (RT (*fun_ptr)(Arg1,Arg2),
04343             typename identity<Arg1>::type arg1,
04344             typename identity<Arg2>::type arg2)
04345   {
04346     return
04347       new_task<RT>
04348       (std_cxx1x::bind(fun_ptr,
04349                        internal::maybe_make_ref<Arg1>::act(arg1),
04350                        internal::maybe_make_ref<Arg2>::act(arg2)));
04351   }
04352 
04353 
04354 
04362   template <typename RT, typename C, typename Arg1, typename Arg2>
04363   inline
04364   Task<RT>
04365   new_task (RT (C::*fun_ptr)(Arg1,Arg2),
04366             typename identity<C>::type &c,
04367             typename identity<Arg1>::type arg1,
04368             typename identity<Arg2>::type arg2)
04369   {
04370     return
04371       new_task<RT>
04372       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
04373                        internal::maybe_make_ref<Arg1>::act(arg1),
04374                        internal::maybe_make_ref<Arg2>::act(arg2)));
04375   }
04376 
04377 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04378 
04385   template <typename RT, typename C, typename Arg1, typename Arg2>
04386   inline
04387   Task<RT>
04388   new_task (RT (C::*fun_ptr)(Arg1,Arg2) const,
04389             typename identity<const C>::type &c,
04390             typename identity<Arg1>::type arg1,
04391             typename identity<Arg2>::type arg2)
04392   {
04393     return
04394       new_task<RT>
04395       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
04396                        internal::maybe_make_ref<Arg1>::act(arg1),
04397                        internal::maybe_make_ref<Arg2>::act(arg2)));
04398   }
04399 #endif
04400 
04401 // ----------- thread starters for ternary functions
04402 
04410   template <typename RT,
04411             typename Arg1, typename Arg2, typename Arg3>
04412   inline
04413   Task<RT>
04414   new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3),
04415             typename identity<Arg1>::type arg1,
04416             typename identity<Arg2>::type arg2,
04417             typename identity<Arg3>::type arg3)
04418   {
04419     return
04420       new_task<RT>
04421       (std_cxx1x::bind(fun_ptr,
04422                        internal::maybe_make_ref<Arg1>::act(arg1),
04423                        internal::maybe_make_ref<Arg2>::act(arg2),
04424                        internal::maybe_make_ref<Arg3>::act(arg3)));
04425   }
04426 
04427 
04428 
04436   template <typename RT, typename C,
04437             typename Arg1, typename Arg2, typename Arg3>
04438   inline
04439   Task<RT>
04440   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3),
04441             typename identity<C>::type &c,
04442             typename identity<Arg1>::type arg1,
04443             typename identity<Arg2>::type arg2,
04444             typename identity<Arg3>::type arg3)
04445   {
04446     return
04447       new_task<RT>
04448       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
04449                        internal::maybe_make_ref<Arg1>::act(arg1),
04450                        internal::maybe_make_ref<Arg2>::act(arg2),
04451                        internal::maybe_make_ref<Arg3>::act(arg3)));
04452   }
04453 
04454 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04455 
04462   template <typename RT, typename C,
04463             typename Arg1, typename Arg2, typename Arg3>
04464   inline
04465   Task<RT>
04466   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const,
04467             typename identity<const C>::type &c,
04468             typename identity<Arg1>::type arg1,
04469             typename identity<Arg2>::type arg2,
04470             typename identity<Arg3>::type arg3)
04471   {
04472     return
04473       new_task<RT>
04474       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
04475                        internal::maybe_make_ref<Arg1>::act(arg1),
04476                        internal::maybe_make_ref<Arg2>::act(arg2),
04477                        internal::maybe_make_ref<Arg3>::act(arg3)));
04478   }
04479 #endif
04480 
04481 
04482 // ----------- thread starters for functions with 4 arguments
04483 
04491   template <typename RT,
04492             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
04493   inline
04494   Task<RT>
04495   new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
04496             typename identity<Arg1>::type arg1,
04497             typename identity<Arg2>::type arg2,
04498             typename identity<Arg3>::type arg3,
04499             typename identity<Arg4>::type arg4)
04500   {
04501     return
04502       new_task<RT>
04503       (std_cxx1x::bind(fun_ptr,
04504                        internal::maybe_make_ref<Arg1>::act(arg1),
04505                        internal::maybe_make_ref<Arg2>::act(arg2),
04506                        internal::maybe_make_ref<Arg3>::act(arg3),
04507                        internal::maybe_make_ref<Arg4>::act(arg4)));
04508   }
04509 
04510 
04511 
04519   template <typename RT, typename C,
04520             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
04521   inline
04522   Task<RT>
04523   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
04524             typename identity<C>::type &c,
04525             typename identity<Arg1>::type arg1,
04526             typename identity<Arg2>::type arg2,
04527             typename identity<Arg3>::type arg3,
04528             typename identity<Arg4>::type arg4)
04529   {
04530     return
04531       new_task<RT>
04532       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
04533                        internal::maybe_make_ref<Arg1>::act(arg1),
04534                        internal::maybe_make_ref<Arg2>::act(arg2),
04535                        internal::maybe_make_ref<Arg3>::act(arg3),
04536                        internal::maybe_make_ref<Arg4>::act(arg4)));
04537   }
04538 
04539 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04540 
04547   template <typename RT, typename C,
04548             typename Arg1, typename Arg2, typename Arg3, typename Arg4>
04549   inline
04550   Task<RT>
04551   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const,
04552             typename identity<const C>::type &c,
04553             typename identity<Arg1>::type arg1,
04554             typename identity<Arg2>::type arg2,
04555             typename identity<Arg3>::type arg3,
04556             typename identity<Arg4>::type arg4)
04557   {
04558     return
04559       new_task<RT>
04560       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
04561                        internal::maybe_make_ref<Arg1>::act(arg1),
04562                        internal::maybe_make_ref<Arg2>::act(arg2),
04563                        internal::maybe_make_ref<Arg3>::act(arg3),
04564                        internal::maybe_make_ref<Arg4>::act(arg4)));
04565   }
04566 #endif
04567 
04568 // ----------- thread starters for functions with 5 arguments
04569 
04577   template <typename RT,
04578             typename Arg1, typename Arg2, typename Arg3,
04579             typename Arg4, typename Arg5>
04580   inline
04581   Task<RT>
04582   new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
04583             typename identity<Arg1>::type arg1,
04584             typename identity<Arg2>::type arg2,
04585             typename identity<Arg3>::type arg3,
04586             typename identity<Arg4>::type arg4,
04587             typename identity<Arg5>::type arg5)
04588   {
04589     return
04590       new_task<RT>
04591       (std_cxx1x::bind(fun_ptr,
04592                        internal::maybe_make_ref<Arg1>::act(arg1),
04593                        internal::maybe_make_ref<Arg2>::act(arg2),
04594                        internal::maybe_make_ref<Arg3>::act(arg3),
04595                        internal::maybe_make_ref<Arg4>::act(arg4),
04596                        internal::maybe_make_ref<Arg5>::act(arg5)));
04597   }
04598 
04599 
04600 
04608   template <typename RT, typename C,
04609             typename Arg1, typename Arg2, typename Arg3,
04610             typename Arg4, typename Arg5>
04611   inline
04612   Task<RT>
04613   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
04614             typename identity<C>::type &c,
04615             typename identity<Arg1>::type arg1,
04616             typename identity<Arg2>::type arg2,
04617             typename identity<Arg3>::type arg3,
04618             typename identity<Arg4>::type arg4,
04619             typename identity<Arg5>::type arg5)
04620   {
04621     return
04622       new_task<RT>
04623       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
04624                        internal::maybe_make_ref<Arg1>::act(arg1),
04625                        internal::maybe_make_ref<Arg2>::act(arg2),
04626                        internal::maybe_make_ref<Arg3>::act(arg3),
04627                        internal::maybe_make_ref<Arg4>::act(arg4),
04628                        internal::maybe_make_ref<Arg5>::act(arg5)));
04629   }
04630 
04631 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04632 
04639   template <typename RT, typename C,
04640             typename Arg1, typename Arg2, typename Arg3,
04641             typename Arg4, typename Arg5>
04642   inline
04643   Task<RT>
04644   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const,
04645             typename identity<const C>::type &c,
04646             typename identity<Arg1>::type arg1,
04647             typename identity<Arg2>::type arg2,
04648             typename identity<Arg3>::type arg3,
04649             typename identity<Arg4>::type arg4,
04650             typename identity<Arg5>::type arg5)
04651   {
04652     return
04653       new_task<RT>
04654       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
04655                        internal::maybe_make_ref<Arg1>::act(arg1),
04656                        internal::maybe_make_ref<Arg2>::act(arg2),
04657                        internal::maybe_make_ref<Arg3>::act(arg3),
04658                        internal::maybe_make_ref<Arg4>::act(arg4),
04659                        internal::maybe_make_ref<Arg5>::act(arg5)));
04660   }
04661 #endif
04662 
04663 // ----------- thread starters for functions with 6 arguments
04664 
04672   template <typename RT,
04673             typename Arg1, typename Arg2, typename Arg3,
04674             typename Arg4, typename Arg5, typename Arg6>
04675   inline
04676   Task<RT>
04677   new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
04678             typename identity<Arg1>::type arg1,
04679             typename identity<Arg2>::type arg2,
04680             typename identity<Arg3>::type arg3,
04681             typename identity<Arg4>::type arg4,
04682             typename identity<Arg5>::type arg5,
04683             typename identity<Arg6>::type arg6)
04684   {
04685     return
04686       new_task<RT>
04687       (std_cxx1x::bind(fun_ptr,
04688                        internal::maybe_make_ref<Arg1>::act(arg1),
04689                        internal::maybe_make_ref<Arg2>::act(arg2),
04690                        internal::maybe_make_ref<Arg3>::act(arg3),
04691                        internal::maybe_make_ref<Arg4>::act(arg4),
04692                        internal::maybe_make_ref<Arg5>::act(arg5),
04693                        internal::maybe_make_ref<Arg6>::act(arg6)));
04694   }
04695 
04696 
04697 
04705   template <typename RT, typename C,
04706             typename Arg1, typename Arg2, typename Arg3,
04707             typename Arg4, typename Arg5, typename Arg6>
04708   inline
04709   Task<RT>
04710   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
04711             typename identity<C>::type &c,
04712             typename identity<Arg1>::type arg1,
04713             typename identity<Arg2>::type arg2,
04714             typename identity<Arg3>::type arg3,
04715             typename identity<Arg4>::type arg4,
04716             typename identity<Arg5>::type arg5,
04717             typename identity<Arg6>::type arg6)
04718   {
04719     return
04720       new_task<RT>
04721       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
04722                        internal::maybe_make_ref<Arg1>::act(arg1),
04723                        internal::maybe_make_ref<Arg2>::act(arg2),
04724                        internal::maybe_make_ref<Arg3>::act(arg3),
04725                        internal::maybe_make_ref<Arg4>::act(arg4),
04726                        internal::maybe_make_ref<Arg5>::act(arg5),
04727                        internal::maybe_make_ref<Arg6>::act(arg6)));
04728   }
04729 
04730 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04731 
04738   template <typename RT, typename C,
04739             typename Arg1, typename Arg2, typename Arg3,
04740             typename Arg4, typename Arg5, typename Arg6>
04741   inline
04742   Task<RT>
04743   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const,
04744             typename identity<const C>::type &c,
04745             typename identity<Arg1>::type arg1,
04746             typename identity<Arg2>::type arg2,
04747             typename identity<Arg3>::type arg3,
04748             typename identity<Arg4>::type arg4,
04749             typename identity<Arg5>::type arg5,
04750             typename identity<Arg6>::type arg6)
04751   {
04752     return
04753       new_task<RT>
04754       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
04755                        internal::maybe_make_ref<Arg1>::act(arg1),
04756                        internal::maybe_make_ref<Arg2>::act(arg2),
04757                        internal::maybe_make_ref<Arg3>::act(arg3),
04758                        internal::maybe_make_ref<Arg4>::act(arg4),
04759                        internal::maybe_make_ref<Arg5>::act(arg5),
04760                        internal::maybe_make_ref<Arg6>::act(arg6)));
04761   }
04762 #endif
04763 
04764 // ----------- thread starters for functions with 7 arguments
04765 
04773   template <typename RT,
04774             typename Arg1, typename Arg2, typename Arg3,
04775             typename Arg4, typename Arg5, typename Arg6,
04776             typename Arg7>
04777   inline
04778   Task<RT>
04779   new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
04780             typename identity<Arg1>::type arg1,
04781             typename identity<Arg2>::type arg2,
04782             typename identity<Arg3>::type arg3,
04783             typename identity<Arg4>::type arg4,
04784             typename identity<Arg5>::type arg5,
04785             typename identity<Arg6>::type arg6,
04786             typename identity<Arg7>::type arg7)
04787   {
04788     return
04789       new_task<RT>
04790       (std_cxx1x::bind(fun_ptr,
04791                        internal::maybe_make_ref<Arg1>::act(arg1),
04792                        internal::maybe_make_ref<Arg2>::act(arg2),
04793                        internal::maybe_make_ref<Arg3>::act(arg3),
04794                        internal::maybe_make_ref<Arg4>::act(arg4),
04795                        internal::maybe_make_ref<Arg5>::act(arg5),
04796                        internal::maybe_make_ref<Arg6>::act(arg6),
04797                        internal::maybe_make_ref<Arg7>::act(arg7)));
04798   }
04799 
04800 
04801 
04809   template <typename RT, typename C,
04810             typename Arg1, typename Arg2, typename Arg3,
04811             typename Arg4, typename Arg5, typename Arg6,
04812             typename Arg7>
04813   inline
04814   Task<RT>
04815   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
04816             typename identity<C>::type &c,
04817             typename identity<Arg1>::type arg1,
04818             typename identity<Arg2>::type arg2,
04819             typename identity<Arg3>::type arg3,
04820             typename identity<Arg4>::type arg4,
04821             typename identity<Arg5>::type arg5,
04822             typename identity<Arg6>::type arg6,
04823             typename identity<Arg7>::type arg7)
04824   {
04825     return
04826       new_task<RT>
04827       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
04828                        internal::maybe_make_ref<Arg1>::act(arg1),
04829                        internal::maybe_make_ref<Arg2>::act(arg2),
04830                        internal::maybe_make_ref<Arg3>::act(arg3),
04831                        internal::maybe_make_ref<Arg4>::act(arg4),
04832                        internal::maybe_make_ref<Arg5>::act(arg5),
04833                        internal::maybe_make_ref<Arg6>::act(arg6),
04834                        internal::maybe_make_ref<Arg7>::act(arg7)));
04835   }
04836 
04837 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04838 
04845   template <typename RT, typename C,
04846             typename Arg1, typename Arg2, typename Arg3,
04847             typename Arg4, typename Arg5, typename Arg6,
04848             typename Arg7>
04849   inline
04850   Task<RT>
04851   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const,
04852             typename identity<const C>::type &c,
04853             typename identity<Arg1>::type arg1,
04854             typename identity<Arg2>::type arg2,
04855             typename identity<Arg3>::type arg3,
04856             typename identity<Arg4>::type arg4,
04857             typename identity<Arg5>::type arg5,
04858             typename identity<Arg6>::type arg6,
04859             typename identity<Arg7>::type arg7)
04860   {
04861     return
04862       new_task<RT>
04863       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
04864                        internal::maybe_make_ref<Arg1>::act(arg1),
04865                        internal::maybe_make_ref<Arg2>::act(arg2),
04866                        internal::maybe_make_ref<Arg3>::act(arg3),
04867                        internal::maybe_make_ref<Arg4>::act(arg4),
04868                        internal::maybe_make_ref<Arg5>::act(arg5),
04869                        internal::maybe_make_ref<Arg6>::act(arg6),
04870                        internal::maybe_make_ref<Arg7>::act(arg7)));
04871   }
04872 #endif
04873 
04874 // ----------- thread starters for functions with 8 arguments
04875 
04883   template <typename RT,
04884             typename Arg1, typename Arg2, typename Arg3,
04885             typename Arg4, typename Arg5, typename Arg6,
04886             typename Arg7, typename Arg8>
04887   inline
04888   Task<RT>
04889   new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
04890                           Arg6,Arg7,Arg8),
04891             typename identity<Arg1>::type arg1,
04892             typename identity<Arg2>::type arg2,
04893             typename identity<Arg3>::type arg3,
04894             typename identity<Arg4>::type arg4,
04895             typename identity<Arg5>::type arg5,
04896             typename identity<Arg6>::type arg6,
04897             typename identity<Arg7>::type arg7,
04898             typename identity<Arg8>::type arg8)
04899   {
04900     return
04901       new_task<RT>
04902       (std_cxx1x::bind(fun_ptr,
04903                        internal::maybe_make_ref<Arg1>::act(arg1),
04904                        internal::maybe_make_ref<Arg2>::act(arg2),
04905                        internal::maybe_make_ref<Arg3>::act(arg3),
04906                        internal::maybe_make_ref<Arg4>::act(arg4),
04907                        internal::maybe_make_ref<Arg5>::act(arg5),
04908                        internal::maybe_make_ref<Arg6>::act(arg6),
04909                        internal::maybe_make_ref<Arg7>::act(arg7),
04910                        internal::maybe_make_ref<Arg8>::act(arg8)));
04911   }
04912 
04913 
04914 
04922   template <typename RT, typename C,
04923             typename Arg1, typename Arg2, typename Arg3,
04924             typename Arg4, typename Arg5, typename Arg6,
04925             typename Arg7, typename Arg8>
04926   inline
04927   Task<RT>
04928   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
04929                              Arg6,Arg7,Arg8),
04930             typename identity<C>::type &c,
04931             typename identity<Arg1>::type arg1,
04932             typename identity<Arg2>::type arg2,
04933             typename identity<Arg3>::type arg3,
04934             typename identity<Arg4>::type arg4,
04935             typename identity<Arg5>::type arg5,
04936             typename identity<Arg6>::type arg6,
04937             typename identity<Arg7>::type arg7,
04938             typename identity<Arg8>::type arg8)
04939   {
04940     return
04941       new_task<RT>
04942       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
04943                        internal::maybe_make_ref<Arg1>::act(arg1),
04944                        internal::maybe_make_ref<Arg2>::act(arg2),
04945                        internal::maybe_make_ref<Arg3>::act(arg3),
04946                        internal::maybe_make_ref<Arg4>::act(arg4),
04947                        internal::maybe_make_ref<Arg5>::act(arg5),
04948                        internal::maybe_make_ref<Arg6>::act(arg6),
04949                        internal::maybe_make_ref<Arg7>::act(arg7),
04950                        internal::maybe_make_ref<Arg8>::act(arg8)));
04951   }
04952 
04953 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
04954 
04961   template <typename RT, typename C,
04962             typename Arg1, typename Arg2, typename Arg3,
04963             typename Arg4, typename Arg5, typename Arg6,
04964             typename Arg7, typename Arg8>
04965   inline
04966   Task<RT>
04967   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
04968                              Arg6,Arg7,Arg8) const,
04969             typename identity<const C>::type &c,
04970             typename identity<Arg1>::type arg1,
04971             typename identity<Arg2>::type arg2,
04972             typename identity<Arg3>::type arg3,
04973             typename identity<Arg4>::type arg4,
04974             typename identity<Arg5>::type arg5,
04975             typename identity<Arg6>::type arg6,
04976             typename identity<Arg7>::type arg7,
04977             typename identity<Arg8>::type arg8)
04978   {
04979     return
04980       new_task<RT>
04981       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
04982                        internal::maybe_make_ref<Arg1>::act(arg1),
04983                        internal::maybe_make_ref<Arg2>::act(arg2),
04984                        internal::maybe_make_ref<Arg3>::act(arg3),
04985                        internal::maybe_make_ref<Arg4>::act(arg4),
04986                        internal::maybe_make_ref<Arg5>::act(arg5),
04987                        internal::maybe_make_ref<Arg6>::act(arg6),
04988                        internal::maybe_make_ref<Arg7>::act(arg7),
04989                        internal::maybe_make_ref<Arg8>::act(arg8)));
04990   }
04991 #endif
04992 
04993 // ----------- thread starters for functions with 9 arguments
04994 
05002   template <typename RT,
05003             typename Arg1, typename Arg2, typename Arg3,
05004             typename Arg4, typename Arg5, typename Arg6,
05005             typename Arg7, typename Arg8, typename Arg9>
05006   inline
05007   Task<RT>
05008   new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
05009                           Arg6,Arg7,Arg8,Arg9),
05010             typename identity<Arg1>::type arg1,
05011             typename identity<Arg2>::type arg2,
05012             typename identity<Arg3>::type arg3,
05013             typename identity<Arg4>::type arg4,
05014             typename identity<Arg5>::type arg5,
05015             typename identity<Arg6>::type arg6,
05016             typename identity<Arg7>::type arg7,
05017             typename identity<Arg8>::type arg8,
05018             typename identity<Arg9>::type arg9)
05019   {
05020     return
05021       new_task<RT>
05022       (std_cxx1x::bind(fun_ptr,
05023                        internal::maybe_make_ref<Arg1>::act(arg1),
05024                        internal::maybe_make_ref<Arg2>::act(arg2),
05025                        internal::maybe_make_ref<Arg3>::act(arg3),
05026                        internal::maybe_make_ref<Arg4>::act(arg4),
05027                        internal::maybe_make_ref<Arg5>::act(arg5),
05028                        internal::maybe_make_ref<Arg6>::act(arg6),
05029                        internal::maybe_make_ref<Arg7>::act(arg7),
05030                        internal::maybe_make_ref<Arg8>::act(arg8),
05031                        internal::maybe_make_ref<Arg9>::act(arg9)));
05032   }
05033 
05034 
05035 
05043   template <typename RT, typename C,
05044             typename Arg1, typename Arg2, typename Arg3,
05045             typename Arg4, typename Arg5, typename Arg6,
05046             typename Arg7, typename Arg8, typename Arg9>
05047   inline
05048   Task<RT>
05049   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
05050                              Arg6,Arg7,Arg8,Arg9),
05051             typename identity<C>::type &c,
05052             typename identity<Arg1>::type arg1,
05053             typename identity<Arg2>::type arg2,
05054             typename identity<Arg3>::type arg3,
05055             typename identity<Arg4>::type arg4,
05056             typename identity<Arg5>::type arg5,
05057             typename identity<Arg6>::type arg6,
05058             typename identity<Arg7>::type arg7,
05059             typename identity<Arg8>::type arg8,
05060             typename identity<Arg9>::type arg9)
05061   {
05062     return
05063       new_task<RT>
05064       (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
05065                        internal::maybe_make_ref<Arg1>::act(arg1),
05066                        internal::maybe_make_ref<Arg2>::act(arg2),
05067                        internal::maybe_make_ref<Arg3>::act(arg3),
05068                        internal::maybe_make_ref<Arg4>::act(arg4),
05069                        internal::maybe_make_ref<Arg5>::act(arg5),
05070                        internal::maybe_make_ref<Arg6>::act(arg6),
05071                        internal::maybe_make_ref<Arg7>::act(arg7),
05072                        internal::maybe_make_ref<Arg8>::act(arg8),
05073                        internal::maybe_make_ref<Arg9>::act(arg9)));
05074   }
05075 
05076 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
05077 
05084   template <typename RT, typename C,
05085             typename Arg1, typename Arg2, typename Arg3,
05086             typename Arg4, typename Arg5, typename Arg6,
05087             typename Arg7, typename Arg8, typename Arg9>
05088   inline
05089   Task<RT>
05090   new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
05091                              Arg6,Arg7,Arg8,Arg9) const,
05092             typename identity<const C>::type &c,
05093             typename identity<Arg1>::type arg1,
05094             typename identity<Arg2>::type arg2,
05095             typename identity<Arg3>::type arg3,
05096             typename identity<Arg4>::type arg4,
05097             typename identity<Arg5>::type arg5,
05098             typename identity<Arg6>::type arg6,
05099             typename identity<Arg7>::type arg7,
05100             typename identity<Arg8>::type arg8,
05101             typename identity<Arg9>::type arg9)
05102   {
05103     return
05104       new_task<RT>
05105       (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
05106                        internal::maybe_make_ref<Arg1>::act(arg1),
05107                        internal::maybe_make_ref<Arg2>::act(arg2),
05108                        internal::maybe_make_ref<Arg3>::act(arg3),
05109                        internal::maybe_make_ref<Arg4>::act(arg4),
05110                        internal::maybe_make_ref<Arg5>::act(arg5),
05111                        internal::maybe_make_ref<Arg6>::act(arg6),
05112                        internal::maybe_make_ref<Arg7>::act(arg7),
05113                        internal::maybe_make_ref<Arg8>::act(arg8),
05114                        internal::maybe_make_ref<Arg9>::act(arg9)));
05115   }
05116 #endif
05117 
05118 
05119 // ------------------------ TaskGroup -------------------------------------
05120 
05140   template <typename RT = void>
05141   class TaskGroup
05142   {
05143     public:
05148       TaskGroup & operator += (const Task<RT> &t)
05149         {
05150           tasks.push_back (t);
05151           return *this;
05152         }
05153 
05166       void join_all () const {
05167         for (typename std::list<Task<RT> >::const_iterator
05168                t=tasks.begin(); t!=tasks.end(); ++t)
05169           t->join ();
05170       }
05171 
05172     private:
05176       std::list<Task<RT> > tasks;
05177   };
05178 
05179 }   // end of implementation of namespace Threads
05180 
05186 //---------------------------------------------------------------------------
05187 DEAL_II_NAMESPACE_CLOSE
05188 // end of #ifndef __deal2__thread_management_h
05189 #endif
05190 //---------------------------------------------------------------------------
05191 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

deal.II documentation generated on Wed May 23 2012 12:03:22 by doxygen 1.7.3