Reference documentation for deal.II version 8.1.0
thread_management.h
1 // ---------------------------------------------------------------------
2 // @f$Id: thread_management.h 31932 2013-12-08 02:15:54Z heister @f$
3 //
4 // Copyright (C) 2000 - 2013 by the deal.II authors
5 //
6 // This file is part of the deal.II library.
7 //
8 // The deal.II library is free software; you can use it, redistribute
9 // it, and/or modify it under the terms of the GNU Lesser General
10 // Public License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 // The full text of the license can be found in the file LICENSE at
13 // the top level of the deal.II distribution.
14 //
15 // ---------------------------------------------------------------------
16 
17 #ifndef __deal2__thread_management_h
18 #define __deal2__thread_management_h
19 
20 
21 #include <deal.II/base/config.h>
23 #include <deal.II/base/template_constraints.h>
24 #include <deal.II/base/std_cxx1x/tuple.h>
25 #include <deal.II/base/std_cxx1x/function.h>
26 #include <deal.II/base/std_cxx1x/shared_ptr.h>
27 #include <deal.II/base/std_cxx1x/bind.h>
28 
29 #ifdef DEAL_II_WITH_THREADS
30 # include <deal.II/base/std_cxx1x/thread.h>
31 # include <deal.II/base/std_cxx1x/mutex.h>
32 # include <deal.II/base/std_cxx1x/condition_variable.h>
33 #endif
34 
35 #include <iterator>
36 #include <vector>
37 #include <list>
38 #include <utility>
39 
40 
41 #ifdef DEAL_II_WITH_THREADS
42 # ifdef DEAL_II_USE_MT_POSIX
43 # include <pthread.h>
44 # endif
45 # include <tbb/task.h>
46 #endif
47 
48 
49 
51 
54 
55 
64 namespace Threads
65 {
80  {
81  public:
116  {
117  public:
125 
133  };
134 
142  inline void acquire () const {}
143 
151  inline void release () const {}
152  };
153 
154 
155 
175  {
176  public:
186  inline void signal () const {}
187 
197  inline void broadcast () const {}
198 
213  inline void wait (DummyThreadMutex &) const {}
214  };
215 
216 
217 
234  {
235  public:
246  DummyBarrier (const unsigned int count,
247  const char *name = 0,
248  void *arg = 0);
249 
258  int wait () const
259  {
260  return 0;
261  }
262 
267  void dump () const {}
268 
275  DeclException1 (ExcBarrierSizeNotUseful,
276  int,
277  << "In single-thread mode, other barrier sizes than 1 are not "
278  << "useful. You gave " << arg1);
279 
281  };
282 
283 
284 #ifdef DEAL_II_WITH_THREADS
285 
314  class Mutex
315  {
316  public:
351  {
352  public:
357  ScopedLock (Mutex &m) : mutex(m)
358  {
359  mutex.acquire();
360  }
361 
369  {
370  mutex.release ();
371  }
372 
373  private:
379  };
380 
384  Mutex ()
385  {}
386 
394  Mutex (const Mutex &)
395  :
396  mutex()
397  {}
398 
399 
403  inline void acquire ()
404  {
405  mutex.lock();
406  }
407 
411  inline void release ()
412  {
413  mutex.unlock();
414  }
415 
416  private:
421  std_cxx1x::mutex mutex;
422 
428  friend class ConditionVariable;
429  };
430 
431 
442  {
443  public:
450  inline void signal ()
451  {
452  condition_variable.notify_one();
453  }
454 
461  inline void broadcast ()
462  {
463  condition_variable.notify_all();
464  }
465 
481  inline void wait (Mutex &mutex)
482  {
483  std_cxx1x::unique_lock<std_cxx1x::mutex> lock(mutex.mutex,
484  std_cxx1x::adopt_lock);
485  condition_variable.wait (lock);
486  }
487 
488  private:
493  std_cxx1x::condition_variable condition_variable;
494  };
495 
496 
526  {
527  public:
533  PosixThreadBarrier (const unsigned int count,
534  const char *name = 0,
535  void *arg = 0);
536 
541  ~PosixThreadBarrier ();
542 
555  int wait ();
556 
557  private:
563 #ifndef DEAL_II_USE_MT_POSIX_NO_BARRIERS
564  pthread_barrier_t barrier;
565 #else
566  unsigned int count;
567 #endif
568  };
569 
570 
579  typedef Mutex ThreadMutex DEAL_II_DEPRECATED;
580 
589  typedef ConditionVariable ThreadCondition DEAL_II_DEPRECATED;
590 
598 
599 #else
600 
609  typedef DummyThreadMutex Mutex;
610  typedef DummyThreadMutex ThreadMutex;
611 
622  typedef DummyThreadCondition ThreadCondition;
623 
633  typedef DummyBarrier Barrier;
634 #endif
635 
636 }
637 
638 
639 namespace Threads
640 {
641 
699  unsigned int n_existing_threads ();
700 
718  unsigned int this_thread_id ();
719 
743  template <typename ForwardIterator>
744  std::vector<std::pair<ForwardIterator,ForwardIterator> >
745  split_range (const ForwardIterator &begin,
746  const ForwardIterator &end,
747  const unsigned int n_intervals);
748 
760  std::vector<std::pair<unsigned int,unsigned int> >
761  split_interval (const unsigned int begin,
762  const unsigned int end,
763  const unsigned int n_intervals);
764 
779  namespace internal
780  {
811  void handle_std_exception (const std::exception &exc);
812 
821  void handle_unknown_exception ();
822 
833  void register_thread ();
834 
845  void deregister_thread ();
846  }
847 
852 } // end declarations of namespace Threads
853 
854 /* ----------- implementation of functions in namespace Threads ---------- */
855 #ifndef DOXYGEN
856 namespace Threads
857 {
858  template <typename ForwardIterator>
859  std::vector<std::pair<ForwardIterator,ForwardIterator> >
860  split_range (const ForwardIterator &begin,
861  const ForwardIterator &end,
862  const unsigned int n_intervals)
863  {
864  typedef std::pair<ForwardIterator,ForwardIterator> IteratorPair;
865 
866  // in non-multithreaded mode, we
867  // often have the case that this
868  // function is called with
869  // n_intervals==1, so have a
870  // shortcut here to handle that
871  // case efficiently
872 
873  if (n_intervals==1)
874  return (std::vector<IteratorPair>
875  (1, IteratorPair(begin, end)));
876 
877  // if more than one interval
878  // requested, do the full work
879  const unsigned int n_elements = std::distance (begin, end);
880  const unsigned int n_elements_per_interval = n_elements / n_intervals;
881  const unsigned int residual = n_elements % n_intervals;
882 
883  std::vector<IteratorPair> return_values (n_intervals);
884 
885  return_values[0].first = begin;
886  for (unsigned int i=0; i<n_intervals; ++i)
887  {
888  if (i != n_intervals-1)
889  {
890  return_values[i].second = return_values[i].first;
891  // note: the cast is
892  // performed to avoid a
893  // warning of gcc that in
894  // the library `dist>=0'
895  // is checked (dist has a
896  // template type, which
897  // here is unsigned if no
898  // cast is performed)
899  std::advance (return_values[i].second,
900  static_cast<signed int>(n_elements_per_interval));
901  // distribute residual in
902  // division equally among
903  // the first few
904  // subintervals
905  if (i < residual)
906  ++return_values[i].second;
907 
908  return_values[i+1].first = return_values[i].second;
909  }
910  else
911  return_values[i].second = end;
912  }
913  return return_values;
914  }
915 }
916 
917 #endif // DOXYGEN
918 
919 namespace Threads
920 {
921  namespace internal
922  {
933  template <typename RT> struct return_value
934  {
935  private:
936  RT value;
937  public:
938  inline return_value () : value() {}
939 
940  inline RT get () const
941  {
942  return value;
943  }
944  inline void set (RT v)
945  {
946  value = v;
947  }
948  };
949 
950 
964  template <typename RT> struct return_value<RT &>
965  {
966  private:
967  RT *value;
968  public:
969  inline return_value () : value(0) {}
970 
971  inline RT &get () const
972  {
973  return *value;
974  }
975  inline void set (RT &v)
976  {
977  value = &v;
978  }
979  };
980 
981 
994  template <> struct return_value<void>
995  {
996  static inline void get () {}
997  };
998  }
999 
1000 
1001 
1002  namespace internal
1003  {
1004  template <typename RT>
1005  inline void call (const std_cxx1x::function<RT ()> &function,
1006  internal::return_value<RT> &ret_val)
1007  {
1008  ret_val.set (function());
1009  }
1010 
1011 
1012  inline void call (const std_cxx1x::function<void ()> &function,
1014  {
1015  function();
1016  }
1017  }
1018 
1019 
1020 
1021  namespace internal
1022  {
1036  template <typename RT, typename ArgList,
1037  int length = std_cxx1x::tuple_size<ArgList>::value>
1039 
1040 
1048  template <typename RT, typename ArgList>
1049  struct fun_ptr_helper<RT, ArgList, 0>
1050  {
1051  typedef RT (type) ();
1052  };
1053 
1054 
1062  template <typename RT, typename ArgList>
1063  struct fun_ptr_helper<RT, ArgList, 1>
1064  {
1065  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type);
1066  };
1067 
1068 
1076  template <typename RT, typename ArgList>
1077  struct fun_ptr_helper<RT, ArgList, 2>
1078  {
1079  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1080  typename std_cxx1x::tuple_element<1,ArgList>::type);
1081  };
1082 
1083 
1091  template <typename RT, typename ArgList>
1092  struct fun_ptr_helper<RT, ArgList, 3>
1093  {
1094  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1095  typename std_cxx1x::tuple_element<1,ArgList>::type,
1096  typename std_cxx1x::tuple_element<2,ArgList>::type);
1097  };
1098 
1099 
1107  template <typename RT, typename ArgList>
1108  struct fun_ptr_helper<RT, ArgList, 4>
1109  {
1110  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1111  typename std_cxx1x::tuple_element<1,ArgList>::type,
1112  typename std_cxx1x::tuple_element<2,ArgList>::type,
1113  typename std_cxx1x::tuple_element<3,ArgList>::type);
1114  };
1115 
1116 
1124  template <typename RT, typename ArgList>
1125  struct fun_ptr_helper<RT, ArgList, 5>
1126  {
1127  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1128  typename std_cxx1x::tuple_element<1,ArgList>::type,
1129  typename std_cxx1x::tuple_element<2,ArgList>::type,
1130  typename std_cxx1x::tuple_element<3,ArgList>::type,
1131  typename std_cxx1x::tuple_element<4,ArgList>::type);
1132  };
1133 
1134 
1142  template <typename RT, typename ArgList>
1143  struct fun_ptr_helper<RT, ArgList, 6>
1144  {
1145  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1146  typename std_cxx1x::tuple_element<1,ArgList>::type,
1147  typename std_cxx1x::tuple_element<2,ArgList>::type,
1148  typename std_cxx1x::tuple_element<3,ArgList>::type,
1149  typename std_cxx1x::tuple_element<4,ArgList>::type,
1150  typename std_cxx1x::tuple_element<5,ArgList>::type);
1151  };
1152 
1153 
1161  template <typename RT, typename ArgList>
1162  struct fun_ptr_helper<RT, ArgList, 7>
1163  {
1164  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1165  typename std_cxx1x::tuple_element<1,ArgList>::type,
1166  typename std_cxx1x::tuple_element<2,ArgList>::type,
1167  typename std_cxx1x::tuple_element<3,ArgList>::type,
1168  typename std_cxx1x::tuple_element<4,ArgList>::type,
1169  typename std_cxx1x::tuple_element<5,ArgList>::type,
1170  typename std_cxx1x::tuple_element<6,ArgList>::type);
1171  };
1172 
1173 
1181  template <typename RT, typename ArgList>
1182  struct fun_ptr_helper<RT, ArgList, 8>
1183  {
1184  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1185  typename std_cxx1x::tuple_element<1,ArgList>::type,
1186  typename std_cxx1x::tuple_element<2,ArgList>::type,
1187  typename std_cxx1x::tuple_element<3,ArgList>::type,
1188  typename std_cxx1x::tuple_element<4,ArgList>::type,
1189  typename std_cxx1x::tuple_element<5,ArgList>::type,
1190  typename std_cxx1x::tuple_element<6,ArgList>::type,
1191  typename std_cxx1x::tuple_element<7,ArgList>::type);
1192  };
1193 
1194 
1202  template <typename RT, typename ArgList>
1203  struct fun_ptr_helper<RT, ArgList, 9>
1204  {
1205  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1206  typename std_cxx1x::tuple_element<1,ArgList>::type,
1207  typename std_cxx1x::tuple_element<2,ArgList>::type,
1208  typename std_cxx1x::tuple_element<3,ArgList>::type,
1209  typename std_cxx1x::tuple_element<4,ArgList>::type,
1210  typename std_cxx1x::tuple_element<5,ArgList>::type,
1211  typename std_cxx1x::tuple_element<6,ArgList>::type,
1212  typename std_cxx1x::tuple_element<7,ArgList>::type,
1213  typename std_cxx1x::tuple_element<8,ArgList>::type);
1214  };
1215 
1216 
1217 
1225  template <typename RT, typename ArgList>
1226  struct fun_ptr_helper<RT, ArgList, 10>
1227  {
1228  typedef RT (type) (typename std_cxx1x::tuple_element<0,ArgList>::type,
1229  typename std_cxx1x::tuple_element<1,ArgList>::type,
1230  typename std_cxx1x::tuple_element<2,ArgList>::type,
1231  typename std_cxx1x::tuple_element<3,ArgList>::type,
1232  typename std_cxx1x::tuple_element<4,ArgList>::type,
1233  typename std_cxx1x::tuple_element<5,ArgList>::type,
1234  typename std_cxx1x::tuple_element<6,ArgList>::type,
1235  typename std_cxx1x::tuple_element<7,ArgList>::type,
1236  typename std_cxx1x::tuple_element<8,ArgList>::type,
1237  typename std_cxx1x::tuple_element<9,ArgList>::type);
1238  };
1239 
1240 
1241 
1259  template <typename RT, typename ArgList>
1260  struct fun_ptr
1261  {
1262  typedef typename fun_ptr_helper<RT,ArgList>::type type;
1263  };
1264  }
1265 
1266 
1267 
1268  namespace internal
1269  {
1270 #ifdef DEAL_II_WITH_THREADS
1271 
1287  template <typename RT>
1289  {
1294  std_cxx1x::thread thread;
1295 
1307  std_cxx1x::shared_ptr<return_value<RT> > ret_val;
1308 
1364 
1369 
1374  :
1375  thread_is_active (false)
1376  {}
1377 
1378  ~ThreadDescriptor ()
1379  {
1380  if (!thread_is_active)
1381  return;
1382  thread.detach();
1383  thread_is_active = false;
1384  }
1385 
1391  void start (const std_cxx1x::function<RT ()> &function)
1392  {
1393  thread_is_active = true;
1394  ret_val.reset(new return_value<RT>());
1395  thread = std_cxx1x::thread (thread_entry_point, function, ret_val);
1396  }
1397 
1398 
1402  void join ()
1403  {
1404  // see if the thread hasn't been
1405  // joined yet. if it has, then
1406  // join() is a no-op. use schmidt's double-checking
1407  // strategy to use the mutex only when necessary
1408  if (thread_is_active == false)
1409  return;
1410 
1411  Mutex::ScopedLock lock (thread_is_active_mutex);
1412  if (thread_is_active == true)
1413  {
1414  Assert (thread.joinable(), ExcInternalError());
1415  thread.join ();
1416  thread_is_active = false;
1417  }
1418  }
1419 
1420  private:
1421 
1426  static
1427  void thread_entry_point (const std_cxx1x::function<RT ()> function,
1428  std_cxx1x::shared_ptr<return_value<RT> > ret_val)
1429  {
1430  // call the function
1431  // in question. since an
1432  // exception that is
1433  // thrown from one of the
1434  // called functions will
1435  // not propagate to the
1436  // main thread, it will
1437  // kill the program if
1438  // not treated here
1439  // before we return to
1440  // the operating system's
1441  // thread library
1442  internal::register_thread ();
1443  try
1444  {
1445  call (function, *ret_val);
1446  }
1447  catch (const std::exception &exc)
1448  {
1449  internal::handle_std_exception (exc);
1450  }
1451  catch (...)
1452  {
1453  internal::handle_unknown_exception ();
1454  }
1455  internal::deregister_thread ();
1456  }
1457  };
1458 
1459 #else
1460 
1472  template <typename RT>
1473  struct ThreadDescriptor
1474  {
1480  std_cxx1x::shared_ptr<return_value<RT> > ret_val;
1481 
1487  void start (const std_cxx1x::function<RT ()> &function)
1488  {
1489  ret_val.reset(new return_value<RT>());
1490  call (function, *ret_val);
1491  }
1492 
1496  void join ()
1497  {}
1498  };
1499 
1500 #endif
1501  }
1502 
1503 
1541  template <typename RT = void>
1542  class Thread
1543  {
1544  public:
1549  Thread (const std_cxx1x::function<RT ()> &function)
1550  :
1551  thread_descriptor (new internal::ThreadDescriptor<RT>())
1552  {
1553  // in a second step, start
1554  // the thread.
1555  thread_descriptor->start (function);
1556  }
1557 
1567  Thread () {}
1568 
1572  Thread (const Thread<RT> &t)
1573  :
1574  thread_descriptor (t.thread_descriptor)
1575  {}
1576 
1585  void join () const
1586  {
1587  if (thread_descriptor)
1588  thread_descriptor->join ();
1589  }
1590 
1600  {
1601  join ();
1602  return thread_descriptor->ret_val->get();
1603  }
1604 
1612  bool valid () const
1613  {
1614  return static_cast<bool>(thread_descriptor);
1615  }
1616 
1617 
1627  bool operator == (const Thread &t)
1628  {
1629  return thread_descriptor == t.thread_descriptor;
1630  }
1631 
1632  private:
1644  std_cxx1x::shared_ptr<internal::ThreadDescriptor<RT> > thread_descriptor;
1645  };
1646 
1647 
1648  namespace internal
1649  {
1659  template <typename T>
1661  {
1662  static T act (T &t)
1663  {
1664  return t;
1665  }
1666  };
1667 
1668 
1669 
1679  template <typename T>
1680  struct maybe_make_ref<T &>
1681  {
1682  static std_cxx1x::reference_wrapper<T> act (T &t)
1683  {
1684  return std_cxx1x::ref(t);
1685  }
1686  };
1687  }
1688 
1689 
1690 
1691  namespace internal
1692  {
1717  template <typename RT, typename ArgList, int length>
1719 
1720 
1721 // ----------- encapsulators for function objects
1722 
1728  template <typename RT, typename ArgList>
1729  class fun_encapsulator<RT, ArgList, 0>
1730  {
1731  public:
1732  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1733  : function (*function)
1734  {}
1735 
1736  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1737  : function (function)
1738  {}
1739 
1740  inline
1741  Thread<RT>
1742  operator() ()
1743  {
1744  return Thread<RT> (function);
1745  }
1746 
1747  private:
1748  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1749  };
1750 
1756  template <typename RT, typename ArgList>
1757  class fun_encapsulator<RT, ArgList, 1>
1758  {
1759  public:
1760  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1761  : function (*function)
1762  {}
1763 
1764  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1765  : function (function)
1766  {}
1767 
1768  inline
1769  Thread<RT>
1770  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1)
1771  {
1772  return
1773  Thread<RT>
1774  (std_cxx1x::bind (function,
1775  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1)));
1776  }
1777 
1778  private:
1779  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1780  };
1781 
1787  template <typename RT, typename ArgList>
1788  class fun_encapsulator<RT, ArgList, 2>
1789  {
1790  public:
1791  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1792  : function (*function)
1793  {}
1794 
1795  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1796  : function (function)
1797  {}
1798 
1799  inline
1800  Thread<RT>
1801  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
1802  typename std_cxx1x::tuple_element<1,ArgList>::type arg2)
1803  {
1804  return
1805  Thread<RT>
1806  (std_cxx1x::bind (function,
1807  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
1808  internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2)));
1809  }
1810 
1811  private:
1812  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1813  };
1814 
1820  template <typename RT, typename ArgList>
1821  class fun_encapsulator<RT, ArgList, 3>
1822  {
1823  public:
1824  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1825  : function (*function)
1826  {}
1827 
1828  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1829  : function (function)
1830  {}
1831 
1832  inline
1833  Thread<RT>
1834  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
1835  typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
1836  typename std_cxx1x::tuple_element<2,ArgList>::type arg3)
1837  {
1838  return
1839  Thread<RT>
1840  (std_cxx1x::bind (function,
1841  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
1842  internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
1843  internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3)));
1844  }
1845 
1846  private:
1847  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1848  };
1849 
1855  template <typename RT, typename ArgList>
1856  class fun_encapsulator<RT, ArgList, 4>
1857  {
1858  public:
1859  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1860  : function (*function)
1861  {}
1862 
1863  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1864  : function (function)
1865  {}
1866 
1867  inline
1868  Thread<RT>
1869  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
1870  typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
1871  typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
1872  typename std_cxx1x::tuple_element<3,ArgList>::type arg4)
1873  {
1874  return
1875  Thread<RT>
1876  (std_cxx1x::bind (function,
1877  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
1878  internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
1879  internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
1880  internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4)));
1881  }
1882 
1883  private:
1884  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1885  };
1886 
1892  template <typename RT, typename ArgList>
1893  class fun_encapsulator<RT, ArgList, 5>
1894  {
1895  public:
1896  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1897  : function (*function)
1898  {}
1899 
1900  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1901  : function (function)
1902  {}
1903 
1904  inline
1905  Thread<RT>
1906  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
1907  typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
1908  typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
1909  typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
1910  typename std_cxx1x::tuple_element<4,ArgList>::type arg5)
1911  {
1912  return
1913  Thread<RT>
1914  (std_cxx1x::bind (function,
1915  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
1916  internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
1917  internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
1918  internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
1919  internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5)));
1920  }
1921 
1922  private:
1923  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1924  };
1925 
1931  template <typename RT, typename ArgList>
1932  class fun_encapsulator<RT, ArgList, 6>
1933  {
1934  public:
1935  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1936  : function (*function)
1937  {}
1938 
1939  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1940  : function (function)
1941  {}
1942 
1943  inline
1944  Thread<RT>
1945  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
1946  typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
1947  typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
1948  typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
1949  typename std_cxx1x::tuple_element<4,ArgList>::type arg5,
1950  typename std_cxx1x::tuple_element<5,ArgList>::type arg6)
1951  {
1952  return
1953  Thread<RT>
1954  (std_cxx1x::bind (function,
1955  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
1956  internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
1957  internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
1958  internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
1959  internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5),
1960  internal::maybe_make_ref<typename std_cxx1x::tuple_element<5,ArgList>::type>::act(arg6)));
1961  }
1962 
1963  private:
1964  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1965  };
1966 
1972  template <typename RT, typename ArgList>
1973  class fun_encapsulator<RT, ArgList, 7>
1974  {
1975  public:
1976  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1977  : function (*function)
1978  {}
1979 
1980  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1981  : function (function)
1982  {}
1983 
1984  inline
1985  Thread<RT>
1986  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
1987  typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
1988  typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
1989  typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
1990  typename std_cxx1x::tuple_element<4,ArgList>::type arg5,
1991  typename std_cxx1x::tuple_element<5,ArgList>::type arg6,
1992  typename std_cxx1x::tuple_element<6,ArgList>::type arg7)
1993  {
1994  return
1995  Thread<RT>
1996  (std_cxx1x::bind (function,
1997  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
1998  internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
1999  internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
2000  internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
2001  internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5),
2002  internal::maybe_make_ref<typename std_cxx1x::tuple_element<5,ArgList>::type>::act(arg6),
2003  internal::maybe_make_ref<typename std_cxx1x::tuple_element<6,ArgList>::type>::act(arg7)));
2004  }
2005 
2006  private:
2007  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
2008  };
2009 
2015  template <typename RT, typename ArgList>
2016  class fun_encapsulator<RT, ArgList, 8>
2017  {
2018  public:
2019  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
2020  : function (*function)
2021  {}
2022 
2023  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
2024  : function (function)
2025  {}
2026 
2027  inline
2028  Thread<RT>
2029  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
2030  typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
2031  typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
2032  typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
2033  typename std_cxx1x::tuple_element<4,ArgList>::type arg5,
2034  typename std_cxx1x::tuple_element<5,ArgList>::type arg6,
2035  typename std_cxx1x::tuple_element<6,ArgList>::type arg7,
2036  typename std_cxx1x::tuple_element<7,ArgList>::type arg8)
2037  {
2038  return
2039  Thread<RT>
2040  (std_cxx1x::bind (function,
2041  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
2042  internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
2043  internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
2044  internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
2045  internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5),
2046  internal::maybe_make_ref<typename std_cxx1x::tuple_element<5,ArgList>::type>::act(arg6),
2047  internal::maybe_make_ref<typename std_cxx1x::tuple_element<6,ArgList>::type>::act(arg7),
2048  internal::maybe_make_ref<typename std_cxx1x::tuple_element<7,ArgList>::type>::act(arg8)));
2049  }
2050 
2051  private:
2052  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
2053  };
2054 
2060  template <typename RT, typename ArgList>
2061  class fun_encapsulator<RT, ArgList, 9>
2062  {
2063  public:
2064  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
2065  : function (*function)
2066  {}
2067 
2068  fun_encapsulator (const std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
2069  : function (function)
2070  {}
2071 
2072  inline
2073  Thread<RT>
2074  operator() (typename std_cxx1x::tuple_element<0,ArgList>::type arg1,
2075  typename std_cxx1x::tuple_element<1,ArgList>::type arg2,
2076  typename std_cxx1x::tuple_element<2,ArgList>::type arg3,
2077  typename std_cxx1x::tuple_element<3,ArgList>::type arg4,
2078  typename std_cxx1x::tuple_element<4,ArgList>::type arg5,
2079  typename std_cxx1x::tuple_element<5,ArgList>::type arg6,
2080  typename std_cxx1x::tuple_element<6,ArgList>::type arg7,
2081  typename std_cxx1x::tuple_element<7,ArgList>::type arg8,
2082  typename std_cxx1x::tuple_element<8,ArgList>::type arg9)
2083  {
2084  return
2085  Thread<RT>
2086  (std_cxx1x::bind (function,
2087  internal::maybe_make_ref<typename std_cxx1x::tuple_element<0,ArgList>::type>::act(arg1),
2088  internal::maybe_make_ref<typename std_cxx1x::tuple_element<1,ArgList>::type>::act(arg2),
2089  internal::maybe_make_ref<typename std_cxx1x::tuple_element<2,ArgList>::type>::act(arg3),
2090  internal::maybe_make_ref<typename std_cxx1x::tuple_element<3,ArgList>::type>::act(arg4),
2091  internal::maybe_make_ref<typename std_cxx1x::tuple_element<4,ArgList>::type>::act(arg5),
2092  internal::maybe_make_ref<typename std_cxx1x::tuple_element<5,ArgList>::type>::act(arg6),
2093  internal::maybe_make_ref<typename std_cxx1x::tuple_element<6,ArgList>::type>::act(arg7),
2094  internal::maybe_make_ref<typename std_cxx1x::tuple_element<7,ArgList>::type>::act(arg8),
2095  internal::maybe_make_ref<typename std_cxx1x::tuple_element<8,ArgList>::type>::act(arg9)));
2096  }
2097 
2098  private:
2099  std_cxx1x::function<typename internal::fun_ptr<RT,ArgList>::type> function;
2100  };
2101  }
2102 
2103 
2104 
2105 
2106 // ----------- encapsulators for functions not taking any parameters
2107 
2115  template <typename RT>
2116  inline
2118  spawn (RT (*fun_ptr)()) DEAL_II_DEPRECATED;
2119 
2120 
2121  template <typename RT>
2122  inline
2124  spawn (RT (*fun_ptr)())
2125  {
2126  return fun_ptr;
2127  }
2128 
2129 
2137  template <typename RT, typename C>
2138  inline
2140  spawn (C &c, RT (C::*fun_ptr)()) DEAL_II_DEPRECATED;
2141 
2142 
2143  template <typename RT, typename C>
2144  inline
2146  spawn (C &c, RT (C::*fun_ptr)())
2147  {
2148  return
2149  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<> >::type>
2150  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c)));
2151  }
2152 
2160  template <typename RT, typename C>
2161  inline
2163  spawn (const C &c, RT (C::*fun_ptr)() const) DEAL_II_DEPRECATED;
2164 
2165 
2166  template <typename RT, typename C>
2167  inline
2168  internal::fun_encapsulator<RT,std_cxx1x::tuple<>,0>
2169  spawn (const C &c, RT (C::*fun_ptr)() const)
2170  {
2171  return
2172  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<> >::type>
2173  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c)));
2174  }
2175 
2176 
2177 
2178 
2179 // ----------- encapsulators for unary functions
2180 
2188  template <typename RT, typename Arg1>
2189  inline
2191  spawn (RT (*fun_ptr)(Arg1)) DEAL_II_DEPRECATED;
2192 
2193 
2194  template <typename RT, typename Arg1>
2195  inline
2196  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1>,1>
2197  spawn (RT (*fun_ptr)(Arg1))
2198  {
2199  return fun_ptr;
2200  }
2201 
2202 
2203 
2211  template <typename RT, typename C, typename Arg1>
2212  inline
2213  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1>,1>
2214  spawn (C &c, RT (C::*fun_ptr)(Arg1)) DEAL_II_DEPRECATED;
2215 
2216 
2217  template <typename RT, typename C, typename Arg1>
2218  inline
2219  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1>,1>
2220  spawn (C &c, RT (C::*fun_ptr)(Arg1))
2221  {
2222  return
2223  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1> >::type>
2224  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1));
2225  }
2226 
2234  template <typename RT, typename C, typename Arg1>
2235  inline
2236  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1>,1>
2237  spawn (const C &c, RT (C::*fun_ptr)(Arg1) const) DEAL_II_DEPRECATED;
2238 
2239 
2240  template <typename RT, typename C, typename Arg1>
2241  inline
2242  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1>,1>
2243  spawn (const C &c, RT (C::*fun_ptr)(Arg1) const)
2244  {
2245  return
2246  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1> >::type>
2247  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1));
2248  }
2249 
2250 
2251 // ----------- encapsulators for binary functions
2252 
2260  template <typename RT, typename Arg1, typename Arg2>
2261  inline
2263  spawn (RT (*fun_ptr)(Arg1,Arg2)) DEAL_II_DEPRECATED;
2264 
2265 
2266  template <typename RT, typename Arg1, typename Arg2>
2267  inline
2268  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2>,2>
2269  spawn (RT (*fun_ptr)(Arg1,Arg2))
2270  {
2271  return fun_ptr;
2272  }
2273 
2274 
2275 
2283  template <typename RT, typename C, typename Arg1, typename Arg2>
2284  inline
2285  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2>,2>
2286  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2)) DEAL_II_DEPRECATED;
2287 
2288 
2289  template <typename RT, typename C, typename Arg1, typename Arg2>
2290  inline
2291  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2>,2>
2292  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2))
2293  {
2294  return
2295  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1,Arg2> >::type>
2296  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2));
2297  }
2298 
2306  template <typename RT, typename C, typename Arg1, typename Arg2>
2307  inline
2308  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2>,2>
2309  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2) const) DEAL_II_DEPRECATED;
2310 
2311 
2312  template <typename RT, typename C, typename Arg1, typename Arg2>
2313  inline
2314  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2>,2>
2315  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2) const)
2316  {
2317  return
2318  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1,Arg2> >::type>
2319  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2));
2320  }
2321 
2322 
2323 // ----------- encapsulators for ternary functions
2324 
2332  template <typename RT,
2333  typename Arg1, typename Arg2, typename Arg3>
2334  inline
2336  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3)) DEAL_II_DEPRECATED;
2337 
2338 
2339  template <typename RT,
2340  typename Arg1, typename Arg2, typename Arg3>
2341  inline
2342  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3>,3>
2343  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3))
2344  {
2345  return fun_ptr;
2346  }
2347 
2348 
2349 
2357  template <typename RT, typename C,
2358  typename Arg1, typename Arg2, typename Arg3>
2359  inline
2360  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3>,3>
2361  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3)) DEAL_II_DEPRECATED;
2362 
2363 
2364  template <typename RT, typename C,
2365  typename Arg1, typename Arg2, typename Arg3>
2366  inline
2367  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3>,3>
2368  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3))
2369  {
2370  return
2371  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1,Arg2,Arg3> >::type>
2372  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3));
2373  }
2374 
2382  template <typename RT, typename C,
2383  typename Arg1, typename Arg2, typename Arg3>
2384  inline
2385  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3>,3>
2386  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const) DEAL_II_DEPRECATED;
2387 
2388 
2389  template <typename RT, typename C,
2390  typename Arg1, typename Arg2, typename Arg3>
2391  inline
2392  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3>,3>
2393  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const)
2394  {
2395  return
2396  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1,Arg2,Arg3> >::type>
2397  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3));
2398  }
2399 
2400 
2401 
2402 // ----------- encapsulators for functions with 4 arguments
2403 
2411  template <typename RT,
2412  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2413  inline
2415  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4)) DEAL_II_DEPRECATED;
2416 
2417 
2418  template <typename RT,
2419  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2420  inline
2421  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4>,4>
2422  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4))
2423  {
2424  return fun_ptr;
2425  }
2426 
2427 
2428 
2436  template <typename RT, typename C,
2437  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2438  inline
2439  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4>,4>
2440  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4)) DEAL_II_DEPRECATED;
2441 
2442 
2443  template <typename RT, typename C,
2444  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2445  inline
2446  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4>,4>
2447  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4))
2448  {
2449  return
2450  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4> >::type>
2451  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4));
2452  }
2453 
2461  template <typename RT, typename C,
2462  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2463  inline
2464  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4>,4>
2465  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const) DEAL_II_DEPRECATED;
2466 
2467 
2468  template <typename RT, typename C,
2469  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2470  inline
2471  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4>,4>
2472  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const)
2473  {
2474  return
2475  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4> >::type>
2476  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4));
2477  }
2478 
2479 
2480 // ----------- encapsulators for functions with 5 arguments
2481 
2489  template <typename RT,
2490  typename Arg1, typename Arg2, typename Arg3,
2491  typename Arg4, typename Arg5>
2492  inline
2494  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5)) DEAL_II_DEPRECATED;
2495 
2496 
2497  template <typename RT,
2498  typename Arg1, typename Arg2, typename Arg3,
2499  typename Arg4, typename Arg5>
2500  inline
2501  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>,5>
2502  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5))
2503  {
2504  return fun_ptr;
2505  }
2506 
2507 
2508 
2516  template <typename RT, typename C,
2517  typename Arg1, typename Arg2, typename Arg3,
2518  typename Arg4, typename Arg5>
2519  inline
2520  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>,5>
2521  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5)) DEAL_II_DEPRECATED;
2522 
2523 
2524  template <typename RT, typename C,
2525  typename Arg1, typename Arg2, typename Arg3,
2526  typename Arg4, typename Arg5>
2527  inline
2528  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>,5>
2529  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5))
2530  {
2531  return
2532  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >::type>
2533  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5));
2534  }
2535 
2543  template <typename RT, typename C,
2544  typename Arg1, typename Arg2, typename Arg3,
2545  typename Arg4, typename Arg5>
2546  inline
2547  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>,5>
2548  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const) DEAL_II_DEPRECATED;
2549 
2550 
2551  template <typename RT, typename C,
2552  typename Arg1, typename Arg2, typename Arg3,
2553  typename Arg4, typename Arg5>
2554  inline
2555  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5>,5>
2556  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const)
2557  {
2558  return
2559  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >::type>
2560  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c), std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3, std_cxx1x::_4, std_cxx1x::_5));
2561  }
2562 
2563 
2564 // ----------- encapsulators for functions with 6 arguments
2565 
2573  template <typename RT,
2574  typename Arg1, typename Arg2, typename Arg3,
2575  typename Arg4, typename Arg5, typename Arg6>
2576  inline
2578  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6)) DEAL_II_DEPRECATED;
2579 
2580 
2581  template <typename RT,
2582  typename Arg1, typename Arg2, typename Arg3,
2583  typename Arg4, typename Arg5, typename Arg6>
2584  inline
2585  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>,6>
2586  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6))
2587  {
2588  return fun_ptr;
2589  }
2590 
2591 
2592 
2600  template <typename RT, typename C,
2601  typename Arg1, typename Arg2, typename Arg3,
2602  typename Arg4, typename Arg5, typename Arg6>
2603  inline
2604  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>,6>
2605  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6)) DEAL_II_DEPRECATED;
2606 
2607 
2608  template <typename RT, typename C,
2609  typename Arg1, typename Arg2, typename Arg3,
2610  typename Arg4, typename Arg5, typename Arg6>
2611  inline
2612  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>,6>
2613  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6))
2614  {
2615  return
2616  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >::type>
2617  (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));
2618  }
2619 
2627  template <typename RT, typename C,
2628  typename Arg1, typename Arg2, typename Arg3,
2629  typename Arg4, typename Arg5, typename Arg6>
2630  inline
2632  std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>,6>
2633  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const) DEAL_II_DEPRECATED;
2634 
2635 
2636  template <typename RT, typename C,
2637  typename Arg1, typename Arg2, typename Arg3,
2638  typename Arg4, typename Arg5, typename Arg6>
2639  inline
2641  std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>,6>
2642  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const)
2643  {
2644  return
2645  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >::type>
2646  (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));
2647  }
2648 
2649 
2650 // ----------- encapsulators for functions with 7 arguments
2651 
2659  template <typename RT,
2660  typename Arg1, typename Arg2, typename Arg3,
2661  typename Arg4, typename Arg5, typename Arg6,
2662  typename Arg7>
2663  inline
2664  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2665  Arg4, Arg5, Arg6, Arg7>,7>
2666  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7)) DEAL_II_DEPRECATED;
2667 
2668 
2669  template <typename RT,
2670  typename Arg1, typename Arg2, typename Arg3,
2671  typename Arg4, typename Arg5, typename Arg6,
2672  typename Arg7>
2673  inline
2674  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2675  Arg4, Arg5, Arg6, Arg7>,7>
2676  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7))
2677  {
2678  return fun_ptr;
2679  }
2680 
2681 
2682 
2690  template <typename RT, typename C,
2691  typename Arg1, typename Arg2, typename Arg3,
2692  typename Arg4, typename Arg5, typename Arg6,
2693  typename Arg7>
2694  inline
2695  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2696  Arg4, Arg5, Arg6, Arg7>,7>
2697  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7)) DEAL_II_DEPRECATED;
2698 
2699 
2700  template <typename RT, typename C,
2701  typename Arg1, typename Arg2, typename Arg3,
2702  typename Arg4, typename Arg5, typename Arg6,
2703  typename Arg7>
2704  inline
2705  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2706  Arg4, Arg5, Arg6, Arg7>,7>
2707  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7))
2708  {
2709  return
2710  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7> >::type>
2711  (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));
2712  }
2713 
2721  template <typename RT, typename C,
2722  typename Arg1, typename Arg2, typename Arg3,
2723  typename Arg4, typename Arg5, typename Arg6,
2724  typename Arg7>
2725  inline
2727  std_cxx1x::tuple<Arg1, Arg2, Arg3,
2728  Arg4, Arg5, Arg6, Arg7>,7>
2729  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const) DEAL_II_DEPRECATED;
2730 
2731 
2732  template <typename RT, typename C,
2733  typename Arg1, typename Arg2, typename Arg3,
2734  typename Arg4, typename Arg5, typename Arg6,
2735  typename Arg7>
2736  inline
2738  std_cxx1x::tuple<Arg1, Arg2, Arg3,
2739  Arg4, Arg5, Arg6, Arg7>,7>
2740  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const)
2741  {
2742  return
2743  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7> >::type>
2744  (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));
2745  }
2746 
2747 
2748 // ----------- encapsulators for functions with 8 arguments
2749 
2757  template <typename RT,
2758  typename Arg1, typename Arg2, typename Arg3,
2759  typename Arg4, typename Arg5, typename Arg6,
2760  typename Arg7, typename Arg8>
2761  inline
2762  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2763  Arg4, Arg5, Arg6,
2764  Arg7, Arg8>,8>
2765  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2766  Arg6,Arg7,Arg8)) DEAL_II_DEPRECATED;
2767 
2768 
2769  template <typename RT,
2770  typename Arg1, typename Arg2, typename Arg3,
2771  typename Arg4, typename Arg5, typename Arg6,
2772  typename Arg7, typename Arg8>
2773  inline
2774  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2775  Arg4, Arg5, Arg6,
2776  Arg7, Arg8>,8>
2777  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2778  Arg6,Arg7,Arg8))
2779  {
2780  return fun_ptr;
2781  }
2782 
2783 
2784 
2792  template <typename RT, typename C,
2793  typename Arg1, typename Arg2, typename Arg3,
2794  typename Arg4, typename Arg5, typename Arg6,
2795  typename Arg7, typename Arg8>
2796  inline
2797  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2798  Arg4, Arg5, Arg6,
2799  Arg7, Arg8>,8>
2800  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2801  Arg6,Arg7,Arg8)) DEAL_II_DEPRECATED;
2802 
2803 
2804  template <typename RT, typename C,
2805  typename Arg1, typename Arg2, typename Arg3,
2806  typename Arg4, typename Arg5, typename Arg6,
2807  typename Arg7, typename Arg8>
2808  inline
2809  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2810  Arg4, Arg5, Arg6,
2811  Arg7, Arg8>,8>
2812  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2813  Arg6,Arg7,Arg8))
2814  {
2815  return
2816  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> >::type>
2817  (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));
2818  }
2819 
2827  template <typename RT, typename C,
2828  typename Arg1, typename Arg2, typename Arg3,
2829  typename Arg4, typename Arg5, typename Arg6,
2830  typename Arg7, typename Arg8>
2831  inline
2833  std_cxx1x::tuple<Arg1, Arg2, Arg3,
2834  Arg4, Arg5, Arg6,
2835  Arg7, Arg8>,8>
2836  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2837  Arg6,Arg7,Arg8) const) DEAL_II_DEPRECATED;
2838 
2839 
2840  template <typename RT, typename C,
2841  typename Arg1, typename Arg2, typename Arg3,
2842  typename Arg4, typename Arg5, typename Arg6,
2843  typename Arg7, typename Arg8>
2844  inline
2846  std_cxx1x::tuple<Arg1, Arg2, Arg3,
2847  Arg4, Arg5, Arg6,
2848  Arg7, Arg8>,8>
2849  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2850  Arg6,Arg7,Arg8) const)
2851  {
2852  return
2853  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> >::type>
2854  (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));
2855  }
2856 
2857 
2858 // ----------- encapsulators for functions with 9 arguments
2859 
2867  template <typename RT,
2868  typename Arg1, typename Arg2, typename Arg3,
2869  typename Arg4, typename Arg5, typename Arg6,
2870  typename Arg7, typename Arg8, typename Arg9>
2871  inline
2872  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2873  Arg4, Arg5, Arg6,
2874  Arg7, Arg8, Arg9>,9>
2875  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2876  Arg6,Arg7,Arg8,Arg9)) DEAL_II_DEPRECATED;
2877 
2878 
2879  template <typename RT,
2880  typename Arg1, typename Arg2, typename Arg3,
2881  typename Arg4, typename Arg5, typename Arg6,
2882  typename Arg7, typename Arg8, typename Arg9>
2883  inline
2884  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2885  Arg4, Arg5, Arg6,
2886  Arg7, Arg8, Arg9>,9>
2887  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2888  Arg6,Arg7,Arg8,Arg9))
2889  {
2890  return fun_ptr;
2891  }
2892 
2893 
2894 
2902  template <typename RT, typename C,
2903  typename Arg1, typename Arg2, typename Arg3,
2904  typename Arg4, typename Arg5, typename Arg6,
2905  typename Arg7, typename Arg8, typename Arg9>
2906  inline
2907  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2908  Arg4, Arg5, Arg6,
2909  Arg7, Arg8, Arg9>,9>
2910  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2911  Arg6,Arg7,Arg8,Arg9)) DEAL_II_DEPRECATED;
2912 
2913 
2914  template <typename RT, typename C,
2915  typename Arg1, typename Arg2, typename Arg3,
2916  typename Arg4, typename Arg5, typename Arg6,
2917  typename Arg7, typename Arg8, typename Arg9>
2918  inline
2919  internal::fun_encapsulator<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3,
2920  Arg4, Arg5, Arg6,
2921  Arg7, Arg8, Arg9>,9>
2922  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2923  Arg6,Arg7,Arg8,Arg9))
2924  {
2925  return
2926  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> >::type>
2927  (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));
2928  }
2929 
2937  template <typename RT, typename C,
2938  typename Arg1, typename Arg2, typename Arg3,
2939  typename Arg4, typename Arg5, typename Arg6,
2940  typename Arg7, typename Arg8, typename Arg9>
2941  inline
2943  std_cxx1x::tuple<Arg1, Arg2, Arg3,
2944  Arg4, Arg5, Arg6,
2945  Arg7, Arg8, Arg9>,9>
2946  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2947  Arg6,Arg7,Arg8,Arg9) const) DEAL_II_DEPRECATED;
2948 
2949 
2950  template <typename RT, typename C,
2951  typename Arg1, typename Arg2, typename Arg3,
2952  typename Arg4, typename Arg5, typename Arg6,
2953  typename Arg7, typename Arg8, typename Arg9>
2954  inline
2956  std_cxx1x::tuple<Arg1, Arg2, Arg3,
2957  Arg4, Arg5, Arg6,
2958  Arg7, Arg8, Arg9>,9>
2959  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2960  Arg6,Arg7,Arg8,Arg9) const)
2961  {
2962  return
2963  std_cxx1x::function<typename internal::fun_ptr<RT,std_cxx1x::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> >::type>
2964  (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));
2965  }
2966 
2967 
2968 
2969 // ----------- thread starters for functions not taking any parameters
2970 
2981  template <typename RT>
2982  inline
2983  Thread<RT>
2984  new_thread (const std_cxx1x::function<RT ()> &function)
2985  {
2986  return Thread<RT>(function);
2987  }
2988 
2996  template <typename RT>
2997  inline
2998  Thread<RT>
2999  new_thread (RT (*fun_ptr)())
3000  {
3001  return Thread<RT>(fun_ptr);
3002  }
3003 
3004 
3012  template <typename RT, typename C>
3013  inline
3014  Thread<RT>
3015  new_thread (RT (C::*fun_ptr)(),
3016  typename identity<C>::type &c)
3017  {
3018  return
3019  Thread<RT>
3020  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c)));
3021  }
3022 
3023 
3024 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3025 
3032  template <typename RT, typename C>
3033  inline
3034  Thread<RT>
3035  new_thread (RT (C::*fun_ptr)() const,
3036  const typename identity<C>::type &c)
3037  {
3038  return
3039  Thread<RT>
3040  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c)));
3041  }
3042 #endif
3043 
3044 
3045 
3046 // ----------- thread starters for unary functions
3047 
3055  template <typename RT, typename Arg1>
3056  inline
3057  Thread<RT>
3058  new_thread (RT (*fun_ptr)(Arg1),
3059  typename identity<Arg1>::type arg1)
3060  {
3061  return
3062  Thread<RT>
3063  (std_cxx1x::bind(fun_ptr,
3065  }
3066 
3067 
3068 
3076  template <typename RT, typename C, typename Arg1>
3077  inline
3078  Thread<RT>
3079  new_thread (RT (C::*fun_ptr)(Arg1),
3080  typename identity<C>::type &c,
3081  typename identity<Arg1>::type arg1)
3082  {
3083  return
3084  Thread<RT>
3085  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3087  }
3088 
3089 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3090 
3097  template <typename RT, typename C, typename Arg1>
3098  inline
3099  Thread<RT>
3100  new_thread (RT (C::*fun_ptr)(Arg1) const,
3101  typename identity<const C>::type &c,
3102  typename identity<Arg1>::type arg1)
3103  {
3104  return
3105  Thread<RT>
3106  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3108  }
3109 #endif
3110 
3111 // ----------- thread starters for binary functions
3112 
3120  template <typename RT, typename Arg1, typename Arg2>
3121  inline
3122  Thread<RT>
3123  new_thread (RT (*fun_ptr)(Arg1,Arg2),
3124  typename identity<Arg1>::type arg1,
3125  typename identity<Arg2>::type arg2)
3126  {
3127  return
3128  Thread<RT>
3129  (std_cxx1x::bind(fun_ptr,
3132  }
3133 
3134 
3135 
3143  template <typename RT, typename C, typename Arg1, typename Arg2>
3144  inline
3145  Thread<RT>
3146  new_thread (RT (C::*fun_ptr)(Arg1,Arg2),
3147  typename identity<C>::type &c,
3148  typename identity<Arg1>::type arg1,
3149  typename identity<Arg2>::type arg2)
3150  {
3151  return
3152  Thread<RT>
3153  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3156  }
3157 
3158 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3159 
3166  template <typename RT, typename C, typename Arg1, typename Arg2>
3167  inline
3168  Thread<RT>
3169  new_thread (RT (C::*fun_ptr)(Arg1,Arg2) const,
3170  typename identity<const C>::type &c,
3171  typename identity<Arg1>::type arg1,
3172  typename identity<Arg2>::type arg2)
3173  {
3174  return
3175  Thread<RT>
3176  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3179  }
3180 #endif
3181 
3182 // ----------- thread starters for ternary functions
3183 
3191  template <typename RT,
3192  typename Arg1, typename Arg2, typename Arg3>
3193  inline
3194  Thread<RT>
3195  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3),
3196  typename identity<Arg1>::type arg1,
3197  typename identity<Arg2>::type arg2,
3198  typename identity<Arg3>::type arg3)
3199  {
3200  return
3201  Thread<RT>
3202  (std_cxx1x::bind(fun_ptr,
3206  }
3207 
3208 
3209 
3217  template <typename RT, typename C,
3218  typename Arg1, typename Arg2, typename Arg3>
3219  inline
3220  Thread<RT>
3221  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3),
3222  typename identity<C>::type &c,
3223  typename identity<Arg1>::type arg1,
3224  typename identity<Arg2>::type arg2,
3225  typename identity<Arg3>::type arg3)
3226  {
3227  return
3228  Thread<RT>
3229  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3233  }
3234 
3235 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3236 
3243  template <typename RT, typename C,
3244  typename Arg1, typename Arg2, typename Arg3>
3245  inline
3246  Thread<RT>
3247  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const,
3248  typename identity<const C>::type &c,
3249  typename identity<Arg1>::type arg1,
3250  typename identity<Arg2>::type arg2,
3251  typename identity<Arg3>::type arg3)
3252  {
3253  return
3254  Thread<RT>
3255  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3259  }
3260 #endif
3261 
3262 
3263 // ----------- thread starters for functions with 4 arguments
3264 
3272  template <typename RT,
3273  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3274  inline
3275  Thread<RT>
3276  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
3277  typename identity<Arg1>::type arg1,
3278  typename identity<Arg2>::type arg2,
3279  typename identity<Arg3>::type arg3,
3280  typename identity<Arg4>::type arg4)
3281  {
3282  return
3283  Thread<RT>
3284  (std_cxx1x::bind(fun_ptr,
3289  }
3290 
3291 
3292 
3300  template <typename RT, typename C,
3301  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3302  inline
3303  Thread<RT>
3304  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
3305  typename identity<C>::type &c,
3306  typename identity<Arg1>::type arg1,
3307  typename identity<Arg2>::type arg2,
3308  typename identity<Arg3>::type arg3,
3309  typename identity<Arg4>::type arg4)
3310  {
3311  return
3312  Thread<RT>
3313  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3318  }
3319 
3320 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3321 
3328  template <typename RT, typename C,
3329  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3330  inline
3331  Thread<RT>
3332  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const,
3333  typename identity<const C>::type &c,
3334  typename identity<Arg1>::type arg1,
3335  typename identity<Arg2>::type arg2,
3336  typename identity<Arg3>::type arg3,
3337  typename identity<Arg4>::type arg4)
3338  {
3339  return
3340  Thread<RT>
3341  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3346  }
3347 #endif
3348 
3349 // ----------- thread starters for functions with 5 arguments
3350 
3358  template <typename RT,
3359  typename Arg1, typename Arg2, typename Arg3,
3360  typename Arg4, typename Arg5>
3361  inline
3362  Thread<RT>
3363  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
3364  typename identity<Arg1>::type arg1,
3365  typename identity<Arg2>::type arg2,
3366  typename identity<Arg3>::type arg3,
3367  typename identity<Arg4>::type arg4,
3368  typename identity<Arg5>::type arg5)
3369  {
3370  return
3371  Thread<RT>
3372  (std_cxx1x::bind(fun_ptr,
3378  }
3379 
3380 
3381 
3389  template <typename RT, typename C,
3390  typename Arg1, typename Arg2, typename Arg3,
3391  typename Arg4, typename Arg5>
3392  inline
3393  Thread<RT>
3394  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
3395  typename identity<C>::type &c,
3396  typename identity<Arg1>::type arg1,
3397  typename identity<Arg2>::type arg2,
3398  typename identity<Arg3>::type arg3,
3399  typename identity<Arg4>::type arg4,
3400  typename identity<Arg5>::type arg5)
3401  {
3402  return
3403  Thread<RT>
3404  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3410  }
3411 
3412 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3413 
3420  template <typename RT, typename C,
3421  typename Arg1, typename Arg2, typename Arg3,
3422  typename Arg4, typename Arg5>
3423  inline
3424  Thread<RT>
3425  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const,
3426  typename identity<const C>::type &c,
3427  typename identity<Arg1>::type arg1,
3428  typename identity<Arg2>::type arg2,
3429  typename identity<Arg3>::type arg3,
3430  typename identity<Arg4>::type arg4,
3431  typename identity<Arg5>::type arg5)
3432  {
3433  return
3434  Thread<RT>
3435  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3441  }
3442 #endif
3443 
3444 // ----------- thread starters for functions with 6 arguments
3445 
3453  template <typename RT,
3454  typename Arg1, typename Arg2, typename Arg3,
3455  typename Arg4, typename Arg5, typename Arg6>
3456  inline
3457  Thread<RT>
3458  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
3459  typename identity<Arg1>::type arg1,
3460  typename identity<Arg2>::type arg2,
3461  typename identity<Arg3>::type arg3,
3462  typename identity<Arg4>::type arg4,
3463  typename identity<Arg5>::type arg5,
3464  typename identity<Arg6>::type arg6)
3465  {
3466  return
3467  Thread<RT>
3468  (std_cxx1x::bind(fun_ptr,
3475  }
3476 
3477 
3478 
3486  template <typename RT, typename C,
3487  typename Arg1, typename Arg2, typename Arg3,
3488  typename Arg4, typename Arg5, typename Arg6>
3489  inline
3490  Thread<RT>
3491  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
3492  typename identity<C>::type &c,
3493  typename identity<Arg1>::type arg1,
3494  typename identity<Arg2>::type arg2,
3495  typename identity<Arg3>::type arg3,
3496  typename identity<Arg4>::type arg4,
3497  typename identity<Arg5>::type arg5,
3498  typename identity<Arg6>::type arg6)
3499  {
3500  return
3501  Thread<RT>
3502  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3509  }
3510 
3511 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3512 
3519  template <typename RT, typename C,
3520  typename Arg1, typename Arg2, typename Arg3,
3521  typename Arg4, typename Arg5, typename Arg6>
3522  inline
3523  Thread<RT>
3524  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const,
3525  typename identity<const C>::type &c,
3526  typename identity<Arg1>::type arg1,
3527  typename identity<Arg2>::type arg2,
3528  typename identity<Arg3>::type arg3,
3529  typename identity<Arg4>::type arg4,
3530  typename identity<Arg5>::type arg5,
3531  typename identity<Arg6>::type arg6)
3532  {
3533  return
3534  Thread<RT>
3535  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3542  }
3543 #endif
3544 
3545 // ----------- thread starters for functions with 7 arguments
3546 
3554  template <typename RT,
3555  typename Arg1, typename Arg2, typename Arg3,
3556  typename Arg4, typename Arg5, typename Arg6,
3557  typename Arg7>
3558  inline
3559  Thread<RT>
3560  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
3561  typename identity<Arg1>::type arg1,
3562  typename identity<Arg2>::type arg2,
3563  typename identity<Arg3>::type arg3,
3564  typename identity<Arg4>::type arg4,
3565  typename identity<Arg5>::type arg5,
3566  typename identity<Arg6>::type arg6,
3567  typename identity<Arg7>::type arg7)
3568  {
3569  return
3570  Thread<RT>
3571  (std_cxx1x::bind(fun_ptr,
3579  }
3580 
3581 
3582 
3590  template <typename RT, typename C,
3591  typename Arg1, typename Arg2, typename Arg3,
3592  typename Arg4, typename Arg5, typename Arg6,
3593  typename Arg7>
3594  inline
3595  Thread<RT>
3596  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
3597  typename identity<C>::type &c,
3598  typename identity<Arg1>::type arg1,
3599  typename identity<Arg2>::type arg2,
3600  typename identity<Arg3>::type arg3,
3601  typename identity<Arg4>::type arg4,
3602  typename identity<Arg5>::type arg5,
3603  typename identity<Arg6>::type arg6,
3604  typename identity<Arg7>::type arg7)
3605  {
3606  return
3607  Thread<RT>
3608  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3616  }
3617 
3618 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3619 
3626  template <typename RT, typename C,
3627  typename Arg1, typename Arg2, typename Arg3,
3628  typename Arg4, typename Arg5, typename Arg6,
3629  typename Arg7>
3630  inline
3631  Thread<RT>
3632  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const,
3633  typename identity<const C>::type &c,
3634  typename identity<Arg1>::type arg1,
3635  typename identity<Arg2>::type arg2,
3636  typename identity<Arg3>::type arg3,
3637  typename identity<Arg4>::type arg4,
3638  typename identity<Arg5>::type arg5,
3639  typename identity<Arg6>::type arg6,
3640  typename identity<Arg7>::type arg7)
3641  {
3642  return
3643  Thread<RT>
3644  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3652  }
3653 #endif
3654 
3655 // ----------- thread starters for functions with 8 arguments
3656 
3664  template <typename RT,
3665  typename Arg1, typename Arg2, typename Arg3,
3666  typename Arg4, typename Arg5, typename Arg6,
3667  typename Arg7, typename Arg8>
3668  inline
3669  Thread<RT>
3670  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3671  Arg6,Arg7,Arg8),
3672  typename identity<Arg1>::type arg1,
3673  typename identity<Arg2>::type arg2,
3674  typename identity<Arg3>::type arg3,
3675  typename identity<Arg4>::type arg4,
3676  typename identity<Arg5>::type arg5,
3677  typename identity<Arg6>::type arg6,
3678  typename identity<Arg7>::type arg7,
3679  typename identity<Arg8>::type arg8)
3680  {
3681  return
3682  Thread<RT>
3683  (std_cxx1x::bind(fun_ptr,
3692  }
3693 
3694 
3695 
3703  template <typename RT, typename C,
3704  typename Arg1, typename Arg2, typename Arg3,
3705  typename Arg4, typename Arg5, typename Arg6,
3706  typename Arg7, typename Arg8>
3707  inline
3708  Thread<RT>
3709  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3710  Arg6,Arg7,Arg8),
3711  typename identity<C>::type &c,
3712  typename identity<Arg1>::type arg1,
3713  typename identity<Arg2>::type arg2,
3714  typename identity<Arg3>::type arg3,
3715  typename identity<Arg4>::type arg4,
3716  typename identity<Arg5>::type arg5,
3717  typename identity<Arg6>::type arg6,
3718  typename identity<Arg7>::type arg7,
3719  typename identity<Arg8>::type arg8)
3720  {
3721  return
3722  Thread<RT>
3723  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3732  }
3733 
3734 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3735 
3742  template <typename RT, typename C,
3743  typename Arg1, typename Arg2, typename Arg3,
3744  typename Arg4, typename Arg5, typename Arg6,
3745  typename Arg7, typename Arg8>
3746  inline
3747  Thread<RT>
3748  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3749  Arg6,Arg7,Arg8) const,
3750  typename identity<const C>::type &c,
3751  typename identity<Arg1>::type arg1,
3752  typename identity<Arg2>::type arg2,
3753  typename identity<Arg3>::type arg3,
3754  typename identity<Arg4>::type arg4,
3755  typename identity<Arg5>::type arg5,
3756  typename identity<Arg6>::type arg6,
3757  typename identity<Arg7>::type arg7,
3758  typename identity<Arg8>::type arg8)
3759  {
3760  return
3761  Thread<RT>
3762  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3771  }
3772 #endif
3773 
3774 // ----------- thread starters for functions with 9 arguments
3775 
3783  template <typename RT,
3784  typename Arg1, typename Arg2, typename Arg3,
3785  typename Arg4, typename Arg5, typename Arg6,
3786  typename Arg7, typename Arg8, typename Arg9>
3787  inline
3788  Thread<RT>
3789  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3790  Arg6,Arg7,Arg8,Arg9),
3791  typename identity<Arg1>::type arg1,
3792  typename identity<Arg2>::type arg2,
3793  typename identity<Arg3>::type arg3,
3794  typename identity<Arg4>::type arg4,
3795  typename identity<Arg5>::type arg5,
3796  typename identity<Arg6>::type arg6,
3797  typename identity<Arg7>::type arg7,
3798  typename identity<Arg8>::type arg8,
3799  typename identity<Arg9>::type arg9)
3800  {
3801  return
3802  Thread<RT>
3803  (std_cxx1x::bind(fun_ptr,
3813  }
3814 
3815 
3816 
3824  template <typename RT, typename C,
3825  typename Arg1, typename Arg2, typename Arg3,
3826  typename Arg4, typename Arg5, typename Arg6,
3827  typename Arg7, typename Arg8, typename Arg9>
3828  inline
3829  Thread<RT>
3830  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3831  Arg6,Arg7,Arg8,Arg9),
3832  typename identity<C>::type &c,
3833  typename identity<Arg1>::type arg1,
3834  typename identity<Arg2>::type arg2,
3835  typename identity<Arg3>::type arg3,
3836  typename identity<Arg4>::type arg4,
3837  typename identity<Arg5>::type arg5,
3838  typename identity<Arg6>::type arg6,
3839  typename identity<Arg7>::type arg7,
3840  typename identity<Arg8>::type arg8,
3841  typename identity<Arg9>::type arg9)
3842  {
3843  return
3844  Thread<RT>
3845  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
3855  }
3856 
3857 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3858 
3865  template <typename RT, typename C,
3866  typename Arg1, typename Arg2, typename Arg3,
3867  typename Arg4, typename Arg5, typename Arg6,
3868  typename Arg7, typename Arg8, typename Arg9>
3869  inline
3870  Thread<RT>
3871  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3872  Arg6,Arg7,Arg8,Arg9) const,
3873  typename identity<const C>::type &c,
3874  typename identity<Arg1>::type arg1,
3875  typename identity<Arg2>::type arg2,
3876  typename identity<Arg3>::type arg3,
3877  typename identity<Arg4>::type arg4,
3878  typename identity<Arg5>::type arg5,
3879  typename identity<Arg6>::type arg6,
3880  typename identity<Arg7>::type arg7,
3881  typename identity<Arg8>::type arg8,
3882  typename identity<Arg9>::type arg9)
3883  {
3884  return
3885  Thread<RT>
3886  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
3896  }
3897 #endif
3898 
3899 // ------------------------ ThreadGroup -------------------------------------
3900 
3912  template <typename RT = void>
3914  {
3915  public:
3920  ThreadGroup &operator += (const Thread<RT> &t)
3921  {
3922  threads.push_back (t);
3923  return *this;
3924  }
3925 
3938  void join_all () const
3939  {
3940  for (typename std::list<Thread<RT> >::const_iterator
3941  t=threads.begin(); t!=threads.end(); ++t)
3942  t->join ();
3943  }
3944 
3945  private:
3949  std::list<Thread<RT> > threads;
3950  };
3951 
3952 
3953  template <typename> class Task;
3954 
3955 
3956  namespace internal
3957  {
3958 #ifdef DEAL_II_WITH_THREADS
3959 
3960  template <typename> struct TaskDescriptor;
3961 
3967  template <typename RT>
3968  struct TaskEntryPoint : public tbb::task
3969  {
3970  TaskEntryPoint (TaskDescriptor<RT> &task_descriptor)
3971  :
3972  task_descriptor (task_descriptor)
3973  {}
3974 
3975  virtual tbb::task *execute ()
3976  {
3977  // call the function object
3978  // and put the return value
3979  // into the proper place
3980  try
3981  {
3982  call (task_descriptor.function, task_descriptor.ret_val);
3983  }
3984  catch (const std::exception &exc)
3985  {
3986  internal::handle_std_exception (exc);
3987  }
3988  catch (...)
3989  {
3990  internal::handle_unknown_exception ();
3991  }
3992  return 0;
3993  }
3994 
4000  };
4001 
4042  template <typename RT>
4043  struct TaskDescriptor
4044  {
4045  private:
4050  std_cxx1x::function<RT ()> function;
4051 
4065  tbb::task *task;
4066 
4072 
4078 
4079  public:
4080 
4085  TaskDescriptor (const std_cxx1x::function<RT ()> &function);
4086 
4098  TaskDescriptor ();
4099 
4108  TaskDescriptor (const TaskDescriptor &);
4109 
4113  ~TaskDescriptor ();
4114 
4128  void queue_task ();
4129 
4139  void join ();
4140 
4141 
4142  template <typename> friend struct TaskEntryPoint;
4143  friend class ::Threads::Task<RT>;
4144  };
4145 
4146 
4147 
4148  template <typename RT>
4149  inline
4150  TaskDescriptor<RT>::TaskDescriptor (const std_cxx1x::function<RT ()> &function)
4151  :
4152  function (function),
4153  task_is_done (false)
4154  {}
4155 
4156 
4157  template <typename RT>
4158  inline
4159  void
4161  {
4162  // use the pattern described in
4163  // the TBB book on pages
4164  // 230/231 ("Start a large task
4165  // in parallel with the main
4166  // program")
4167  task = new (tbb::task::allocate_root()) tbb::empty_task;
4168  task->set_ref_count (2);
4169 
4170  tbb::task *worker = new (task->allocate_child()) TaskEntryPoint<RT>(*this);
4171  task->spawn (*worker);
4172  }
4173 
4174 
4175 
4176  template <typename RT>
4178  {
4179  Assert (false, ExcInternalError());
4180  }
4181 
4182 
4183 
4184  template <typename RT>
4186  {
4187  Assert (false, ExcInternalError());
4188  }
4189 
4190 
4191 
4192  template <typename RT>
4193  inline
4195  {
4196  // wait for the task to
4197  // complete for sure
4198  join ();
4199 
4200  // now destroy the empty task
4201  // structure. the book recommends to
4202  // spawn it as well and let the
4203  // scheduler destroy the object when
4204  // done, but this has the disadvantage
4205  // that the scheduler may not get to
4206  // actually finishing the task before
4207  // it goes out of scope (at the end of
4208  // the program, or if a thread is done
4209  // on which it was run) and then we
4210  // would get a hard-to-decipher warning
4211  // about unfinished tasks when the
4212  // scheduler "goes out of the
4213  // arena". rather, let's explicitly
4214  // destroy the empty task
4215  // object. before that, make sure that
4216  // the task has been shut down,
4217  // expressed by a zero reference count
4218  Assert (task != 0, ExcInternalError());
4219  Assert (task->ref_count()==0, ExcInternalError());
4220  task->destroy (*task);
4221  }
4222 
4223 
4224  template <typename RT>
4225  inline
4226  void
4228  {
4229  // if the task is already done, just
4230  // return. this makes sure we call
4231  // tbb::Task::wait_for_all() exactly
4232  // once, as required by TBB. we could
4233  // also get the reference count of task
4234  // for doing this, but that is usually
4235  // slower. note that this does not work
4236  // when the thread calling this
4237  // function is not the same as the one
4238  // that initialized the task.
4239  //
4240  // TODO: can we assert that no other
4241  // thread tries to end the task?
4242  if (task_is_done == true)
4243  return;
4244 
4245  // let TBB wait for the task to
4246  // complete.
4247  task_is_done = true;
4248  task->wait_for_all();
4249  }
4250 
4251 
4252 
4253 #else // no threading enabled
4254 
4261  template <typename RT>
4262  struct TaskDescriptor
4263  {
4269 
4277  TaskDescriptor (const std_cxx1x::function<RT ()> &function)
4278  {
4279  call (function, ret_val);
4280  }
4281 
4288  static void join () {}
4289 
4297  static void queue_task () {}
4298  };
4299 
4300 #endif
4301 
4302  }
4303 
4304 
4305 
4319  template <typename RT = void>
4320  class Task
4321  {
4322  public:
4328  Task (const std_cxx1x::function<RT ()> &function_object)
4329  {
4330  // create a task descriptor and tell it
4331  // to queue itself up with the scheduling
4332  // system
4333  task_descriptor =
4334  std_cxx1x::shared_ptr<internal::TaskDescriptor<RT> >
4335  (new internal::TaskDescriptor<RT>(function_object));
4336  task_descriptor->queue_task ();
4337  }
4338 
4339 
4343  Task (const Task<RT> &t)
4344  :
4345  task_descriptor (t.task_descriptor)
4346  {}
4347 
4348 
4358  Task () {}
4359 
4370  void join () const
4371  {
4372  AssertThrow (task_descriptor !=
4373  std_cxx1x::shared_ptr<internal::TaskDescriptor<RT> >(),
4374  ExcNoTask());
4375  task_descriptor->join ();
4376  }
4377 
4387  {
4388  join ();
4389  return task_descriptor->ret_val.get();
4390  }
4391 
4392 
4402  bool operator == (const Task &t)
4403  {
4404  AssertThrow (task_descriptor !=
4405  std_cxx1x::shared_ptr<internal::TaskDescriptor<RT> >(),
4406  ExcNoTask());
4407  return task_descriptor == t.task_descriptor;
4408  }
4409 
4416  DeclException0 (ExcNoTask);
4418  private:
4427  std_cxx1x::shared_ptr<internal::TaskDescriptor<RT> > task_descriptor;
4428  };
4429 
4430 
4431 
4442  template <typename RT>
4443  inline
4444  Task<RT>
4445  new_task (const std_cxx1x::function<RT ()> &function)
4446  {
4447  return Task<RT>(function);
4448  }
4449 
4457  template <typename RT>
4458  inline
4459  Task<RT>
4460  new_task (RT (*fun_ptr)())
4461  {
4462  return new_task<RT>(std_cxx1x::function<RT ()>(fun_ptr));
4463  }
4464 
4465 
4473  template <typename RT, typename C>
4474  inline
4475  Task<RT>
4476  new_task (RT (C::*fun_ptr)(),
4477  typename identity<C>::type &c)
4478  {
4479  return
4480  new_task<RT>
4481  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c)));
4482  }
4483 
4484 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4485 
4492  template <typename RT, typename C>
4493  inline
4494  Task<RT>
4495  new_task (RT (C::*fun_ptr)() const,
4496  const typename identity<C>::type &c)
4497  {
4498  return
4499  new_task<RT>
4500  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c)));
4501  }
4502 #endif
4503 
4504 
4505 
4506 // ----------- thread starters for unary functions
4507 
4515  template <typename RT, typename Arg1>
4516  inline
4517  Task<RT>
4518  new_task (RT (*fun_ptr)(Arg1),
4519  typename identity<Arg1>::type arg1)
4520  {
4521  return
4522  new_task<RT>
4523  (std_cxx1x::bind(fun_ptr,
4525  }
4526 
4527 
4528 
4536  template <typename RT, typename C, typename Arg1>
4537  inline
4538  Task<RT>
4539  new_task (RT (C::*fun_ptr)(Arg1),
4540  typename identity<C>::type &c,
4541  typename identity<Arg1>::type arg1)
4542  {
4543  return
4544  new_task<RT>
4545  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
4547  }
4548 
4549 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4550 
4557  template <typename RT, typename C, typename Arg1>
4558  inline
4559  Task<RT>
4560  new_task (RT (C::*fun_ptr)(Arg1) const,
4561  typename identity<const C>::type &c,
4562  typename identity<Arg1>::type arg1)
4563  {
4564  return
4565  new_task<RT>
4566  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
4568  }
4569 #endif
4570 
4571 // ----------- thread starters for binary functions
4572 
4580  template <typename RT, typename Arg1, typename Arg2>
4581  inline
4582  Task<RT>
4583  new_task (RT (*fun_ptr)(Arg1,Arg2),
4584  typename identity<Arg1>::type arg1,
4585  typename identity<Arg2>::type arg2)
4586  {
4587  return
4588  new_task<RT>
4589  (std_cxx1x::bind(fun_ptr,
4592  }
4593 
4594 
4595 
4603  template <typename RT, typename C, typename Arg1, typename Arg2>
4604  inline
4605  Task<RT>
4606  new_task (RT (C::*fun_ptr)(Arg1,Arg2),
4607  typename identity<C>::type &c,
4608  typename identity<Arg1>::type arg1,
4609  typename identity<Arg2>::type arg2)
4610  {
4611  return
4612  new_task<RT>
4613  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
4616  }
4617 
4618 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4619 
4626  template <typename RT, typename C, typename Arg1, typename Arg2>
4627  inline
4628  Task<RT>
4629  new_task (RT (C::*fun_ptr)(Arg1,Arg2) const,
4630  typename identity<const C>::type &c,
4631  typename identity<Arg1>::type arg1,
4632  typename identity<Arg2>::type arg2)
4633  {
4634  return
4635  new_task<RT>
4636  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
4639  }
4640 #endif
4641 
4642 // ----------- thread starters for ternary functions
4643 
4651  template <typename RT,
4652  typename Arg1, typename Arg2, typename Arg3>
4653  inline
4654  Task<RT>
4655  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3),
4656  typename identity<Arg1>::type arg1,
4657  typename identity<Arg2>::type arg2,
4658  typename identity<Arg3>::type arg3)
4659  {
4660  return
4661  new_task<RT>
4662  (std_cxx1x::bind(fun_ptr,
4666  }
4667 
4668 
4669 
4677  template <typename RT, typename C,
4678  typename Arg1, typename Arg2, typename Arg3>
4679  inline
4680  Task<RT>
4681  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3),
4682  typename identity<C>::type &c,
4683  typename identity<Arg1>::type arg1,
4684  typename identity<Arg2>::type arg2,
4685  typename identity<Arg3>::type arg3)
4686  {
4687  return
4688  new_task<RT>
4689  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
4693  }
4694 
4695 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4696 
4703  template <typename RT, typename C,
4704  typename Arg1, typename Arg2, typename Arg3>
4705  inline
4706  Task<RT>
4707  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const,
4708  typename identity<const C>::type &c,
4709  typename identity<Arg1>::type arg1,
4710  typename identity<Arg2>::type arg2,
4711  typename identity<Arg3>::type arg3)
4712  {
4713  return
4714  new_task<RT>
4715  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
4719  }
4720 #endif
4721 
4722 
4723 // ----------- thread starters for functions with 4 arguments
4724 
4732  template <typename RT,
4733  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
4734  inline
4735  Task<RT>
4736  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
4737  typename identity<Arg1>::type arg1,
4738  typename identity<Arg2>::type arg2,
4739  typename identity<Arg3>::type arg3,
4740  typename identity<Arg4>::type arg4)
4741  {
4742  return
4743  new_task<RT>
4744  (std_cxx1x::bind(fun_ptr,
4749  }
4750 
4751 
4752 
4760  template <typename RT, typename C,
4761  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
4762  inline
4763  Task<RT>
4764  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
4765  typename identity<C>::type &c,
4766  typename identity<Arg1>::type arg1,
4767  typename identity<Arg2>::type arg2,
4768  typename identity<Arg3>::type arg3,
4769  typename identity<Arg4>::type arg4)
4770  {
4771  return
4772  new_task<RT>
4773  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
4778  }
4779 
4780 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4781 
4788  template <typename RT, typename C,
4789  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
4790  inline
4791  Task<RT>
4792  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const,
4793  typename identity<const C>::type &c,
4794  typename identity<Arg1>::type arg1,
4795  typename identity<Arg2>::type arg2,
4796  typename identity<Arg3>::type arg3,
4797  typename identity<Arg4>::type arg4)
4798  {
4799  return
4800  new_task<RT>
4801  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
4806  }
4807 #endif
4808 
4809 // ----------- thread starters for functions with 5 arguments
4810 
4818  template <typename RT,
4819  typename Arg1, typename Arg2, typename Arg3,
4820  typename Arg4, typename Arg5>
4821  inline
4822  Task<RT>
4823  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
4824  typename identity<Arg1>::type arg1,
4825  typename identity<Arg2>::type arg2,
4826  typename identity<Arg3>::type arg3,
4827  typename identity<Arg4>::type arg4,
4828  typename identity<Arg5>::type arg5)
4829  {
4830  return
4831  new_task<RT>
4832  (std_cxx1x::bind(fun_ptr,
4838  }
4839 
4840 
4841 
4849  template <typename RT, typename C,
4850  typename Arg1, typename Arg2, typename Arg3,
4851  typename Arg4, typename Arg5>
4852  inline
4853  Task<RT>
4854  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
4855  typename identity<C>::type &c,
4856  typename identity<Arg1>::type arg1,
4857  typename identity<Arg2>::type arg2,
4858  typename identity<Arg3>::type arg3,
4859  typename identity<Arg4>::type arg4,
4860  typename identity<Arg5>::type arg5)
4861  {
4862  return
4863  new_task<RT>
4864  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
4870  }
4871 
4872 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4873 
4880  template <typename RT, typename C,
4881  typename Arg1, typename Arg2, typename Arg3,
4882  typename Arg4, typename Arg5>
4883  inline
4884  Task<RT>
4885  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const,
4886  typename identity<const C>::type &c,
4887  typename identity<Arg1>::type arg1,
4888  typename identity<Arg2>::type arg2,
4889  typename identity<Arg3>::type arg3,
4890  typename identity<Arg4>::type arg4,
4891  typename identity<Arg5>::type arg5)
4892  {
4893  return
4894  new_task<RT>
4895  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
4901  }
4902 #endif
4903 
4904 // ----------- thread starters for functions with 6 arguments
4905 
4913  template <typename RT,
4914  typename Arg1, typename Arg2, typename Arg3,
4915  typename Arg4, typename Arg5, typename Arg6>
4916  inline
4917  Task<RT>
4918  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
4919  typename identity<Arg1>::type arg1,
4920  typename identity<Arg2>::type arg2,
4921  typename identity<Arg3>::type arg3,
4922  typename identity<Arg4>::type arg4,
4923  typename identity<Arg5>::type arg5,
4924  typename identity<Arg6>::type arg6)
4925  {
4926  return
4927  new_task<RT>
4928  (std_cxx1x::bind(fun_ptr,
4935  }
4936 
4937 
4938 
4946  template <typename RT, typename C,
4947  typename Arg1, typename Arg2, typename Arg3,
4948  typename Arg4, typename Arg5, typename Arg6>
4949  inline
4950  Task<RT>
4951  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
4952  typename identity<C>::type &c,
4953  typename identity<Arg1>::type arg1,
4954  typename identity<Arg2>::type arg2,
4955  typename identity<Arg3>::type arg3,
4956  typename identity<Arg4>::type arg4,
4957  typename identity<Arg5>::type arg5,
4958  typename identity<Arg6>::type arg6)
4959  {
4960  return
4961  new_task<RT>
4962  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
4969  }
4970 
4971 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4972 
4979  template <typename RT, typename C,
4980  typename Arg1, typename Arg2, typename Arg3,
4981  typename Arg4, typename Arg5, typename Arg6>
4982  inline
4983  Task<RT>
4984  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const,
4985  typename identity<const C>::type &c,
4986  typename identity<Arg1>::type arg1,
4987  typename identity<Arg2>::type arg2,
4988  typename identity<Arg3>::type arg3,
4989  typename identity<Arg4>::type arg4,
4990  typename identity<Arg5>::type arg5,
4991  typename identity<Arg6>::type arg6)
4992  {
4993  return
4994  new_task<RT>
4995  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
5002  }
5003 #endif
5004 
5005 // ----------- thread starters for functions with 7 arguments
5006 
5014  template <typename RT,
5015  typename Arg1, typename Arg2, typename Arg3,
5016  typename Arg4, typename Arg5, typename Arg6,
5017  typename Arg7>
5018  inline
5019  Task<RT>
5020  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
5021  typename identity<Arg1>::type arg1,
5022  typename identity<Arg2>::type arg2,
5023  typename identity<Arg3>::type arg3,
5024  typename identity<Arg4>::type arg4,
5025  typename identity<Arg5>::type arg5,
5026  typename identity<Arg6>::type arg6,
5027  typename identity<Arg7>::type arg7)
5028  {
5029  return
5030  new_task<RT>
5031  (std_cxx1x::bind(fun_ptr,
5039  }
5040 
5041 
5042 
5050  template <typename RT, typename C,
5051  typename Arg1, typename Arg2, typename Arg3,
5052  typename Arg4, typename Arg5, typename Arg6,
5053  typename Arg7>
5054  inline
5055  Task<RT>
5056  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
5057  typename identity<C>::type &c,
5058  typename identity<Arg1>::type arg1,
5059  typename identity<Arg2>::type arg2,
5060  typename identity<Arg3>::type arg3,
5061  typename identity<Arg4>::type arg4,
5062  typename identity<Arg5>::type arg5,
5063  typename identity<Arg6>::type arg6,
5064  typename identity<Arg7>::type arg7)
5065  {
5066  return
5067  new_task<RT>
5068  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
5076  }
5077 
5078 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
5079 
5086  template <typename RT, typename C,
5087  typename Arg1, typename Arg2, typename Arg3,
5088  typename Arg4, typename Arg5, typename Arg6,
5089  typename Arg7>
5090  inline
5091  Task<RT>
5092  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const,
5093  typename identity<const C>::type &c,
5094  typename identity<Arg1>::type arg1,
5095  typename identity<Arg2>::type arg2,
5096  typename identity<Arg3>::type arg3,
5097  typename identity<Arg4>::type arg4,
5098  typename identity<Arg5>::type arg5,
5099  typename identity<Arg6>::type arg6,
5100  typename identity<Arg7>::type arg7)
5101  {
5102  return
5103  new_task<RT>
5104  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
5112  }
5113 #endif
5114 
5115 // ----------- thread starters for functions with 8 arguments
5116 
5124  template <typename RT,
5125  typename Arg1, typename Arg2, typename Arg3,
5126  typename Arg4, typename Arg5, typename Arg6,
5127  typename Arg7, typename Arg8>
5128  inline
5129  Task<RT>
5130  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
5131  Arg6,Arg7,Arg8),
5132  typename identity<Arg1>::type arg1,
5133  typename identity<Arg2>::type arg2,
5134  typename identity<Arg3>::type arg3,
5135  typename identity<Arg4>::type arg4,
5136  typename identity<Arg5>::type arg5,
5137  typename identity<Arg6>::type arg6,
5138  typename identity<Arg7>::type arg7,
5139  typename identity<Arg8>::type arg8)
5140  {
5141  return
5142  new_task<RT>
5143  (std_cxx1x::bind(fun_ptr,
5152  }
5153 
5154 
5155 
5163  template <typename RT, typename C,
5164  typename Arg1, typename Arg2, typename Arg3,
5165  typename Arg4, typename Arg5, typename Arg6,
5166  typename Arg7, typename Arg8>
5167  inline
5168  Task<RT>
5169  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
5170  Arg6,Arg7,Arg8),
5171  typename identity<C>::type &c,
5172  typename identity<Arg1>::type arg1,
5173  typename identity<Arg2>::type arg2,
5174  typename identity<Arg3>::type arg3,
5175  typename identity<Arg4>::type arg4,
5176  typename identity<Arg5>::type arg5,
5177  typename identity<Arg6>::type arg6,
5178  typename identity<Arg7>::type arg7,
5179  typename identity<Arg8>::type arg8)
5180  {
5181  return
5182  new_task<RT>
5183  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
5192  }
5193 
5194 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
5195 
5202  template <typename RT, typename C,
5203  typename Arg1, typename Arg2, typename Arg3,
5204  typename Arg4, typename Arg5, typename Arg6,
5205  typename Arg7, typename Arg8>
5206  inline
5207  Task<RT>
5208  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
5209  Arg6,Arg7,Arg8) const,
5210  typename identity<const C>::type &c,
5211  typename identity<Arg1>::type arg1,
5212  typename identity<Arg2>::type arg2,
5213  typename identity<Arg3>::type arg3,
5214  typename identity<Arg4>::type arg4,
5215  typename identity<Arg5>::type arg5,
5216  typename identity<Arg6>::type arg6,
5217  typename identity<Arg7>::type arg7,
5218  typename identity<Arg8>::type arg8)
5219  {
5220  return
5221  new_task<RT>
5222  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
5231  }
5232 #endif
5233 
5234 // ----------- thread starters for functions with 9 arguments
5235 
5243  template <typename RT,
5244  typename Arg1, typename Arg2, typename Arg3,
5245  typename Arg4, typename Arg5, typename Arg6,
5246  typename Arg7, typename Arg8, typename Arg9>
5247  inline
5248  Task<RT>
5249  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
5250  Arg6,Arg7,Arg8,Arg9),
5251  typename identity<Arg1>::type arg1,
5252  typename identity<Arg2>::type arg2,
5253  typename identity<Arg3>::type arg3,
5254  typename identity<Arg4>::type arg4,
5255  typename identity<Arg5>::type arg5,
5256  typename identity<Arg6>::type arg6,
5257  typename identity<Arg7>::type arg7,
5258  typename identity<Arg8>::type arg8,
5259  typename identity<Arg9>::type arg9)
5260  {
5261  return
5262  new_task<RT>
5263  (std_cxx1x::bind(fun_ptr,
5273  }
5274 
5275 
5276 
5284  template <typename RT, typename C,
5285  typename Arg1, typename Arg2, typename Arg3,
5286  typename Arg4, typename Arg5, typename Arg6,
5287  typename Arg7, typename Arg8, typename Arg9>
5288  inline
5289  Task<RT>
5290  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
5291  Arg6,Arg7,Arg8,Arg9),
5292  typename identity<C>::type &c,
5293  typename identity<Arg1>::type arg1,
5294  typename identity<Arg2>::type arg2,
5295  typename identity<Arg3>::type arg3,
5296  typename identity<Arg4>::type arg4,
5297  typename identity<Arg5>::type arg5,
5298  typename identity<Arg6>::type arg6,
5299  typename identity<Arg7>::type arg7,
5300  typename identity<Arg8>::type arg8,
5301  typename identity<Arg9>::type arg9)
5302  {
5303  return
5304  new_task<RT>
5305  (std_cxx1x::bind(fun_ptr, std_cxx1x::ref(c),
5315  }
5316 
5317 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
5318 
5325  template <typename RT, typename C,
5326  typename Arg1, typename Arg2, typename Arg3,
5327  typename Arg4, typename Arg5, typename Arg6,
5328  typename Arg7, typename Arg8, typename Arg9>
5329  inline
5330  Task<RT>
5331  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
5332  Arg6,Arg7,Arg8,Arg9) const,
5333  typename identity<const C>::type &c,
5334  typename identity<Arg1>::type arg1,
5335  typename identity<Arg2>::type arg2,
5336  typename identity<Arg3>::type arg3,
5337  typename identity<Arg4>::type arg4,
5338  typename identity<Arg5>::type arg5,
5339  typename identity<Arg6>::type arg6,
5340  typename identity<Arg7>::type arg7,
5341  typename identity<Arg8>::type arg8,
5342  typename identity<Arg9>::type arg9)
5343  {
5344  return
5345  new_task<RT>
5346  (std_cxx1x::bind(fun_ptr, std_cxx1x::cref(c),
5356  }
5357 #endif
5358 
5359 
5360 // ------------------------ TaskGroup -------------------------------------
5361 
5381  template <typename RT = void>
5383  {
5384  public:
5389  TaskGroup &operator += (const Task<RT> &t)
5390  {
5391  tasks.push_back (t);
5392  return *this;
5393  }
5394 
5407  void join_all () const
5408  {
5409  for (typename std::list<Task<RT> >::const_iterator
5410  t=tasks.begin(); t!=tasks.end(); ++t)
5411  t->join ();
5412  }
5413 
5414  private:
5418  std::list<Task<RT> > tasks;
5419  };
5420 
5421 } // end of implementation of namespace Threads
5422 
5428 //---------------------------------------------------------------------------
5429 DEAL_II_NAMESPACE_CLOSE
5430 // end of #ifndef __deal2__thread_management_h
5431 #endif
5432 //---------------------------------------------------------------------------
bool valid() const
std::vector< std::pair< ForwardIterator, ForwardIterator > > split_range(const ForwardIterator &begin, const ForwardIterator &end, const unsigned int n_intervals)
unsigned int this_thread_id()
Thread(const Thread< RT > &t)
TaskDescriptor< RT > & task_descriptor
Mutex(const Mutex &)
std_cxx1x::shared_ptr< internal::TaskDescriptor< RT > > task_descriptor
std::list< Task< RT > > tasks
#define AssertThrow(cond, exc)
Definition: exceptions.h:362
Thread< RT > new_thread(const std_cxx1x::function< RT()> &function)
void start(const std_cxx1x::function< RT()> &function)
std::vector< std::pair< unsigned int, unsigned int > > split_interval(const unsigned int begin, const unsigned int end, const unsigned int n_intervals)
void join() const
void wait(DummyThreadMutex &) const
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:515
#define Assert(cond, exc)
Definition: exceptions.h:299
static void thread_entry_point(const std_cxx1x::function< RT()> function, std_cxx1x::shared_ptr< return_value< RT > > ret_val)
void join() const
#define DeclException0(Exception0)
Definition: exceptions.h:505
std_cxx1x::shared_ptr< internal::ThreadDescriptor< RT > > thread_descriptor
unsigned int n_existing_threads()
Mutex ThreadMutex DEAL_II_DEPRECATED
std_cxx1x::function< RT()> function
std_cxx1x::mutex mutex
std_cxx1x::shared_ptr< return_value< RT > > ret_val
PosixThreadBarrier Barrier
Task(const Task< RT > &t)
internal::fun_encapsulator< RT, std_cxx1x::tuple<>, 0 > spawn(RT(*fun_ptr)()) DEAL_II_DEPRECATED
Thread(const std_cxx1x::function< RT()> &function)
Task< RT > new_task(const std_cxx1x::function< RT()> &function)
::ExceptionBase & ExcInternalError()
Task(const std_cxx1x::function< RT()> &function_object)
std::list< Thread< RT > > threads
std_cxx1x::condition_variable condition_variable