]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Merge the new threading scheme.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 6 Feb 2003 18:14:39 +0000 (18:14 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 6 Feb 2003 18:14:39 +0000 (18:14 +0000)
git-svn-id: https://svn.dealii.org/trunk@7060 0785d39b-7218-0410-832d-ea1e28bc413d

27 files changed:
deal.II/aclocal.m4
deal.II/base/include/base/config.h.in
deal.II/base/include/base/thread_management.h
deal.II/base/source/data_out_base.cc
deal.II/base/source/thread_management.cc
deal.II/common/Make.global_options.in
deal.II/configure
deal.II/configure.in
deal.II/contrib/hsl/source/detached_ma27.cc
deal.II/deal.II/source/dofs/dof_tools.cc
deal.II/deal.II/source/grid/grid_generator.cc
deal.II/deal.II/source/multigrid/mg_dof_tools.cc
deal.II/deal.II/source/numerics/data_out.cc
deal.II/deal.II/source/numerics/data_out_faces.cc
deal.II/deal.II/source/numerics/data_out_rotation.cc
deal.II/deal.II/source/numerics/derivative_approximation.cc
deal.II/deal.II/source/numerics/error_estimator.cc
deal.II/deal.II/source/numerics/matrices.cc
deal.II/deal.II/source/numerics/time_dependent.cc
deal.II/examples/step-13/step-13.cc
deal.II/examples/step-14/step-14.cc
deal.II/examples/step-9/step-9.cc
deal.II/lac/include/lac/sparse_matrix.templates.h
deal.II/lac/include/lac/sparse_vanka.templates.h
deal.II/lac/include/lac/swappable_vector.h
deal.II/lac/include/lac/swappable_vector.templates.h
tests/base/Makefile

index fae35f911aa1b352741bc2f15cfdef787d9e98f2..37b378a1b7d9f7bacc3ff1182e303c4fb43694d7 100644 (file)
@@ -228,6 +228,9 @@ AC_DEFUN(DEAL_II_SET_CXX_FLAGS, dnl
     CXXFLAGSO="$CXXFLAGS -O2 -Wuninitialized -felide-constructors -ftemplate-depth-32"
     CXXFLAGSG="$CXXFLAGS -DDEBUG -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Winline -Woverloaded-virtual -Wstrict-prototypes -Wsynth -Wsign-compare -Wconversion -Wswitch -ftemplate-depth-32"
 
+    dnl BOOST uses long long, so don't warn about this
+    CXXFLAGSG="$CXXFLAGSG -Wno-long-long"
+
     dnl Set PIC flags. On some systems, -fpic/PIC is implied, so don't set
     dnl anything to avoid a warning
     case "$target" in
@@ -297,12 +300,36 @@ AC_DEFUN(DEAL_II_SET_CXX_FLAGS, dnl
       CXXFLAGSG="`echo $CXXFLAGSG | perl -pi -e 's/-W //g;'`"
     fi
 
-    dnl Use -Wno-long-long on Apple Darwin to avoid some unnecessary warning
+    dnl Some system specific things
     case "$target" in
+      dnl Use -Wno-long-long on Apple Darwin to avoid some unnecessary warning
       *apple-darwin*)
        CXXFLAGSG="$CXXFLAGSG -Wno-long-double"
        CXXFLAGSO="$CXXFLAGSO -Wno-long-double"
         ;;
+
+      dnl On DEC OSF, including both stdio.h and unistd.h causes a warning
+      dnl from the preprocessor that cuserid is redefined as a preprocessor
+      dnl variable. Suppress this if necessary by switching off warnings
+      dnl from the preprocessor
+      *dec-osf*)
+        AC_MSG_CHECKING(for preprocessor warning with cuserid)
+       CXXFLAGS="$CXXFLAGSG -Werror"
+       AC_TRY_COMPILE(
+          [
+#          include <stdio.h>
+#          include <unistd.h>
+          ],
+          [;],
+          [
+            AC_MSG_RESULT(no)
+          ],
+          [
+            AC_MSG_RESULT(yes)
+            CXXFLAGSG="$CXXFLAGSG -Wp,-w"
+            CXXFLAGSO="$CXXFLAGSO -Wp,-w"
+          ])
+        ;;
     esac
 
     dnl In order to link shared libraries, almost all versions of gcc can
@@ -405,6 +432,8 @@ AC_DEFUN(DEAL_II_SET_CXX_FLAGS, dnl
           dnl #1182:`statement either is unreachable or causes unreachable code'
           dnl       (happens in switch(dim) clauses for other dimensions than
           dnl       the present one)
+         dnl #450:`the type "long long" is nonstandard'
+         dnl       BOOST uses long long, unfortunately
           dnl
           dnl Also disable the following error:
           dnl #265: `class "..." is inaccessible' (happens when we try to
@@ -423,11 +452,12 @@ AC_DEFUN(DEAL_II_SET_CXX_FLAGS, dnl
           CXXFLAGSG="$CXXFLAGS -model ansi -std strict_ansi -w1 -msg_display_number -timplicit_local -DDEBUG"
           CXXFLAGSO="$CXXFLAGS -model ansi -std strict_ansi -w2 -msg_display_number -timplicit_local -fast"
   
-          for i in 175 236 237 381 487 1136 1156 111 1182 265 ; do
+          for i in 175 236 237 381 487 1136 1156 111 1182 265 450 ; do
             CXXFLAGSG="$CXXFLAGSG -msg_disable $i"
             CXXFLAGSO="$CXXFLAGSO -msg_disable $i"
           done
   
+
           dnl If we use -model ansi to compile the files, we also have to
           dnl specify it for linking
           LDFLAGS="$LDFLAGS -model ansi"
@@ -481,7 +511,7 @@ AC_DEFUN(DEAL_II_SET_CXX_FLAGS, dnl
           ;;
   
       borland_bcc)
-          CXXFLAGSG="$CXXFLAGS -q -DDEBUG -w -w-use -w-amp"
+          CXXFLAGSG="$CXXFLAGS -q -DDEBUG -w -w-use -w-amp -w-prc"
           CXXFLAGSO="$CXXFLAGS -q -O2"
           CXXFLAGSPIC=""
           LDFLAGSPIC=""
@@ -792,6 +822,7 @@ AC_DEFUN(DEAL_II_THREAD_CPPFLAGS, dnl
 [
   AC_MSG_CHECKING(for platform specific multi-threading defines)
   AC_LANG(C++)
+  CXXFLAGS="$CXXFLAGSG"
   AC_TRY_COMPILE(
    [
 #       if !defined (_REENTRANT) && !defined (_THREAD_SAFE)
@@ -958,8 +989,8 @@ AC_DEFUN(DEAL_II_CHECK_PARTLY_BRACKETED_INITIALIZER, dnl
     case "$GXX_VERSION" in
       gcc*)
        AC_MSG_CHECKING(for only partly bracketed mutex initializer)
-       CXXFLAGS="$CXXFLAGSG -Werror"
        AC_LANG(C++)
+       CXXFLAGS="$CXXFLAGSG -Werror"
        AC_TRY_COMPILE(
        [
 #      include <vector>
@@ -1041,6 +1072,7 @@ AC_DEFUN(DEAL_II_CHECK_POSIX_THREAD_FUNCTIONS, dnl
 [
   AC_MSG_CHECKING(for posix thread functions)
   AC_LANG(C++)
+  CXXFLAGS="$CXXFLAGSG"
   AC_TRY_COMPILE(
    [
 #      include <pthread.h>
@@ -1245,6 +1277,7 @@ AC_DEFUN(DEAL_II_CHECK_GETRUSAGE, dnl
 [
   AC_MSG_CHECKING(whether getrusage is properly declared)
   AC_LANG(C++)
+  CXXFLAGS="$CXXFLAGSG"
   AC_TRY_COMPILE(
     [
 #include <sys/resource.h>
@@ -1412,9 +1445,9 @@ dnl
 dnl -------------------------------------------------------------
 AC_DEFUN(DEAL_II_CHECK_RAND_R, dnl
 [
+  AC_MSG_CHECKING(for rand_r)
   AC_LANG(C++)
   CXXFLAGS=$CXXFLAGSG
-  AC_MSG_CHECKING(for rand_r)
   AC_TRY_COMPILE(
        [
 #include <cstdlib>
@@ -1811,7 +1844,7 @@ dnl
 dnl -------------------------------------------------------------
 AC_DEFUN(DEAL_II_CHECK_NAMESP_TEMPL_FRIEND_BUG, dnl
 [
-  AC_MSG_CHECKING(for template friend in namespace bug)
+  AC_MSG_CHECKING(for 1st template friend in namespace bug)
   AC_LANG(C++)
   CXXFLAGS="$CXXFLAGSG"
   AC_TRY_COMPILE(
@@ -1856,6 +1889,70 @@ AC_DEFUN(DEAL_II_CHECK_NAMESP_TEMPL_FRIEND_BUG, dnl
 
 
 
+dnl -------------------------------------------------------------
+dnl Another bug in gcc with template and namespaces (fixed since 3.2, 
+dnl but present in 3.0):
+dnl 
+dnl /* ----------------------------------------------- */
+dnl namespace NS {
+dnl   template <typename> struct Foo;
+dnl }
+dnl 
+dnl class Bar {
+dnl     template <typename Y> friend struct NS::Foo;
+dnl };
+dnl 
+dnl namespace NS {
+dnl   template <typename> struct Foo { Foo (); };
+dnl }
+dnl 
+dnl template struct NS::Foo<int>;
+dnl /* ----------------------------------------------- */
+dnl
+dnl gcc2.95 provides a really unhelpful error message, 3.0 gets an
+dnl internal compiler error.
+dnl
+dnl Usage: DEAL_II_CHECK_NAMESP_TEMPL_FRIEND_BUG2
+dnl
+dnl -------------------------------------------------------------
+AC_DEFUN(DEAL_II_CHECK_NAMESP_TEMPL_FRIEND_BUG2, dnl
+[
+  AC_MSG_CHECKING(for 2nd template friend in namespace bug)
+  AC_LANG(C++)
+  CXXFLAGS="$CXXFLAGSG -Werror"
+  AC_TRY_COMPILE(
+    [
+       namespace NS {
+         template <typename> struct Foo;
+       }
+
+       class Bar {
+           template <typename Y> friend struct NS::Foo;
+       };
+
+       namespace NS {
+         template <typename> struct Foo { Foo (); };
+       }
+
+       template struct NS::Foo<int>;
+    ],
+    [],
+    [
+      AC_MSG_RESULT(no)
+    ],
+    [
+      AC_MSG_RESULT(yes. using workaround)
+      AC_DEFINE_UNQUOTED(DEAL_II_NAMESP_TEMPL_FRIEND_BUG2, 1, 
+                         [Define if we have to work around another bug in gcc with
+                          marking all instances of a template class as friends
+                         to this class if the class is inside a namespace.
+                          See the aclocal.m4 file in the top-level directory
+                          for a description of this bug.])
+    ])
+])
+
+
+
 dnl -------------------------------------------------------------
 dnl In some cases, we would like to name partial specializations
 dnl as friends. However, the standard forbids us to do so. But
@@ -2304,6 +2401,48 @@ AC_DEFUN(DEAL_II_CHECK_LONG_DOUBLE_LOOP_BUG, dnl
 
 
 
+dnl -------------------------------------------------------------
+dnl The boost::shared_ptr class has a templated assignment operator
+dnl but no assignment operator matching the default operator
+dnl signature (this if for boost 1.29 at least). So when using
+dnl using a normal assignment between identical types, the
+dnl compiler synthesizes teh default operator, rather than using
+dnl the template. It doesn't matter here, but is probably an
+dnl oversight on behalf of the operators.
+dnl
+dnl With -Wsynth in gcc we then get a warning. So if we find that
+dnl this is still the case, disable -Wsynth, i.e. remove it from
+dnl the list of warning flags.
+dnl
+dnl Usage: DEAL_II_CHECK_BOOST_SHARED_PTR_ASSIGNMENT
+dnl
+dnl -------------------------------------------------------------
+AC_DEFUN(DEAL_II_CHECK_BOOST_SHARED_PTR_ASSIGNMENT, dnl
+[
+  if test "x$GXX_VERSION" != "x" ; then
+    AC_MSG_CHECKING(for boost::shared_ptr assignment operator= template buglet)
+    AC_LANG(C++)
+    CXXFLAGS="-Wsynth -Werror -I `pwd`/contrib/boost/include"
+    AC_TRY_COMPILE(
+      [
+#       include <boost_local/shared_ptr.hpp>
+      ],
+      [
+        boost::shared_ptr<int> a,b;
+        a = b;
+      ],
+      [
+        AC_MSG_RESULT(no)
+      ],
+      [
+        AC_MSG_RESULT(yes)
+       CXXFLAGSG="`echo $CXXFLAGSG | perl -pi -e 's/-Wsynth\s*//g;'`"
+      ])
+  fi
+])
+
+
+
 dnl -------------------------------------------------------------
 dnl gcc2.95 doesn't have the std::iterator class, but the standard
 dnl requires it, so check whether we have to work around it
@@ -2472,9 +2611,9 @@ dnl Usage: DEAL_II_CHECK_ADVANCE_WARNING
 dnl -------------------------------------------------------------
 AC_DEFUN(DEAL_II_CHECK_ADVANCE_WARNING, dnl
 [
+  AC_MSG_CHECKING(for std::advance warning)
   AC_LANG(C++)
   CXXFLAGS="$CXXFLAGSG -Werror"
-  AC_MSG_CHECKING(for std::advance warning)
   AC_TRY_COMPILE(
        [
 #include <map>
@@ -2760,9 +2899,9 @@ dnl
 dnl -------------------------------------------------------------
 AC_DEFUN(DEAL_II_CHECK_CXXFLAGS_CONSISTENCY, dnl
 [
+  AC_MSG_CHECKING(for consistency of CXXFLAGSG flags)
   AC_LANG(C++)
   CXXFLAGS="$CXXFLAGSG"
-  AC_MSG_CHECKING(for consistency of CXXFLAGSG flags)
   AC_TRY_COMPILE(
     [],
     [;],
@@ -2774,8 +2913,8 @@ AC_DEFUN(DEAL_II_CHECK_CXXFLAGS_CONSISTENCY, dnl
       exit 1;
     ])
   
-  CXXFLAGS="$CXXFLAGSO"
   AC_MSG_CHECKING(for consistency of CXXFLAGSO flags)
+  CXXFLAGS="$CXXFLAGSO"
   AC_TRY_COMPILE(
     [],
     [;],
index fffe90e4528993a102437893da912803e7a6f07b..5402fdd1064060f86f5f8221bf6099db16dd1167 100644 (file)
    description of this bug. */
 #undef DEAL_II_NAMESP_TEMPL_FRIEND_BUG
 
+/* Define if we have to work around another bug in gcc with marking all
+   instances of a template class as friends to this class if the class is
+   inside a namespace. See the aclocal.m4 file in the top-level directory for
+   a description of this bug. */
+#undef DEAL_II_NAMESP_TEMPL_FRIEND_BUG2
+
 /* Defined if the compiler does not properly implement the resolution of
    defect report #45 to the C++ standard, which makes nested types implicit
    friends of the enclosing class. */
index 5d9eb31fd634a63e201bdffb6a0d613a31dd21a9..541c3cf7b08a5e74f853cccfeaefe7cb7fddd273 100644 (file)
 #include <base/config.h>
 #include <base/exceptions.h>
 
-#include <utility>
-#include <vector>
 #include <iterator>
+#include <vector>
+#include <utility>
+
+#include <list>
+#include <boost_local/type_traits.hpp>
+#include <boost_local/tuple/tuple.hpp>
+#include <boost_local/shared_ptr.hpp>
 
 #if DEAL_II_USE_MT == 1
 #  if defined(DEAL_II_USE_MT_POSIX)
@@ -32,9 +37,6 @@
 
 namespace Threads 
 {
-                                  // forward declarations
-  class FunDataBase;
-
 /**
  * This class is used instead of a true lock class when not using
  * multithreading. It allows to write programs such that they start
@@ -184,54 +186,6 @@ namespace Threads
                                        */
       inline void wait (DummyThreadMutex &) {};
   };
-  
-/**
- * This class is used instead of a true thread manager class when not
- * using multithreading. It allows to write programs such that they
- * start new threads and/or lock objects in multithreading mode, and
- * use dummy thread management and synchronisation classes instead
- * when running in single-thread mode. Specifically, the @p{spawn}
- * functions only call the function but wait for it to return instead
- * of running in on another thread, and the mutices do nothing
- * really. The only reason to provide such a function is that the
- * program can be compiled both in MT and non-MT mode without
- * difference.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  class DummyThreadManager 
-  {
-    public:
-                                      /**
-                                       * Typedef for a global
-                                       * function that might be
-                                       * called on a new thread.
-                                       */
-      typedef void * (*FunPtr) (void *);
-
-                                      /**
-                                       * Emulate spawning a new
-                                       * thread and calling the
-                                       * passed function
-                                       * thereon. Actually only call
-                                       * that function with the given
-                                       * parameters, and wait for it
-                                       * to return.
-                                       */
-      void spawn (const FunPtr fun_ptr,
-                 void *       fun_data,
-                 int          flags) const;
-
-                                      /**
-                                       * Emulate that we wait for
-                                       * other threads to
-                                       * return. Since no other
-                                       * threads have been started,
-                                       * the right thing, of course,
-                                       * is to return immediately.
-                                       */
-      inline void wait () const {};
-  };
 
 
   
@@ -546,85 +500,14 @@ namespace Threads
   };
 
 
-  class PosixThreadManager 
-  {
-    public:
-                                      /**
-                                       * Typedef for a global
-                                       * function that might be
-                                       * called on a new thread.
-                                       */
-      typedef void * (*FunPtr) (void *);
-
-                                      /**
-                                       * Constructor. Initialize data
-                                       * structures.
-                                       */
-      PosixThreadManager ();
-
-                                      /**
-                                       * Destructor. Wait for all
-                                       * spawned threads if they have
-                                       * not yet finished, and
-                                       * release the resources of
-                                       * this object.
-                                       */
-      ~PosixThreadManager ();
-      
-                                      /**
-                                       * Spawn a new thread and
-                                       * calling the passed function
-                                       * thereon. Store the
-                                       * identifier of the thread for
-                                       * later operations as waiting
-                                       * for that thread.
-                                       *
-                                       * The @p{flags} argument is
-                                       * currently ignored.
-                                       */
-      void spawn (const FunPtr fun_ptr,
-                 void *       fun_data,
-                 int          flags);
-
-                                      /**
-                                       * Wait for all spawned threads
-                                       * to return.
-                                       */
-      void wait () const;
-
-    private:
-                                      /**
-                                       * Copy constructor. Made
-                                       * private since copying these
-                                       * kinds of objects is a no-go.
-                                       */
-      PosixThreadManager (const PosixThreadManager &) {};
-      
-                                      /**
-                                       * List of thread ids. This
-                                       * variable actually points to
-                                       * an object of type
-                                       * @p{std::list<pthread_t>},
-                                       * but to avoid including
-                                       * @p{<list>} into this central
-                                       * header file and all other
-                                       * files including it, we use a
-                                       * void pointer instead.
-                                       */
-      void * const thread_id_list;
-
-                                      /**
-                                       * Mutex by which we guard all
-                                       * accesses to the thread list.
-                                       */
-      mutable PosixThreadMutex list_mutex;
-  };
-  
-  
-  
+                                   /**
+                                    * If using POSIX functions, then
+                                    * alias the POSIX wrapper classes
+                                    * to the names we use throughout
+                                    * the library.
+                                    */
   typedef PosixThreadMutex     ThreadMutex;
   typedef PosixThreadCondition ThreadCondition;  
-  typedef PosixThreadManager   ThreadManager;
   typedef PosixThreadBarrier   Barrier;
 
 #  else
@@ -637,7952 +520,6006 @@ namespace Threads
                                    * classes are aliased to dummy
                                    * classes that actually do
                                    * nothing, in particular not lock
-                                   * objects or start new
-                                   * threads. Likewise for the
+                                   * objects. Likewise for the
                                    * barrier class.
                                    */
   typedef DummyThreadMutex     ThreadMutex;
   typedef DummyThreadCondition ThreadCondition;  
-  typedef DummyThreadManager   ThreadManager;
   typedef DummyBarrier         Barrier;
 #endif
+  
+}
 
 
+namespace Threads
+{
 
-                                  /**
-                                   * Given a class, argument type,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class RetType>
-  struct MemFunPtr0
-  {
-      typedef RetType (Class::*type) ();
-  };
+                                   /**
+                                    * Return the number of presently
+                                    * existing threads. This function
+                                    * may be useful in a situation
+                                    * where a large number of threads
+                                    * are concurrently, and you want
+                                    * to decide whether creation of
+                                    * another thread is reasonable or
+                                    * whether running the respective
+                                    * operation sequentially is more
+                                    * useful since already many more
+                                    * threads than processors are
+                                    * running.
+                                    *
+                                    * Note that the function returns
+                                    * the total number of threads, not
+                                    * those actually running. Some of
+                                    * the threads may be waiting for
+                                    * locks and mutexes, or may be
+                                    * sleeping until they are
+                                    * delivered with data to work on.
+                                    * 
+                                    * Upon program start, this number
+                                    * is one. It is increased each
+                                    * time a thread is created using
+                                    * the @ref{Threads::spawn} or
+                                    * @ref{Threads::spawn_n}
+                                    * functions. It is decreased once
+                                    * a thread terminates by returning
+                                    * from the function that was
+                                    * spawned.
+                                    *
+                                    * Note that this means that only
+                                    * threads created and terminated
+                                    * through the interfaces of this
+                                    * namespace are taken care of. If
+                                    * threads are created by directly
+                                    * calling the respective functions
+                                    * of the operating system
+                                    * (e.g. @p{pthread_create} for the
+                                    * POSIX thread interface), or if
+                                    * they are killed (e.g. either
+                                    * through @p{pthread_exit} from
+                                    * the spawned thread, or
+                                    * @p{pthread_kill} from another
+                                    * thread), then these events are
+                                    * not registered and counted for
+                                    * the result of this function.
+                                    */
+  unsigned int n_existing_threads ();
 
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class RetType>
-  struct MemFunPtr0<const Class, RetType>
-  {
-      typedef RetType (Class::*type) () const;
-  };
-#endif  
                                   /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
+                                   * Split the range @p{[begin,end)}
+                                   * into @p{n_intervals} subintervals
+                                   * of equal size. The last interval
+                                   * will be a little bit larger, if
+                                   * the number of elements in the
+                                   * whole range is not exactly
+                                   * divisible by @p{n_intervals}. The
+                                   * type of the iterators has to
+                                   * fulfill the requirements of a
+                                   * forward iterator,
+                                   * i.e. @p{operator++} must be
+                                   * available, and of course it must
+                                   * be assignable.
+                                   *
+                                   * A list of subintervals is
+                                   * returned as a vector of pairs of
+                                   * iterators, where each pair
+                                   * denotes the range
+                                   * @p{[begin[i],end[i])}.
                                    */
-  template <class Class, class Arg1, class RetType>
-  struct MemFunPtr1
-  {
-      typedef RetType (Class::*type) (Arg1);
-  };
+  template <typename ForwardIterator>
+  std::vector<std::pair<ForwardIterator,ForwardIterator> >
+  split_range (const ForwardIterator &begin,
+              const ForwardIterator &end,
+              const unsigned int n_intervals);
 
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class RetType>
-  struct MemFunPtr1<const Class, Arg1, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1) const;
-  };
-#endif  
                                   /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
+                                   * Split the interval @p{[begin,end)}
+                                   * into subintervals of (almost)
+                                   * equal size. This function works
+                                   * mostly as the one before, with
+                                   * the difference that instead of
+                                   * iterators, now values are taken
+                                   * that define the whole interval.
                                    */
-  template <class Class, class Arg1, class Arg2, class RetType>
-  struct MemFunPtr2
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2);
-  };
+  std::vector<std::pair<unsigned int,unsigned int> >
+  split_interval (const unsigned int begin,
+                 const unsigned int end,
+                 const unsigned int n_intervals);
 
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class RetType>
-  struct MemFunPtr2<const Class, Arg1, Arg2, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2) const;
-  };
-#endif  
+                                   /**
+                                    * A namespace in which helper
+                                    * functions and the like for the
+                                    * threading subsystem are
+                                    * implemented. The members of this
+                                    * namespace are not meant for
+                                    * public use.
+                                    *
+                                    * The classes inside this
+                                    * namespace are suppressed by the
+                                    * documentation script in the
+                                    * class overview table, to keep it
+                                    * short.
+                                    * 
+                                    * @author Wolfgang Bangerth, 2003
+                                    */
+  namespace internal
+  {
+                                     /**
+                                      * If in a sub-thread an
+                                      * exception is thrown, it is not
+                                      * propagated to the main
+                                      * thread. Therefore, the
+                                      * exception handler that is
+                                      * provided by the applications
+                                      * main function or some of its
+                                      * other parts will not be able
+                                      * to catch these
+                                      * exceptions. Therefore, we have
+                                      * to provide an exception
+                                      * handler in the top function of
+                                      * each sub-thread that at least
+                                      * catches the exception and
+                                      * prints some information,
+                                      * rather than letting the
+                                      * operating system to just kill
+                                      * the program without a
+                                      * message. In each of the
+                                      * functions we use as entry
+                                      * points to new threads, we
+                                      * therefore install a try-catch
+                                      * block, and if an exception of
+                                      * type @p{std::exception} is
+                                      * caught, it passes over control
+                                      * to this function, which will
+                                      * then provide some output.
+                                      */
+    void handle_std_exception (const std::exception &exc);
+
+                                     /**
+                                      * Same as above, but the type of
+                                      * the exception is not derived
+                                      * from @p{std::exception}, so
+                                      * there is little way to provide
+                                      * something more useful.
+                                      */
+    void handle_unknown_exception ();
+
+                                     /**
+                                      * The following function is used
+                                      * for internal bookkeeping of the
+                                      * number of existing threads. It
+                                      * is not thought for use in
+                                      * application programs, but only
+                                      * for use in the template
+                                      * functions below.
+                                      */
+    void register_thread ();
+  
+                                     /**
+                                      * The following function is used
+                                      * for internal bookkeeping of the
+                                      * number of existing threads. It
+                                      * is not thought for use in
+                                      * application programs, but only
+                                      * for use in the template
+                                      * functions below.
+                                      */
+    void deregister_thread ();  
+  }
+  
+}   // end declarations of namespace Threads
 
-                                  /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class RetType>
-  struct MemFunPtr3
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3);
-  };
 
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class RetType>
-  struct MemFunPtr3<const Class, Arg1, Arg2, Arg3, RetType>
+/* ----------- implementation of functions in namespace Threads ---------- */
+namespace Threads 
+{  
+  template <typename ForwardIterator>
+  std::vector<std::pair<ForwardIterator,ForwardIterator> >
+  split_range (const ForwardIterator &begin,
+              const ForwardIterator &end,
+              const unsigned int     n_intervals)
   {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3) const;
-  };
-#endif  
+    typedef std::pair<ForwardIterator,ForwardIterator> IteratorPair;
 
-                                  /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class RetType>
-  struct MemFunPtr4
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4);
-  };
+                                    // in non-multithreaded mode, we
+                                    // often have the case that this
+                                    // function is called with
+                                    // n_intervals==1, so have a
+                                    // shortcut here to handle that
+                                    // case efficiently
+    
+    if (n_intervals==1)
+      return (std::vector<IteratorPair>
+             (1, IteratorPair(begin, end)));
+    
+                                    // if more than one interval
+                                    // requested, do the full work
+    const unsigned int n_elements              = distance (begin, end);
+    const unsigned int n_elements_per_interval = n_elements / n_intervals;
+    const unsigned int residual                = n_elements % n_intervals;
+    
+    std::vector<IteratorPair> return_values (n_intervals);
 
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class RetType>
-  struct MemFunPtr4<const Class, Arg1, Arg2, Arg3, Arg4, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4) const;
-  };
-#endif  
+    return_values[0].first = begin;
+    for (unsigned int i=0; i<n_intervals; ++i)
+      {
+       if (i != n_intervals-1) 
+         {
+           return_values[i].second = return_values[i].first;
+                                            // note: the cast is
+                                            // performed to avoid a
+                                            // warning of gcc that in
+                                            // the library `dist>=0'
+                                            // is checked (dist has a
+                                            // template type, which
+                                            // here is unsigned if no
+                                            // cast is performed)
+           std::advance (return_values[i].second,
+                         static_cast<signed int>(n_elements_per_interval));
+                                            // distribute residual in
+                                            // division equally among
+                                            // the first few
+                                            // subintervals
+           if (i < residual)
+             ++return_values[i].second;
+           
+           return_values[i+1].first = return_values[i].second;
+         }
+       else
+         return_values[i].second = end;
+      }
+    return return_values;
+  }  
 
-                                  /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class RetType>
-  struct MemFunPtr5
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5);
-  };
 
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class RetType>
-  struct MemFunPtr5<const Class, Arg1, Arg2, Arg3, Arg4, Arg5, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5) const;
-  };
-#endif  
+  namespace internal 
+  {
+                                     /**
+                                      * A type that is used to
+                                      * distinguish argument lists of
+                                      * functions by enumeration.
+                                      */
+    template <int> struct int2type
+    {
+    };
+  } 
+
+
+  namespace internal 
+  {
+                                     /**
+                                      * Given an arbitrary type RT,
+                                      * store an element of it and grant
+                                      * access to it through functions
+                                      * get() and set(). There are
+                                      * specializations for reference
+                                      * types (which cannot be set), and
+                                      * for type void.
+                                      */
+    template <typename RT> struct return_value
+    {
+      private:
+        RT value;
+      public:
+        inline return_value () : value() {}
+      
+        inline RT get () const { return value; }
+        inline void set (RT v) { value = v; }
+    };
+
+  
+                                     /**
+                                      * Given an arbitrary type RT,
+                                      * store an element of it and grant
+                                      * access to it through functions
+                                      * get() and set(). This is the
+                                      * specialization for reference
+                                      * types: since they cannot be set
+                                      * after construction time, we
+                                      * store a pointer instead, that
+                                      * holds the address of the object
+                                      * being referenced.
+                                      */
+    template <typename RT> struct return_value<RT &>
+    {
+      private:
+        RT * value;
+      public:
+        inline return_value () : value(0) {}
+
+        inline RT & get () const { return *value; }
+        inline void set (RT & v) { value = &v; }
+    };
+
+  
+                                     /**
+                                      * Given an arbitrary type RT,
+                                      * store an element of it and grant
+                                      * access to it through functions
+                                      * get() and set(). This is the
+                                      * specialization for type void:
+                                      * there is obviously nothing to
+                                      * store, so no function set(), and
+                                      * a function get() that returns
+                                      * void.
+                                      */
+    template <> struct return_value<void> {
+        static inline void get () {}
+    };
+  }
 
-                                  /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class RetType>
-  struct MemFunPtr6
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
-  };
+  
 
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class RetType>
-  struct MemFunPtr6<const Class, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const;
-  };
-#endif  
+  namespace internal
+  {
+                                     /**
+                                      * Call arbitrary functions with
+                                      * return type RT. For each number
+                                      * of arguments to these functions,
+                                      * there is an instance of the
+                                      * do_call function in this class
+                                      * that unpacks the argument list
+                                      * (which is passed by reference)
+                                      * and calls the function. The
+                                      * number of arguments is
+                                      * distinguished by the last
+                                      * argument. The return value
+                                      * object is the second last. A
+                                      * second version of the do_call
+                                      * function is used to call member
+                                      * function pointers, in which case
+                                      * there is an additional argument
+                                      * at second position holding a
+                                      * reference to the object with
+                                      * which the member function
+                                      * pointer is to be called.
+                                      *
+                                      * There is a specialization of
+                                      * this class for the case that the
+                                      * return type is void, in which
+                                      * case there is no return value to
+                                      * be set.
+                                      */
+    template <typename RT>
+    struct Caller 
+    {
+                                         /**
+                                          * Call a function with 0
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<0> &)
+          {
+            ret_val.set ((*fun_ptr) ());
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 0 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<0> &)
+          {
+            ret_val.set ((obj.*fun_ptr) ());
+          }
+
+
+                                         /**
+                                          * Call a function with 1
+                                          * argument, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<1> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 1 argument, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<1> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>()));
+          }
+
+
+
+
+                                         /**
+                                          * Call a function with 2
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<2> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 2 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<2> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>()));
+          }
+
+
+                                         /**
+                                          * Call a function with 3
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<3> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>(),
+                                     arg_list.template get<2>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 3 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<3> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>(),
+                                         arg_list.template get<2>()));
+          }
+
+
+                                         /**
+                                          * Call a function with 4
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<4> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>(),
+                                     arg_list.template get<2>(),
+                                     arg_list.template get<3>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 4 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<4> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>(),
+                                         arg_list.template get<2>(),
+                                         arg_list.template get<3>()));
+          }
+
+
+                                         /**
+                                          * Call a function with 5
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<5> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>(),
+                                     arg_list.template get<2>(),
+                                     arg_list.template get<3>(),
+                                     arg_list.template get<4>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 5 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<5> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>(),
+                                         arg_list.template get<2>(),
+                                         arg_list.template get<3>(),
+                                         arg_list.template get<4>()));
+          }
+
+
+                                         /**
+                                          * Call a function with 6
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<6> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>(),
+                                     arg_list.template get<2>(),
+                                     arg_list.template get<3>(),
+                                     arg_list.template get<4>(),
+                                     arg_list.template get<5>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 6 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<6> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>(),
+                                         arg_list.template get<2>(),
+                                         arg_list.template get<3>(),
+                                         arg_list.template get<4>(),
+                                         arg_list.template get<5>()));
+          }
+
+
+                                         /**
+                                          * Call a function with 7
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<7> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>(),
+                                     arg_list.template get<2>(),
+                                     arg_list.template get<3>(),
+                                     arg_list.template get<4>(),
+                                     arg_list.template get<5>(),
+                                     arg_list.template get<6>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 7 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<7> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>(),
+                                         arg_list.template get<2>(),
+                                         arg_list.template get<3>(),
+                                         arg_list.template get<4>(),
+                                         arg_list.template get<5>(),
+                                         arg_list.template get<6>()));
+          }
+
+
+                                         /**
+                                          * Call a function with 8
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<8> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>(),
+                                     arg_list.template get<2>(),
+                                     arg_list.template get<3>(),
+                                     arg_list.template get<4>(),
+                                     arg_list.template get<5>(),
+                                     arg_list.template get<6>(),
+                                     arg_list.template get<7>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 8 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<8> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>(),
+                                         arg_list.template get<2>(),
+                                         arg_list.template get<3>(),
+                                         arg_list.template get<4>(),
+                                         arg_list.template get<5>(),
+                                         arg_list.template get<6>(),
+                                         arg_list.template get<7>()));
+          }
+
+
+                                         /**
+                                          * Call a function with 9
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<9> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>(),
+                                     arg_list.template get<2>(),
+                                     arg_list.template get<3>(),
+                                     arg_list.template get<4>(),
+                                     arg_list.template get<5>(),
+                                     arg_list.template get<6>(),
+                                     arg_list.template get<7>(),
+                                     arg_list.template get<8>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 9 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<9> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>(),
+                                         arg_list.template get<2>(),
+                                         arg_list.template get<3>(),
+                                         arg_list.template get<4>(),
+                                         arg_list.template get<5>(),
+                                         arg_list.template get<6>(),
+                                         arg_list.template get<7>(),
+                                         arg_list.template get<8>()));
+          }
+
+
+                                         /**
+                                          * Call a function with 10
+                                          * arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<10> &)
+          {
+            ret_val.set ((*fun_ptr) (arg_list.template get<0>(),
+                                     arg_list.template get<1>(),
+                                     arg_list.template get<2>(),
+                                     arg_list.template get<3>(),
+                                     arg_list.template get<4>(),
+                                     arg_list.template get<5>(),
+                                     arg_list.template get<6>(),
+                                     arg_list.template get<7>(),
+                                     arg_list.template get<8>(),
+                                     arg_list.template get<9>()));
+          }
+
+                                         /**
+                                          * Call a member function with
+                                          * 10 arguments, and set the
+                                          * return value.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<RT> &ret_val,
+                                    const int2type<10> &)
+          {
+            ret_val.set ((obj.*fun_ptr) (arg_list.template get<0>(),
+                                         arg_list.template get<1>(),
+                                         arg_list.template get<2>(),
+                                         arg_list.template get<3>(),
+                                         arg_list.template get<4>(),
+                                         arg_list.template get<5>(),
+                                         arg_list.template get<6>(),
+                                         arg_list.template get<7>(),
+                                         arg_list.template get<8>(),
+                                         arg_list.template get<9>()));
+          }
+    };
+
+
+
+  
+                                     /**
+                                      * Call arbitrary functions with
+                                      * void return type. For each
+                                      * number of arguments to these
+                                      * functions, there is an instance
+                                      * of the do_call function in this
+                                      * class that unpacks the argument
+                                      * list (which is passed by
+                                      * reference) and calls the
+                                      * function. The number of
+                                      * arguments is distinguished by
+                                      * the last argument. The return
+                                      * value object is the second last,
+                                      * but since the return type is
+                                      * void, this is of course simply
+                                      * ignored. A second version of the
+                                      * do_call function is used to call
+                                      * member function pointers, in
+                                      * which case there is an
+                                      * additional argument at second
+                                      * position holding a reference to
+                                      * the object with which the member
+                                      * function pointer is to be
+                                      * called.
+                                      */
+    template <>
+    struct Caller<void>
+    {
+                                         /**
+                                          * Call a void function with 0
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &,
+                                    internal::return_value<void> &,
+                                    const int2type<0> &)
+          {
+            (*fun_ptr) ();
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 0 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &,
+                                    internal::return_value<void> &,
+                                    const int2type<0> &)
+          {
+            (obj.*fun_ptr) ();
+          }
+
+
+                                         /**
+                                          * Call a void function with 1
+                                          * argument.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<1> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 1 argument.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<1> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>());
+          }
+
+
+
+
+                                         /**
+                                          * Call a void function with 2
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<2> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 2 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<2> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>());
+          }
+
+
+                                         /**
+                                          * Call a void function with 3
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<3> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>(),
+                        arg_list.template get<2>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 3 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<3> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>(),
+                            arg_list.template get<2>());
+          }
+
+
+                                         /**
+                                          * Call a void function with 4
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<4> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>(),
+                        arg_list.template get<2>(),
+                        arg_list.template get<3>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 4 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<4> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>(),
+                            arg_list.template get<2>(),
+                            arg_list.template get<3>());
+          }
+
+
+                                         /**
+                                          * Call a void function with 5
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<5> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>(),
+                        arg_list.template get<2>(),
+                        arg_list.template get<3>(),
+                        arg_list.template get<4>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 5 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<5> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>(),
+                            arg_list.template get<2>(),
+                            arg_list.template get<3>(),
+                            arg_list.template get<4>());
+          }
+
+
+                                         /**
+                                          * Call a void function with 6
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<6> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>(),
+                        arg_list.template get<2>(),
+                        arg_list.template get<3>(),
+                        arg_list.template get<4>(),
+                        arg_list.template get<5>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 6 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<6> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>(),
+                            arg_list.template get<2>(),
+                            arg_list.template get<3>(),
+                            arg_list.template get<4>(),
+                            arg_list.template get<5>());
+          }
+
+
+                                         /**
+                                          * Call a void function with 7
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<7> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>(),
+                        arg_list.template get<2>(),
+                        arg_list.template get<3>(),
+                        arg_list.template get<4>(),
+                        arg_list.template get<5>(),
+                        arg_list.template get<6>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 7 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<7> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>(),
+                            arg_list.template get<2>(),
+                            arg_list.template get<3>(),
+                            arg_list.template get<4>(),
+                            arg_list.template get<5>(),
+                            arg_list.template get<6>());
+          }
+
+
+                                         /**
+                                          * Call a void function with 8
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<8> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>(),
+                        arg_list.template get<2>(),
+                        arg_list.template get<3>(),
+                        arg_list.template get<4>(),
+                        arg_list.template get<5>(),
+                        arg_list.template get<6>(),
+                        arg_list.template get<7>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 8 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<8> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>(),
+                            arg_list.template get<2>(),
+                            arg_list.template get<3>(),
+                            arg_list.template get<4>(),
+                            arg_list.template get<5>(),
+                            arg_list.template get<6>(),
+                            arg_list.template get<7>());
+          }
+
+
+                                         /**
+                                          * Call a void function with 9
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<9> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>(),
+                        arg_list.template get<2>(),
+                        arg_list.template get<3>(),
+                        arg_list.template get<4>(),
+                        arg_list.template get<5>(),
+                        arg_list.template get<6>(),
+                        arg_list.template get<7>(),
+                        arg_list.template get<8>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 9 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<9> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>(),
+                            arg_list.template get<2>(),
+                            arg_list.template get<3>(),
+                            arg_list.template get<4>(),
+                            arg_list.template get<5>(),
+                            arg_list.template get<6>(),
+                            arg_list.template get<7>(),
+                            arg_list.template get<8>());
+          }
+
+
+                                         /**
+                                          * Call a void function with 10
+                                          * arguments.
+                                          */
+        template <typename PFun, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<10> &)
+          {
+            (*fun_ptr) (arg_list.template get<0>(),
+                        arg_list.template get<1>(),
+                        arg_list.template get<2>(),
+                        arg_list.template get<3>(),
+                        arg_list.template get<4>(),
+                        arg_list.template get<5>(),
+                        arg_list.template get<6>(),
+                        arg_list.template get<7>(),
+                        arg_list.template get<8>(),
+                        arg_list.template get<9>());
+          }
+
+                                         /**
+                                          * Call a void member function
+                                          * with 10 arguments.
+                                          */
+        template <typename PFun, typename C, typename ArgList>
+        static inline void do_call (PFun     fun_ptr,
+                                    C       &obj,
+                                    ArgList &arg_list,
+                                    internal::return_value<void> &,
+                                    const int2type<10> &)
+          {
+            (obj.*fun_ptr) (arg_list.template get<0>(),
+                            arg_list.template get<1>(),
+                            arg_list.template get<2>(),
+                            arg_list.template get<3>(),
+                            arg_list.template get<4>(),
+                            arg_list.template get<5>(),
+                            arg_list.template get<6>(),
+                            arg_list.template get<7>(),
+                            arg_list.template get<8>(),
+                            arg_list.template get<9>());
+          }
+    };
+  
+  
+
+                                     /**
+                                      * Call an arbitrary function by
+                                      * dispatching to the functions in
+                                      * the Caller class based on the
+                                      * number of elements in the
+                                      * argument list and the return
+                                      * type.
+                                      */
+    template <typename RT, typename PFun, typename ArgList>
+    static inline void call (PFun     fun_ptr,
+                             ArgList &arg_list,
+                             internal::return_value<RT> &ret_val)
+    {
+      Caller<RT>::do_call (fun_ptr, arg_list, ret_val,
+                           int2type<boost::tuples::length<ArgList>::value>());
+    }
+
+
+  
+                                     /**
+                                      * Call an arbitrary member
+                                      * function by dispatching to the
+                                      * functions in the Caller class
+                                      * based on the number of elements
+                                      * in the argument list and the
+                                      * return type.
+                                      */
+    template <typename RT, typename PFun, typename C, typename ArgList>
+    static inline void call (PFun     fun_ptr,
+                             C       &obj,
+                             ArgList &arg_list,
+                             internal::return_value<RT> &ret_val)
+    {
+      Caller<RT>::do_call (fun_ptr, obj, arg_list, ret_val,
+                           int2type<boost::tuples::length<ArgList>::value>());
+    }  
+  }
 
-                                  /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class RetType>
-  struct MemFunPtr7
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7);
-  };
-
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class RetType>
-  struct MemFunPtr7<const Class, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const;
-  };
-#endif  
 
 
-                                  /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class RetType>
-  struct MemFunPtr8
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
-  };
-
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class RetType>
-  struct MemFunPtr8<const Class, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) const;
-  };
-#endif  
+  namespace internal
+  {
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments, and whether the
+                                      * second argument is a const or
+                                      * non-const class, dependening on
+                                      * which the member function will
+                                      * also me const or
+                                      * non-const. There are
+                                      * specializations of this class
+                                      * for each number of arguments,
+                                      * and the const and non-const
+                                      * versions.
+                                      */
+    template <typename RT, class C, typename ArgList,
+              int length = boost::tuples::length<ArgList>::value>
+    struct mem_fun_ptr_helper;
+  
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 0 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 0>
+    {
+        typedef RT (C::*type) ();
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 0 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 0>
+    {
+        typedef RT (C::*type) () const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 1 argument
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 1>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 1 argument
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 1>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type) const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 2 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 2>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 2 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 2>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type) const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 3 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 3>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 3 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 3>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type) const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 4 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 4>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 4 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 4>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type) const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 5 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 5>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 5 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 5>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type) const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 6 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 6>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 6 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 6>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type) const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 7 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 7>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type,
+                               typename boost::tuples::element<6,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 7 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 7>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type,
+                               typename boost::tuples::element<6,ArgList>::type) const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 8 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 8>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type,
+                               typename boost::tuples::element<6,ArgList>::type,
+                               typename boost::tuples::element<7,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 8 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 8>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type,
+                               typename boost::tuples::element<6,ArgList>::type,
+                               typename boost::tuples::element<7,ArgList>::type) const;
+    };
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 9 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 9>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type,
+                               typename boost::tuples::element<6,ArgList>::type,
+                               typename boost::tuples::element<7,ArgList>::type,
+                               typename boost::tuples::element<8,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 9 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 9>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type,
+                               typename boost::tuples::element<6,ArgList>::type,
+                               typename boost::tuples::element<7,ArgList>::type,
+                               typename boost::tuples::element<8,ArgList>::type) const;
+    };
+
+
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 10 arguments
+                                      * and non-const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, C, ArgList, 10>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type,
+                               typename boost::tuples::element<6,ArgList>::type,
+                               typename boost::tuples::element<7,ArgList>::type,
+                               typename boost::tuples::element<8,ArgList>::type,
+                               typename boost::tuples::element<9,ArgList>::type);
+    };
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 10 arguments
+                                      * and const member functions.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr_helper<RT, const C, ArgList, 10>
+    {
+        typedef RT (C::*type) (typename boost::tuples::element<0,ArgList>::type,
+                               typename boost::tuples::element<1,ArgList>::type,
+                               typename boost::tuples::element<2,ArgList>::type,
+                               typename boost::tuples::element<3,ArgList>::type,
+                               typename boost::tuples::element<4,ArgList>::type,
+                               typename boost::tuples::element<5,ArgList>::type,
+                               typename boost::tuples::element<6,ArgList>::type,
+                               typename boost::tuples::element<7,ArgList>::type,
+                               typename boost::tuples::element<8,ArgList>::type,
+                               typename boost::tuples::element<9,ArgList>::type) const;
+    };
+
+  
+
+                                     /**
+                                      * Construct a pointer to member
+                                      * function based on the template
+                                      * arguments, and whether the
+                                      * second argument is a const or
+                                      * non-const class, dependening on
+                                      * which the member function will
+                                      * also me const or non-const. We
+                                      * do this by dispatching to the
+                                      * mem_fun_ptr_helper classes that
+                                      * are overloaded on the number of
+                                      * elements and the const/non-const
+                                      * decision.
+                                      *
+                                      * Note that the last template
+                                      * argument for the
+                                      * mem_fun_ptr_helper class is
+                                      * automatically computed in the
+                                      * default argument to the general
+                                      * template.
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_ptr
+    {
+        typedef typename mem_fun_ptr_helper<RT,C,ArgList>::type type;
+    };  
+  }
 
 
+  namespace internal
+  {
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments, and whether the
+                                      * second argument is a const or
+                                      * non-const class, dependening on
+                                      * which the member function will
+                                      * also me const or
+                                      * non-const. There are
+                                      * specializations of this class
+                                      * for each number of arguments.
+                                      */
+    template <typename RT, typename ArgList,
+              int length = boost::tuples::length<ArgList>::value>
+    struct fun_ptr_helper;
+  
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 0 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 0>
+    {
+        typedef RT (*type) ();
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 1 argument.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 1>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type);
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 2 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 2>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type);
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 3 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 3>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type,
+                            typename boost::tuples::element<2,ArgList>::type);
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 4 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 4>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type,
+                            typename boost::tuples::element<2,ArgList>::type,
+                            typename boost::tuples::element<3,ArgList>::type);
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 5 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 5>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type,
+                            typename boost::tuples::element<2,ArgList>::type,
+                            typename boost::tuples::element<3,ArgList>::type,
+                            typename boost::tuples::element<4,ArgList>::type);
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 6 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 6>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type,
+                            typename boost::tuples::element<2,ArgList>::type,
+                            typename boost::tuples::element<3,ArgList>::type,
+                            typename boost::tuples::element<4,ArgList>::type,
+                            typename boost::tuples::element<5,ArgList>::type);
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 7 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 7>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type,
+                            typename boost::tuples::element<2,ArgList>::type,
+                            typename boost::tuples::element<3,ArgList>::type,
+                            typename boost::tuples::element<4,ArgList>::type,
+                            typename boost::tuples::element<5,ArgList>::type,
+                            typename boost::tuples::element<6,ArgList>::type);
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 8 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 8>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type,
+                            typename boost::tuples::element<2,ArgList>::type,
+                            typename boost::tuples::element<3,ArgList>::type,
+                            typename boost::tuples::element<4,ArgList>::type,
+                            typename boost::tuples::element<5,ArgList>::type,
+                            typename boost::tuples::element<6,ArgList>::type,
+                            typename boost::tuples::element<7,ArgList>::type);
+    };
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 9 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 9>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type,
+                            typename boost::tuples::element<2,ArgList>::type,
+                            typename boost::tuples::element<3,ArgList>::type,
+                            typename boost::tuples::element<4,ArgList>::type,
+                            typename boost::tuples::element<5,ArgList>::type,
+                            typename boost::tuples::element<6,ArgList>::type,
+                            typename boost::tuples::element<7,ArgList>::type,
+                            typename boost::tuples::element<8,ArgList>::type);
+    };
+
+
+
+                                     /**
+                                      * Construct a pointer to non-member
+                                      * function based on the template
+                                      * arguments. This is the
+                                      * specialization for 10 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr_helper<RT, ArgList, 10>
+    {
+        typedef RT (*type) (typename boost::tuples::element<0,ArgList>::type,
+                            typename boost::tuples::element<1,ArgList>::type,
+                            typename boost::tuples::element<2,ArgList>::type,
+                            typename boost::tuples::element<3,ArgList>::type,
+                            typename boost::tuples::element<4,ArgList>::type,
+                            typename boost::tuples::element<5,ArgList>::type,
+                            typename boost::tuples::element<6,ArgList>::type,
+                            typename boost::tuples::element<7,ArgList>::type,
+                            typename boost::tuples::element<8,ArgList>::type,
+                            typename boost::tuples::element<9,ArgList>::type);
+    };
+
+  
+
+                                     /**
+                                      * Construct a pointer to
+                                      * non-member function based on the
+                                      * template arguments. We do this
+                                      * by dispatching to the
+                                      * fun_ptr_helper classes that are
+                                      * overloaded on the number of
+                                      * elements.
+                                      *
+                                      * Note that the last template
+                                      * argument for the
+                                      * fun_ptr_helper class is
+                                      * automatically computed in the
+                                      * default argument to the general
+                                      * template.
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_ptr
+    {
+        typedef typename fun_ptr_helper<RT,ArgList>::type type;
+    };  
+  }
 
-                                  /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9, class RetType>
-  struct MemFunPtr9
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
-  };
 
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9, class RetType>
-  struct MemFunPtr9<const Class, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) const;
-  };
-#endif  
+  namespace internal 
+  {
+                                     /**
+                                      * Extract the Nth element of the
+                                      * type list and make it a
+                                      * reference.
+                                      */
+    template <int N, typename Tuple>
+    struct add_reference_to_Nth
+    {
+        typedef typename boost::tuples::element<N,Tuple>::type ArgType;
+        typedef typename boost::add_reference<ArgType>::type type;
+    };
+  
+                                     /**
+                                      * Specializations of this template
+                                      * declare a typedef to a tuple
+                                      * type that has the same basic
+                                      * types as the first template
+                                      * argument, but all references
+                                      * instead of values. The second
+                                      * argument is used to distinguish
+                                      * between the lengths of argument
+                                      * lists. The default argument
+                                      * makes it possible to omit this
+                                      * length argument.
+                                      */
+    template <typename Tuple, int = boost::tuples::length<Tuple>::value>
+    struct tie_args_helper;
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 0.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,0>
+    {
+        typedef Tuple type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 1.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,1>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type>
+        type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 2.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,2>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type>
+        type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 3.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,3>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type,
+                     typename add_reference_to_Nth<2,Tuple>::type>
+        type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 4.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,4>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type,
+                     typename add_reference_to_Nth<2,Tuple>::type,
+                     typename add_reference_to_Nth<3,Tuple>::type>
+        type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 5.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,5>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type,
+                     typename add_reference_to_Nth<2,Tuple>::type,
+                     typename add_reference_to_Nth<3,Tuple>::type,
+                     typename add_reference_to_Nth<4,Tuple>::type>
+        type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 6.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,6>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type,
+                     typename add_reference_to_Nth<2,Tuple>::type,
+                     typename add_reference_to_Nth<3,Tuple>::type,
+                     typename add_reference_to_Nth<4,Tuple>::type,
+                     typename add_reference_to_Nth<5,Tuple>::type>
+        type;
+    };
+
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 7.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,7>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type,
+                     typename add_reference_to_Nth<2,Tuple>::type,
+                     typename add_reference_to_Nth<3,Tuple>::type,
+                     typename add_reference_to_Nth<4,Tuple>::type,
+                     typename add_reference_to_Nth<5,Tuple>::type,
+                     typename add_reference_to_Nth<6,Tuple>::type>
+        type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 8.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,8>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type,
+                     typename add_reference_to_Nth<2,Tuple>::type,
+                     typename add_reference_to_Nth<3,Tuple>::type,
+                     typename add_reference_to_Nth<4,Tuple>::type,
+                     typename add_reference_to_Nth<5,Tuple>::type,
+                     typename add_reference_to_Nth<6,Tuple>::type,
+                     typename add_reference_to_Nth<7,Tuple>::type>
+        type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 9.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,9>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type,
+                     typename add_reference_to_Nth<2,Tuple>::type,
+                     typename add_reference_to_Nth<3,Tuple>::type,
+                     typename add_reference_to_Nth<4,Tuple>::type,
+                     typename add_reference_to_Nth<5,Tuple>::type,
+                     typename add_reference_to_Nth<6,Tuple>::type,
+                     typename add_reference_to_Nth<7,Tuple>::type,
+                     typename add_reference_to_Nth<8,Tuple>::type>
+        type;
+    };
+
+
+                                     /**
+                                      * Make a tuple type of all
+                                      * references out of the given
+                                      * tuple. Specialization for tuple
+                                      * of length 10.
+                                      */
+    template <typename Tuple>
+    struct tie_args_helper<Tuple,10>
+    {
+        typedef 
+        boost::tuple<typename add_reference_to_Nth<0,Tuple>::type,
+                     typename add_reference_to_Nth<1,Tuple>::type,
+                     typename add_reference_to_Nth<2,Tuple>::type,
+                     typename add_reference_to_Nth<3,Tuple>::type,
+                     typename add_reference_to_Nth<4,Tuple>::type,
+                     typename add_reference_to_Nth<5,Tuple>::type,
+                     typename add_reference_to_Nth<6,Tuple>::type,
+                     typename add_reference_to_Nth<7,Tuple>::type,
+                     typename add_reference_to_Nth<8,Tuple>::type,
+                     typename add_reference_to_Nth<9,Tuple>::type>
+        type;
+    };
+
+
+  
+                                     /**
+                                      * Declare a typedef to a tuple
+                                      * type that has the same basic
+                                      * types as the template
+                                      * argument, but all references
+                                      * instead of values.
+                                      *
+                                      * Do so by redirecting to the
+                                      * tie_args_helper specializations;
+                                      * note that the second argument of
+                                      * these templates is computed
+                                      * automatically by the default
+                                      * argument specification.
+                                      */
+    template <typename Tuple>
+    struct tie_args 
+    {
+        typedef typename tie_args_helper<Tuple>::type type;
+    };
+  }
 
+#if (DEAL_II_USE_MT == 1)
+#  if defined(DEAL_II_USE_MT_POSIX)
   
+  namespace internal 
+  {
+                                     /**
+                                      * Base class describing a
+                                      * thread. This is the basic
+                                      * class abstracting the
+                                      * operating system's POSIX
+                                      * implementation into a C++
+                                      * class. It provides a mechanism
+                                      * to start a new thread, as well
+                                      * as for joining it.
+                                      *
+                                      * @author Wolfgang Bangerth, 2003
+                                      */
+    struct thread_description_base
+    {
+      private:
+                                         /**
+                                          * Variable holding the data
+                                          * the operating system needs
+                                          * to work with a thread.
+                                          */
+        pthread_t             thread;
+
+                                         /**
+                                          * Store whether the
+                                          * @p{join()} member function
+                                          * as already been called. If
+                                          * @p{true}, then @p{join}
+                                          * will return immediately,
+                                          * otherwise it needs to go
+                                          * through a call to the
+                                          * operating system.
+                                          *
+                                          * This class is generated
+                                          * exactly once per thread,
+                                          * but is kept in the
+                                          * background: user's should
+                                          * not directly access this
+                                          * class. Access to it is
+                                          * performed through counted
+                                          * pointers, both from
+                                          * @p{Thread<>} objects as
+                                          * well as from the thread
+                                          * entry point function on
+                                          * the new thread. It is only
+                                          * deleted when all users
+                                          * have freed it, which means
+                                          * that also the new thread
+                                          * has ended.
+                                          */
+        mutable volatile bool was_joined;
+
+                                         /**
+                                          * Mutex used to synchronise
+                                          * calls to the @p{join()}
+                                          * function.
+                                          */
+        mutable ThreadMutex   join_mutex;
+
+      public:
+
+                                         /**
+                                          * Constructor.
+                                          */
+        thread_description_base () : was_joined (false) {};
+
+                                         /**
+                                          * Destructor.
+                                          */
+        virtual ~thread_description_base ();
+
+                                         /**
+                                          * Create a new thread with
+                                          * the given thread entry
+                                          * point and arguments. Store
+                                          * the result of the
+                                          * operation in the
+                                          * @p{thread} member variable
+                                          * for further use.
+                                          */
+        void create (void * (*p) (void *), void *d);
+
+                                         /**
+                                          * Join a thread, i.e. wait
+                                          * for it to finish. This
+                                          * function can safely be
+                                          * called from different
+                                          * threads at the same time,
+                                          * and can also be called
+                                          * more than once.
+                                          */
+        void join () const;
+    };
+
+#  else       // some other threading model
+#    error Not Implemented
+#  endif     // defined(DEAL_II_USE_MT_POSIX)
+
+                                     /**
+                                      * Class derived from
+                                      * @ref{thread_description_base}
+                                      * that also provides the
+                                      * possibility to store a return
+                                      * value.
+                                      *
+                                      * @author Wolfgang Bangerth, 2003
+                                      */
+    template <typename RT>
+    struct thread_description : public thread_description_base
+    {
+        return_value<RT> ret_val;
+    };
+
+                                     // forward declare another class
+    template <typename> struct wrapper_base;
+  }
 
 
-                                  /**
-                                   * Given a class, argument types,
-                                   * and the return type, generate a
-                                   * local typedef denoting a pointer
-                                   * to such a member function.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9, class Arg10, class RetType>
-  struct MemFunPtr10
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10);
-  };
-
-#ifdef DEAL_II_CONST_MEM_FUN_PTR_BUG
-                                  /**
-                                   * Same as above, but for the case
-                                   * of a member function marked
-                                   * @p{const}. This should not
-                                   * really be necessary, but Intel's
-                                   * compiler has a bug here so we
-                                   * have to work around.
-                                   */
-  template <class Class, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9, class Arg10, class RetType>
-  struct MemFunPtr10<const Class, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10, RetType>
-  {
-      typedef RetType (Class::*type) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) const;
-  };
-#endif  
 
-  
-  
-/**
- * Class used to store a pointer temporarily and delete the object
- * pointed to upon destruction of this object. For more information on
- * use and internals of this class see the report on multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  class FunEncapsulation
+                                   /**
+                                    * User visible class describing a
+                                    * thread. Relays all real calls to
+                                    * the internal thread object
+                                    * abstracting the operating
+                                    * system's functions, to which it
+                                    * keeps a shared pointer. This
+                                    * object can be freely copied
+                                    * around in user space.
+                                    *
+                                    * The default value of the
+                                    * template argument is @p{void},
+                                    * so if the function you are
+                                    * calling on a new thread has no
+                                    * return value, you can omit the
+                                    * template argument.
+                                    * 
+                                    * @author Wolfgang Bangerth, 2003
+                                    */
+  template <typename RT = void>
+  class Thread
   {
-    private:
-                                      /**
-                                       * Default constructor. Construct
-                                       * the object empty, i.e. set
-                                       * @p{data==0}. Since this is not
-                                       * very useful, disallow it by
-                                       * declaring this constructor
-                                       * @p{private}.
-                                       */
-      FunEncapsulation ();
-
+                                       /**
+                                        * Construct a thread object
+                                        * with a pointer to an
+                                        * internal thread object. This
+                                        * is the constructor used to
+                                        * the @p{spawn} family of
+                                        * functions.
+                                        *
+                                        * We would like to make this
+                                        * constructor private and only
+                                        * grant the
+                                        * @p{wrapper_base::fire_up}
+                                        * function friendship, but
+                                        * granting friendship to
+                                        * functions in other
+                                        * namespaces doesn't work with
+                                        * some compilers, so only do
+                                        * so if the configure script
+                                        * decided that this is safe.
+                                        */
+#ifdef DEAL_II_NAMESP_TEMPL_FRIEND_BUG2
     public:
-                                      /**
-                                       * Copy constructor. Clone the
-                                       * object pointed to by
-                                       * @p{fun_data.fun_data_base}.
-                                       */
-      FunEncapsulation (const FunEncapsulation &fun_encapsulation);
-
-                                      /**
-                                       * This is the usual
-                                       * constructor. Set @p{fun_data_base} to
-                                       * @p{fun_data_base}. This is what
-                                       * the @p{fun_data_*} functions
-                                       * use.
-                                       */
-      FunEncapsulation (FunDataBase *fun_data_base);
-
-                                      /**
-                                       * Destructor. Delete the object
-                                       * pointed to by @p{fun_data_base}.
-                                       */
-      ~FunEncapsulation ();
-
-                                      /**
-                                       * Copy another object of this
-                                       * type by cloning its @p{fun_data_base}
-                                       * object.
-                                       */
-      const FunEncapsulation & operator = (const FunEncapsulation &fun_encapsulation);
-    
-                                      /**
-                                       * Pointer to the object which
-                                       * contains all the parameters.
-                                       */
-      const FunDataBase * fun_data_base;
-  };
-
-
+#endif
+      Thread (const boost::shared_ptr<internal::thread_description<RT> > &td)
+                      : thread_descriptor (td) {};
 
-/**
- * Abstract base class for those classes that actually store
- * parameters of functions. For more information on use and internals
- * of this class see the report on multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  class FunDataBase
-  {
     public:
-                                      /**
-                                       * Typedef a pointer to a
-                                       * function that satifies the
-                                       * requirements of thread entry
-                                       * points.
-                                       */
-      typedef void * (*ThreadEntryPoint) (void *);
-
-                                      /**
-                                       * Default constructor. Store the
-                                       * pointer to the function which
-                                       * we will use as thread entry
-                                       * point for the derived class.
-                                       */
-      FunDataBase (const ThreadEntryPoint thread_entry_point);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunDataBase (const FunDataBase &);
-
-                                      /**
-                                       * Destructor. Needs to be
-                                       * virtual to make destruction of
-                                       * derived classes through base
-                                       * class pointers.
-                                       */
-      virtual ~FunDataBase ();
-
-                                      /**
-                                       * Virtual constructor. Needed to
-                                       * copy an object of which we
-                                       * only have a pointer to the
-                                       * base class. Copying such
-                                       * objects is necessary to
-                                       * guarantee memory consistency.
-                                       */
-      virtual FunDataBase * clone () const = 0;
-
-                                      /**
-                                       * Lock to be used when starting
-                                       * a thread and which is released
-                                       * after the data of this object
-                                       * is copied and therefore no
-                                       * more needed. This ensures that
-                                       * no data is deleted when it is
-                                       * still in use.
-                                       */
-      mutable ThreadMutex lock;
-
+      
                                        /**
-                                        * A condition variable that is
-                                        * used for the same purpose.
+                                        * Default constructor. You
+                                        * can't do much with a thread
+                                        * object constructed this way,
+                                        * except for assigning it a
+                                        * thread object that holds
+                                        * data created by the
+                                        * @p{spawn} functions.
                                         */
-      mutable ThreadCondition condition;
-    
-    private:
-                                      /**
-                                       * Pointer to the thread entry
-                                       * point function. The address of
-                                       * that function is passed from
-                                       * the derived classes to the
-                                       * constructor of this class.
-                                       */
-      ThreadEntryPoint thread_entry_point;
-
-                                      /**
-                                       * Make the thread starter
-                                       * function a friend, since it
-                                       * needs to have access to the
-                                       * @p{thread_entry_point} variable.
-                                       */
-      friend void spawn (ThreadManager          &thread_manager,
-                        const FunEncapsulation &fun_data);
-  };
-
-
-
-/**
- * Class to store the parameters of a void function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename RetType>
-  class FunData0 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) ();
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData0 (FunPtr fun_ptr);
+      Thread () {};
 
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData0 (const FunData0 &fun_data0);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-
-//TODO:[WB] (compiler) with some compilers we get into trouble if the following class is not public, since we can't somehow declare the encapsulate function as friend. change this when compilers accept the friend declaration
-  public:
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData0<RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           *
-                                           * Since the function in
-                                           * question here does not
-                                           * take parameters, this
-                                           * function also does
-                                           * nothing. It is only
-                                           * present for
-                                           * orthogonality of thread
-                                           * creation.
-                                           */
-         FunEncapsulation collect_args ();
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
+                                       /**
+                                        * Join the thread represented
+                                        * by this object, i.e. wait
+                                        * for it to finish. You can't
+                                        * call this function if you
+                                        * have used the default
+                                        * constructor of this class
+                                        * and have not assigned a
+                                        * thread object to it.
+                                        */
+      void join () const {
+        AssertThrow (thread_descriptor, ExcNoThread());
+        thread_descriptor->join ();
       };
 
-// we should be declaring the following function friend, but gcc2.95
-// does not allow us to do that at present...
-//                                    /**
-//                                     * Declare a function that uses
-//                                     * the @ref{ArgCollector} as
-//                                     * friend.
-//                                     */
-//        friend
-//        FunData0<void>::ArgCollector
-//        encapsulate (void (*fun_ptr)());
-  };
-
-
-
-/**
- * Class to store the parameters of a unary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename Arg1, typename RetType>
-  class FunData1 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData1 (FunPtr fun_ptr,
-               Arg1   arg1);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData1 (const FunData1 &fun_data1);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData1<Arg1,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
+                                       /**
+                                        * Get the return value of the
+                                        * function of the
+                                        * thread. Since this is only
+                                        * available once the thread
+                                        * finishes, this implicitely
+                                        * also calls @p{join()}.
+                                        */
+      RT return_value () {
+        join ();
+        return thread_descriptor->ret_val.get();
       };
 
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_>
-      friend
-      typename FunData1<Arg1_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_));
-  };
-
-
-
-/**
- * Class to store the parameters of a binary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename Arg1, typename Arg2, typename RetType>
-  class FunData2 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData2 (FunPtr fun_ptr,
-               Arg1   arg1,
-               Arg2   arg2);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData2 (const FunData2 &fun_data2);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
 
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
+                                       /**
+                                        * Check for equality of thread
+                                        * objects. Since objects of
+                                        * this class store an implicit
+                                        * pointer to an object that
+                                        * exists exactly once for each
+                                        * thread, the check is simply
+                                        * to compare these pointers.
+                                        */
+      bool operator == (const Thread &t) {
+        return thread_descriptor == t.thread_descriptor;
+      };
 
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
+                                       /**
+                                        * Exception
+                                        */
+      DeclException0 (ExcNoThread);
       
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData2<Arg1,Arg2,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
+    private:
+                                       /**
+                                        * Shared pointer to the object
+                                        * representing the thread, and
+                                        * abstracting operating system
+                                        * functions to work on
+                                        * it. Boost's shared pointer
+                                        * implementation will make
+                                        * sure that that object lives
+                                        * as long as there is at least
+                                        * one subscriber to it.
+                                        */
+      boost::shared_ptr<internal::thread_description<RT> > thread_descriptor;
 
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_>
-      friend
-      typename FunData2<Arg1_,Arg2_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_, Arg2_));
+#ifndef DEAL_II_NAMESP_TEMPL_FRIEND_BUG2
+      template <typename RT_> friend struct Threads::internal::wrapper_base;
+#endif
   };
 
-  
-/**
- * Class to store the parameters of a ternary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  class FunData3 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData3 (FunPtr fun_ptr,
-               Arg1   arg1,
-               Arg2   arg2,
-               Arg3   arg3);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData3 (const FunData3 &fun_data3);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
 
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
 
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
+  namespace internal
+  {
+
+                                     /**
+                                      * Base class for the classes
+                                      * wrapping function pointers and
+                                      * arguments for non-member and
+                                      * member functions.
+                                      *
+                                      * @author Wolfgang Bangerth, 2003
+                                      */
+    template <typename RT>
+    struct wrapper_base
+    {
+
+                                         /**
+                                          * Start a new thread, wait
+                                          * until it has copied the
+                                          * data out of this object,
+                                          * and return the thread
+                                          * descriptor.
+                                          */
+        Thread<RT> fire_up () {
+          thread_descriptor =
+            DescriptionPointer(new internal::thread_description<RT>());
+
+          ThreadMutex::ScopedLock lock (mutex);        
+          thread_descriptor->create (entry_point, (void *)this);
+          condition.wait (mutex);
+
+          return thread_descriptor;
+        }
+
+      protected:
+                                         /**
+                                          * Typedef for the type of a
+                                          * thread entry point, as
+                                          * required by POSIX.
+                                          */
+        typedef void * (*EntryPoint) (void *);
+
+                                         /**
+                                          * Typedef for shared
+                                          * pointers to the objects
+                                          * describing threads on the
+                                          * OS level.
+                                          */
+        typedef
+        boost::shared_ptr<internal::thread_description<RT> >
+        DescriptionPointer;
+
+                                         /**
+                                          * Constructor. Take the
+                                          * address of a thread entry
+                                          * point and store it.
+                                          */
+        wrapper_base (const EntryPoint ep)
+                        : entry_point (ep) {};
+
+                                         /**
+                                          * Shared pointer to the
+                                          * unique object describing a
+                                          * thread on the OS level.
+                                          */
+        DescriptionPointer thread_descriptor;
+
+                                         /**
+                                          * Mutex and condition
+                                          * variable used to
+                                          * synchronise calling and
+                                          * called thread.
+                                          */
+        mutable ThreadMutex     mutex;    
+        mutable ThreadCondition condition;
+
+      private:
+                                         /**
+                                          * Address of the thread
+                                          * entry point. Is set in the
+                                          * constructor, and is the
+                                          * address of a function in
+                                          * derived classes.
+                                          */
+        const EntryPoint entry_point;
+    };
+  
+
+                                     /**
+                                      * Wrap the arguments to a
+                                      * non-member or static member
+                                      * function and provide an entry
+                                      * point for a new thread that
+                                      * unwraps this data and calls
+                                      * the function with them.
+                                      *
+                                      * @author Wolfgang Bangerth, 2003
+                                      */
+    template <typename RT, typename ArgList>
+    struct fun_wrapper : public wrapper_base<RT>
+    {
+                                         /**
+                                          * Typedef for the type of
+                                          * the function to be called
+                                          * on the new thread.
+                                          */
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;
+
+                                         /**
+                                          * Typedef for a typelist of
+                                          * reference arguments to the
+                                          * function to be called.
+                                          */
+        typedef typename internal::tie_args<ArgList>::type ArgReferences;
+
+                                         /**
+                                          * Constructor. Store the
+                                          * necessary information
+                                          * about the function to be
+                                          * called and with which
+                                          * arguments.
+                                          *
+                                          * Pass down the address of
+                                          * this class's thread entry
+                                          * point function. This way,
+                                          * we can ensure that object
+                                          * and thread entry point
+                                          * function always are in
+                                          * synch with respect to
+                                          * their knowledge of the
+                                          * types involved.
+                                          */
+        fun_wrapper (FunPtr               fun_ptr,
+                     const ArgReferences &args)
+                        : wrapper_base<RT> (&entry_point),
+                          fun_ptr (fun_ptr),
+                          args (args)  {};
+      private:
+                                         /**
+                                          * Default constructor. Made
+                                          * private and not
+                                          * implemented to prevent
+                                          * calling.
+                                          */
+        fun_wrapper ();
+
+                                         /**
+                                          * Copy constructor. Made
+                                          * private and not
+                                          * implemented to prevent
+                                          * calling.
+                                          */
+        fun_wrapper (const fun_wrapper &);
+
+                                         /**
+                                          * Pointer to the function to
+                                          * be called on the new
+                                          * thread.
+                                          */
+        FunPtr        fun_ptr;
+
+                                         /**
+                                          * References to the
+                                          * arguments with which the
+                                          * function is to be called.
+                                          */
+        ArgReferences args;
       
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData3<Arg1,Arg2,Arg3,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
 
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_, typename Arg3_>
-      friend
-      typename FunData3<Arg1_,Arg2_,Arg3_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_,Arg2_,Arg3_));
-  };
-
-
-/**
- * Class to store the parameters of a quaternary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  class FunData4 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData4 (FunPtr fun_ptr,
-               Arg1   arg1,
-               Arg2   arg2,
-               Arg3   arg3,
-               Arg4   arg4);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData4 (const FunData4 &fun_data4);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_>
-      friend
-      typename FunData4<Arg1_,Arg2_,Arg3_,Arg4_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_));
-  };
-
-
-
-/**
- * Class to store the parameters of a quintary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  class FunData5 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData5 (FunPtr fun_ptr,
-               Arg1   arg1,
-               Arg2   arg2,
-               Arg3   arg3,
-               Arg4   arg4,
-               Arg5   arg5);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData5 (const FunData5 &fun_data5);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_>
-      friend
-      typename FunData5<Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_, Arg5_));
-  };
-
-
-/**
- * Class to store the parameters of a function with 6 arguments. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  class FunData6 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData6 (FunPtr fun_ptr,
-               Arg1   arg1,
-               Arg2   arg2,
-               Arg3   arg3,
-               Arg4   arg4,
-               Arg5   arg5,
-               Arg6   arg6);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData6 (const FunData6 &fun_data6);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_>
-      friend
-      typename FunData6<Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                  Arg4_, Arg5_, Arg6_));
-  };
-  
-  
-/**
- * Class to store the parameters of a function with 7 arguments. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  class FunData7 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData7 (FunPtr fun_ptr,
-               Arg1   arg1,
-               Arg2   arg2,
-               Arg3   arg3,
-               Arg4   arg4,
-               Arg5   arg5,
-               Arg6   arg6,
-               Arg7   arg7);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData7 (const FunData7 &fun_data7);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      Arg7   arg7;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6,
-                                        Arg7 arg7);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_>
-      friend
-      typename FunData7<Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                  Arg4_, Arg5_, Arg6_, Arg7_));
-  };
-  
-  
-/**
- * Class to store the parameters of a function with 8 arguments. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  class FunData8 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData8 (FunPtr fun_ptr,
-               Arg1   arg1,
-               Arg2   arg2,
-               Arg3   arg3,
-               Arg4   arg4,
-               Arg5   arg5,
-               Arg6   arg6,
-               Arg7   arg7,
-               Arg8   arg8);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData8 (const FunData8 &fun_data8);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      Arg7   arg7;
-      Arg8   arg8;
+                                         /**
+                                          * Entry point for the new
+                                          * thread.
+                                          */
+        static void * entry_point (void *arg)
+          {
+            const wrapper_base<RT> *w
+              = reinterpret_cast<const wrapper_base<RT>*> (arg);
+            const fun_wrapper *wrapper
+              = static_cast<const fun_wrapper*> (w);
+
+                                             // copy information from
+                                             // the stack of the
+                                             // calling thread
+            FunPtr    fun_ptr = wrapper->fun_ptr;
+            ArgList   args    = wrapper->args;
+
+            boost::shared_ptr<internal::thread_description<RT> >
+              thread_descriptor  = wrapper->thread_descriptor;
+          
+                                             // signal the fact that
+                                             // we have copied all the
+                                             // information that is
+                                             // needed
+            {
+              ThreadMutex::ScopedLock lock (wrapper->mutex);
+              wrapper->condition.signal ();
+            }
+
+                                             // call the
+                                             // function. since an
+                                             // exception that is
+                                             // thrown from one of the
+                                             // called functions will
+                                             // not propagate to the
+                                             // main thread, it will
+                                             // kill the program if
+                                             // not treated here
+                                             // before we return to
+                                             // the operating system's
+                                             // thread library
+            internal::register_thread ();
+            try 
+              {
+                internal::call (fun_ptr, args,
+                                thread_descriptor->ret_val);
+              }
+            catch (const std::exception &exc)
+              {
+                internal::handle_std_exception (exc);
+              }
+            catch (...)
+              {
+                internal::handle_unknown_exception ();
+              }
+            internal::deregister_thread ();
+          
+            return 0;
+          };
+    };
+
+  
+  
+                                     /**
+                                      * Wrap the arguments to a member
+                                      * function and provide an entry
+                                      * point for a new thread that
+                                      * unwraps this data and calls
+                                      * the function with them.
+                                      *
+                                      * @author Wolfgang Bangerth, 2003
+                                      */
+    template <typename RT, class C, typename ArgList>
+    struct mem_fun_wrapper : public wrapper_base<RT>
+    {
+                                         /**
+                                          * Typedef for the type of
+                                          * the function to be called
+                                          * on the new thread.
+                                          */
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;
+
+                                         /**
+                                          * Typedef for a typelist of
+                                          * reference arguments to the
+                                          * function to be called.
+                                          */
+        typedef typename internal::tie_args<ArgList>::type ArgReferences;
       
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6,
-                                        Arg7 arg7,
-                                        Arg8 arg8);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_>
-      friend
-      typename FunData8<Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                  Arg4_, Arg5_, Arg6_,
-                                  Arg7_, Arg8_));
-  };
-  
-  
-/**
- * Class to store the parameters of a function with 9 arguments. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2001
- */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  class FunData9 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData9 (FunPtr fun_ptr,
-               Arg1   arg1,
-               Arg2   arg2,
-               Arg3   arg3,
-               Arg4   arg4,
-               Arg5   arg5,
-               Arg6   arg6,
-               Arg7   arg7,
-               Arg8   arg8,
-               Arg9   arg9);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData9 (const FunData9 &fun_data9);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      Arg7   arg7;
-      Arg8   arg8;
-      Arg9   arg9;
+                                         /**
+                                          * Constructor. Store the
+                                          * necessary information
+                                          * about the function to be
+                                          * called and with which
+                                          * arguments.
+                                          *
+                                          * Pass down the address of
+                                          * this class's thread entry
+                                          * point function. This way,
+                                          * we can ensure that object
+                                          * and thread entry point
+                                          * function always are in
+                                          * synch with respect to
+                                          * their knowledge of the
+                                          * types involved.
+                                          */
+        mem_fun_wrapper (MemFunPtr            mem_fun_ptr,
+                         C                   &c,
+                         const ArgReferences &args)
+                        : wrapper_base<RT> (&entry_point),
+                          c (c),
+                          mem_fun_ptr (mem_fun_ptr),
+                          args (args)  {};
+      private:
+                                         /**
+                                          * Default constructor. Made
+                                          * private and not
+                                          * implemented to prevent
+                                          * calling.
+                                          */
+        mem_fun_wrapper ();
+
+                                         /**
+                                          * Copy constructor. Made
+                                          * private and not
+                                          * implemented to prevent
+                                          * calling.
+                                          */
+        mem_fun_wrapper (const mem_fun_wrapper &);
       
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6,
-                                        Arg7 arg7,
-                                        Arg8 arg8,
-                                        Arg9 arg9);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_, typename Arg9_>
-      friend
-      typename FunData9<Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,Arg9_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                  Arg4_, Arg5_, Arg6_,
-                                  Arg7_, Arg8_, Arg9_));
-  };
-  
-  
-/**
- * Class to store the parameters of a function with 10 arguments. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2001
- */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  class FunData10 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a global
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10);
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      FunData10 (FunPtr fun_ptr,
-                Arg1   arg1,
-                Arg2   arg2,
-                Arg3   arg3,
-                Arg4   arg4,
-                Arg5   arg5,
-                Arg6   arg6,
-                Arg7   arg7,
-                Arg8   arg8,
-                Arg9   arg9,
-                Arg10  arg10);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      FunData10 (const FunData10 &fun_data10);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      Arg7   arg7;
-      Arg8   arg8;
-      Arg9   arg9;
-      Arg10  arg10;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6,
-                                        Arg7 arg7,
-                                        Arg8 arg8,
-                                        Arg9 arg9,
-                                        Arg10 arg10);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_, typename Arg9_, typename Arg10_>
-      friend
-      typename FunData10<Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,Arg9_,Arg10_,void>::ArgCollector
-      encapsulate (void (*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                  Arg4_, Arg5_, Arg6_,
-                                  Arg7_, Arg8_, Arg9_,
-                                  Arg10_));
-  };
-  
-  
-/**
- * Class to store the parameters of a void function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <class Class, typename RetType>
-  class MemFunData0 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr0<Class,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData0 (FunPtr fun_ptr,
-                  Class *object);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData0 (const MemFunData0 &fun_data0);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData0<Class,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object);
-
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_>
-      friend
-      typename MemFunData0<Class_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)());
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_>
-      friend
-      typename MemFunData0<const Class_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)() const);
-#endif
-  };
-
-
-
-/**
- * Class to store the parameters of a unary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <class Class, typename Arg1, typename RetType>
-  class MemFunData1 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr1<Class,Arg1,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData1 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData1 (const MemFunData1 &fun_data1);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-      
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData1<Class,Arg1,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1   arg1);
-
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1);
-
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_>
-      friend
-      typename MemFunData1<Class_,Arg1_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_>
-      friend
-      typename MemFunData1<const Class_,Arg1_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_) const);
-#endif
-  };
-
-
-
-/**
- * Class to store the parameters of a binary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <class Class, typename Arg1, typename Arg2, typename RetType>
-  class MemFunData2 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr2<Class,Arg1,Arg2,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData2 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1,
-                  Arg2   arg2);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData2 (const MemFunData2 &fun_data2);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData2<Class,Arg1,Arg2,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2);
-         
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2);
-    
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_>
-      friend
-      typename MemFunData2<Class_,Arg1_,Arg2_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_>
-      friend
-      typename MemFunData2<const Class_,Arg1_,Arg2_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_) const);
-#endif
-  };
-
-  
-/**
- * Class to store the parameters of a ternary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  class MemFunData3 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr3<Class,Arg1,Arg2,Arg3,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData3 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData3 (const MemFunData3 &fun_data3);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3);
-    
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2,
-                                        Arg3   arg3);
-
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_>
-      friend 
-      typename MemFunData3<Class_,Arg1_,Arg2_,Arg3_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_,Arg2_,Arg3_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_>
-      friend 
-      typename MemFunData3<const Class_,Arg1_,Arg2_,Arg3_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_,Arg2_,Arg3_) const);
-#endif
-  };
-
-
-
-/**
- * Class to store the parameters of a quaternary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  class MemFunData4 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData4 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3,
-                  Arg4   arg4);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData4 (const MemFunData4 &fun_data4);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4);
-    
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2,
-                                        Arg3   arg3,
-                                        Arg4   arg4);
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_>
-      friend
-      typename MemFunData4<Class_,Arg1_,Arg2_,Arg3_,Arg4_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_>
-      friend
-      typename MemFunData4<const Class_,Arg1_,Arg2_,Arg3_,Arg4_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_, Arg4_) const);
-#endif  
-};
-
-
-
-/**
- * Class to store the parameters of a quintary function. For more
- * information on use and internals of this class see the report on
- * multithreading.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  class MemFunData5 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData5 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3,
-                  Arg4   arg4,
-                  Arg5   arg5);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData5 (const MemFunData5 &fun_data5);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5);
-    
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2,
-                                        Arg3   arg3,
-                                        Arg4   arg4,
-                                        Arg5   arg5);
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_>
-      friend 
-      typename MemFunData5<Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_>
-      friend 
-      typename MemFunData5<const Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_) const);
-#endif
-  };
-  
-
-  
-/**
- * Class to store the parameters of a function with 6 arguments. For
- * more information on use and internals of this class see the report
- * on this subject.
- *
- * @author Wolfgang Bangerth, Ralf Hartmann, 2000
- */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  class MemFunData6 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData6 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3,
-                  Arg4   arg4,
-                  Arg5   arg5,
-                  Arg6   arg6);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData6 (const MemFunData6 &fun_data6);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6);
-    
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2,
-                                        Arg3   arg3,
-                                        Arg4   arg4,
-                                        Arg5   arg5,
-                                        Arg6   arg6);
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_>
-      friend 
-      typename MemFunData6<Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_>
-      friend 
-      typename MemFunData6<const Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_) const);
-#endif  
-  };
-
-
-
-/**
- * Class to store the parameters of a function with 7 arguments. For
- * more information on use and internals of this class see the report
- * on this subject.
- *
- * @author Wolfgang Bangerth, Ralf Hartmann, 2001
- */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  class MemFunData7 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData7 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3,
-                  Arg4   arg4,
-                  Arg5   arg5,
-                  Arg6   arg6,
-                  Arg7   arg7);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData7 (const MemFunData7 &fun_data7);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      Arg7   arg7;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6,
-                                        Arg7 arg7);
-    
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2,
-                                        Arg3   arg3,
-                                        Arg4   arg4,
-                                        Arg5   arg5,
-                                        Arg6   arg6,
-                                        Arg7   arg7);
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_>
-      friend 
-      typename MemFunData7<Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_, Arg7_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_>
-      friend 
-      typename MemFunData7<const Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_, Arg7_) const);
-#endif
-  };
-  
-  
-/**
- * Class to store the parameters of a function with 8 arguments. For
- * more information on use and internals of this class see the report
- * on this subject.
- *
- * @author Wolfgang Bangerth, Ralf Hartmann, 2001
- */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  class MemFunData8 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData8 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3,
-                  Arg4   arg4,
-                  Arg5   arg5,
-                  Arg6   arg6,
-                  Arg7   arg7,
-                  Arg8   arg8);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData8 (const MemFunData8 &fun_data8);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      Arg7   arg7;
-      Arg8   arg8;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6,
-                                        Arg7 arg7,
-                                        Arg8 arg8);
-    
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2,
-                                        Arg3   arg3,
-                                        Arg4   arg4,
-                                        Arg5   arg5,
-                                        Arg6   arg6,
-                                        Arg7   arg7,
-                                        Arg8   arg8);
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_>
-      friend 
-      typename MemFunData8<Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_,
-                                          Arg7_, Arg8_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_>
-      friend 
-      typename MemFunData8<const Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_,
-                                          Arg7_, Arg8_) const);
-#endif
-  };
-  
-  
-/**
- * Class to store the parameters of a function with 9 arguments. For
- * more information on use and internals of this class see the report
- * on this subject.
- *
- * @author Wolfgang Bangerth, Ralf Hartmann, 2001
- */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  class MemFunData9 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData9 (FunPtr fun_ptr,
-                  Class *object,
-                  Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3,
-                  Arg4   arg4,
-                  Arg5   arg5,
-                  Arg6   arg6,
-                  Arg7   arg7,
-                  Arg8   arg8,
-                  Arg9   arg9);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData9 (const MemFunData9 &fun_data9);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      Arg7   arg7;
-      Arg8   arg8;
-      Arg9   arg9;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6,
-                                        Arg7 arg7,
-                                        Arg8 arg8,
-                                        Arg9 arg9);
-    
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2,
-                                        Arg3   arg3,
-                                        Arg4   arg4,
-                                        Arg5   arg5,
-                                        Arg6   arg6,
-                                        Arg7   arg7,
-                                        Arg8   arg8,
-                                        Arg9   arg9);
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_, typename Arg9_>
-      friend 
-      typename MemFunData9<Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,Arg9_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_,
-                                          Arg7_, Arg8_, Arg9_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_, typename Arg9_>
-      friend 
-      typename MemFunData9<const Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,Arg9_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_,
-                                          Arg7_, Arg8_, Arg9_) const);
-#endif
-  };
-  
-  
-/**
- * Class to store the parameters of a function with 10 arguments. For
- * more information on use and internals of this class see the report
- * on this subject.
- *
- * @author Wolfgang Bangerth, Ralf Hartmann, 2001
- */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  class MemFunData10 : public FunDataBase
-  {
-    public:
-                                      /**
-                                       * Typedef a pointer to a member
-                                       * function which we will call
-                                       * from this class.
-                                       */
-      typedef typename MemFunPtr10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::type FunPtr;
-
-                                      /**
-                                       * Constructor. Store pointer to
-                                       * the function and the values of
-                                       * the arguments.
-                                       */
-      MemFunData10 (FunPtr fun_ptr,
-                   Class *object,
-                   Arg1   arg1,
-                   Arg2   arg2,
-                   Arg3   arg3,
-                   Arg4   arg4,
-                   Arg5   arg5,
-                   Arg6   arg6,
-                   Arg7   arg7,
-                   Arg8   arg8,
-                   Arg9   arg9,
-                   Arg10  arg10);
-
-                                      /**
-                                       * Copy constructor.
-                                       */
-      MemFunData10 (const MemFunData10 &fun_data10);
-
-                                      /**
-                                       * Virtual constructor.
-                                       */
-      virtual FunDataBase * clone () const;
-
-    private:
-
-                                      /**
-                                       * Pointer to the function to be
-                                       * called and values of the
-                                       * arguments to be passed.
-                                       */
-      FunPtr fun_ptr;
-
-                                      /**
-                                       * Pointer to the object which
-                                       * we shall work on.
-                                       */
-      Class *object;
-                                      /**
-                                       * Values of the arguments of the
-                                       * function to be called.
-                                       */
-      Arg1   arg1;
-      Arg2   arg2;
-      Arg3   arg3;
-      Arg4   arg4;
-      Arg5   arg5;
-      Arg6   arg6;
-      Arg7   arg7;
-      Arg8   arg8;
-      Arg9   arg9;
-      Arg10  arg10;
-      
-                                      /**
-                                       * Static function used as entry
-                                       * point for the new thread.
-                                       */
-      static void * thread_entry_point (void *arg);
-
-                                      /**
-                                       * Helper class, used to collect
-                                       * the values of the parameters
-                                       * which we will pass to the
-                                       * function, once we know its
-                                       * type.
-                                       */
-      class ArgCollector
-      {
-       public:
-                                          /**
-                                           * Typedef the function
-                                           * pointer type of the
-                                           * underlying class to a
-                                           * local type.
-                                           */
-         typedef typename MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::FunPtr FunPtr;
-       
-                                          /**
-                                           * Constructor. Take and store a
-                                           * pointer to the function which
-                                           * is to be called.
-                                           */
-         ArgCollector (FunPtr fun_ptr);
-    
-                                          /**
-                                           * Take the arguments with
-                                           * which we want to call the
-                                           * function and produce and
-                                           * object of the desired type
-                                           * from that.
-                                           */
-         FunEncapsulation collect_args (Class *object,
-                                        Arg1 arg1,
-                                        Arg2 arg2,
-                                        Arg3 arg3,
-                                        Arg4 arg4,
-                                        Arg5 arg5,
-                                        Arg6 arg6,
-                                        Arg7 arg7,
-                                        Arg8 arg8,
-                                        Arg9 arg9,
-                                        Arg10 arg10);
-    
-                                          /**
-                                           * Same as above, but take
-                                           * a reference instead of a
-                                           * pointer. This allows us
-                                           * to be a little
-                                           * convenient, as we can
-                                           * use @p{object} or
-                                           * @p{this}, without taking
-                                           * care that one is a
-                                           * reference and the other
-                                           * a pointer.
-                                           */
-         FunEncapsulation collect_args (Class &object,
-                                        Arg1   arg1,
-                                        Arg2   arg2,
-                                        Arg3   arg3,
-                                        Arg4   arg4,
-                                        Arg5   arg5,
-                                        Arg6   arg6,
-                                        Arg7   arg7,
-                                        Arg8   arg8,
-                                        Arg9   arg9,
-                                        Arg10  arg10);
-       private:
-                                          /**
-                                           * Space to temporarily store
-                                           * the function pointer.
-                                           */
-         FunPtr fun_ptr;
-      };
-
-                                      /**
-                                       * Declare a function that uses
-                                       * the @ref{ArgCollector} as
-                                       * friend.
-                                       */
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_, typename Arg9_, typename Arg10_>
-      friend 
-      typename MemFunData10<Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,Arg9_,Arg10_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_,
-                                          Arg7_, Arg8_, Arg9_, Arg10_));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-      template <class Class_, typename Arg1_, typename Arg2_, typename Arg3_, typename Arg4_, typename Arg5_, typename Arg6_, typename Arg7_, typename Arg8_, typename Arg9_, typename Arg10_>
-      friend 
-      typename MemFunData10<const Class_,Arg1_,Arg2_,Arg3_,Arg4_,Arg5_,Arg6_,Arg7_,Arg8_,Arg9_,Arg10_,void>::ArgCollector
-      encapsulate (void (Class_::*fun_ptr)(Arg1_, Arg2_, Arg3_,
-                                          Arg4_, Arg5_, Arg6_,
-                                          Arg7_, Arg8_, Arg9_, Arg10_) const);
-#endif
-  };
-  
-  
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  inline
-  FunData0<void>::ArgCollector
-  encapsulate (void (*fun_ptr)());
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1>
-  inline
-  typename FunData1<Arg1,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1));
-
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2>
-  inline
-  typename FunData2<Arg1,Arg2,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2));
-  
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2, typename Arg3>
-  inline
-  typename FunData3<Arg1,Arg2,Arg3,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3));
-  
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-  inline
-  typename FunData4<Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4));
-
-
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-  inline
-  typename FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5));
-
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
-  inline
-  typename FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6));
-
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7>
-  inline
-  typename FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7));
-
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8>
-  inline
-  typename FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8));
-
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9>
-  inline
-  typename FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9));
-
-
-                                  /**
-                                   * Encapsulate a function pointer
-                                   * into an object with which a new
-                                   * thread can later be spawned.
-                                   * For more information on use and
-                                   * internals of this class see the
-                                   * report on multithreading.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10>
-  inline
-  typename FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10));
-
-
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class>
-  inline
-  typename MemFunData0<Class,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)());
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class>
-  inline
-  typename MemFunData0<const Class,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)() const);
-#endif
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1>
-  inline
-  typename MemFunData1<Class,Arg1,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1>
-  inline
-  typename MemFunData1<const Class,Arg1,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1) const);
-#endif
-
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2>
-  inline
-  typename MemFunData2<Class,Arg1,Arg2,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2>
-  inline
-  typename MemFunData2<const Class,Arg1,Arg2,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2) const);
-#endif
-   
-
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3>
-  inline
-  typename MemFunData3<Class,Arg1,Arg2,Arg3,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3>
-  inline
-  typename MemFunData3<const Class,Arg1,Arg2,Arg3,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3) const);
-#endif
-   
-
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-  inline
-  typename MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-  inline
-  typename MemFunData4<const Class,Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4) const);
-#endif
-   
-
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-  inline
-  typename MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-  inline
-  typename MemFunData5<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5) const);
-#endif
-
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
-  inline
-  typename MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
-  inline
-  typename MemFunData6<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const);
-#endif
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7>
-  inline
-  typename MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7>
-  inline
-  typename MemFunData7<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const);
-#endif
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8>
-  inline
-  typename MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8>
-  inline
-  typename MemFunData8<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) const);
-#endif
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9>
-  inline
-  typename MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9>
-  inline
-  typename MemFunData9<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) const);
-#endif
-                                  /**
-                                   * Encapsulate a member function
-                                   * pointer into an object with
-                                   * which a new thread can later be
-                                   * spawned.  For more information
-                                   * on use and internals of this
-                                   * class see the report on this
-                                   * subject.
-                                   *
-                                   * This function exists once for
-                                   * each number of parameters.
-                                   */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10>
-  inline
-  typename MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10));
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-                                   /**
-                                   * Same as the previous function,
-                                   * but for member functions marked
-                                   * @p{const}. This function should
-                                   * not be necessary, since the
-                                   * compiler should deduce a
-                                   * constant class as template
-                                   * argument, but we have to work
-                                   * around a bug in Intel's icc
-                                   * compiler with this.  
-                                    */
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10>
-  inline
-  typename MemFunData10<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) const);
-#endif
-  
-                                  /**
-                                   * Spawn a new thread using the
-                                   * function and parameters
-                                   * encapsulated in @p{fun_data}, and
-                                   * using the given thread manager
-                                   * object.
-                                   */
-  void spawn (ThreadManager          &thread_manager,
-             const FunEncapsulation &fun_data);
-
-
-                                  /**
-                                   * Spawn several threads at once,
-                                   * using the same parameters and
-                                   * calling the same function.
-                                   */
-  void spawn_n (ThreadManager          &thread_manager,
-               const FunEncapsulation &fun_encapsulation,
-               const unsigned int      n_threads);
-
-                                   /**
-                                    * Return the number of presently
-                                    * existing threads. This function
-                                    * may be useful in a situation
-                                    * where a large number of threads
-                                    * are concurrently, and you want
-                                    * to decide whether creation of
-                                    * another thread is reasonable or
-                                    * whether running the respective
-                                    * operation sequentially is more
-                                    * useful since already many more
-                                    * threads than processors are
-                                    * running.
-                                    *
-                                    * Note that the function returns
-                                    * the total number of threads, not
-                                    * those actually running. Some of
-                                    * the threads may be waiting for
-                                    * locks and mutexes, or may be
-                                    * sleeping until they are
-                                    * delivered with data to work on.
-                                    * 
-                                    * Upon program start, this number
-                                    * is one. It is increased each
-                                    * time a thread is created using
-                                    * the @ref{Threads::spawn} or
-                                    * @ref{Threads::spawn_n}
-                                    * functions. It is decreased once
-                                    * a thread terminates by returning
-                                    * from the function that was
-                                    * spawned.
-                                    *
-                                    * Note that this means that only
-                                    * threads created and terminated
-                                    * through the interfaces of this
-                                    * namespace are taken care of. If
-                                    * threads are created by directly
-                                    * calling the respective functions
-                                    * of the operating system
-                                    * (e.g. @p{pthread_create} for the
-                                    * POSIX thread interface), or if
-                                    * they are killed (e.g. either
-                                    * through @p{pthread_exit} from
-                                    * the spawned thread, or
-                                    * @p{pthread_kill} from another
-                                    * thread), then these events are
-                                    * not registered and counted for
-                                    * the result of this function.
-                                    */
-  unsigned int n_existing_threads ();
-
-                                  /**
-                                   * Split the range @p{[begin,end)}
-                                   * into @p{n_intervals} subintervals
-                                   * of equal size. The last interval
-                                   * will be a little bit larger, if
-                                   * the number of elements in the
-                                   * whole range is not exactly
-                                   * divisible by @p{n_intervals}. The
-                                   * type of the iterators has to
-                                   * fulfill the requirements of a
-                                   * forward iterator,
-                                   * i.e. @p{operator++} must be
-                                   * available, and of course it must
-                                   * be assignable.
-                                   *
-                                   * A list of subintervals is
-                                   * returned as a vector of pairs of
-                                   * iterators, where each pair
-                                   * denotes the range
-                                   * @p{[begin[i],end[i])}.
-                                   */
-  template <typename ForwardIterator>
-  std::vector<std::pair<ForwardIterator,ForwardIterator> >
-  split_range (const ForwardIterator &begin,
-              const ForwardIterator &end,
-              const unsigned int n_intervals);
-
-                                  /**
-                                   * Split the interval @p{[begin,end)}
-                                   * into subintervals of (almost)
-                                   * equal size. This function works
-                                   * mostly as the one before, with
-                                   * the difference that instead of
-                                   * iterators, now values are taken
-                                   * that define the whole interval.
-                                   */
-  std::vector<std::pair<unsigned int,unsigned int> >
-  split_interval (const unsigned int begin,
-                 const unsigned int end,
-                 const unsigned int n_intervals);
-  
-  
-
-/**
- * This class is used to make some sanity checks on the numbers of
- * objects of some types related with thread spawning, which are
- * created and deleted. This is a helpful thing when trying to
- * implement the data copying using @p{clone} functions etc, in order to
- * avoid that there are some objects which are copied but not deleted.
- *
- * It basically only monitors the number of objects which is alive at
- * each time, and complains if the number is nonzero when the counting
- * object is deleted. Since one will probably want to use one global
- * counter, the complaint is raised at the end of the program, and
- * then means that somewhen within the lifetime of your program there
- * has occured a memory leak.
- *
- * This class is not meant for public use.
- *
- * @author Wolfgang Bangerth, 2000
- */
-  struct FunDataCounter
-  {
-                                      /**
-                                       * Constructor. Sets all
-                                       * counters to zero.
-                                       */
-      FunDataCounter ();
-      
-                                      /**
-                                       * Destructor. Check whether
-                                       * the total number of objects
-                                       * is zero, otherwise throw an
-                                       * exception.
-                                       */
-      ~FunDataCounter ();
-
-                                      /**
-                                       * Counters for the two types
-                                       * of objects which we
-                                       * presently monitor.
-                                       */
-      unsigned int n_fun_encapsulation_objects;
-      unsigned int n_fun_data_base_objects;
-
-                                      /**
-                                       * Exception
-                                       */
-      DeclException2 (ExcObjectsExist,
-                     char*, int,
-                     << "There are still " << arg2 << " objects of type "
-                     << arg1 << " alive. You probably have a memory "
-                     << "leak somewhere.");
-  };
-
-
-                                   /**
-                                    * The following function is used
-                                    * for internal bookkeeping of the
-                                    * number of existing threads. It
-                                    * is not thought for use in
-                                    * application programs, but only
-                                    * for use in the template
-                                    * functions below.
-                                    */
-  void register_new_thread ();
-  
-                                   /**
-                                    * The following function is used
-                                    * for internal bookkeeping of the
-                                    * number of existing threads. It
-                                    * is not thought for use in
-                                    * application programs, but only
-                                    * for use in the template
-                                    * functions below.
-                                    */
-  void deregister_new_thread ();  
-
-                                   /**
-                                    * If in a sub-thread an exception
-                                    * is thrown, it is not propagated
-                                    * to the main thread. Therefore,
-                                    * the exception handler that is
-                                    * provided by the applications
-                                    * main function or some of its
-                                    * other parts will not be able to
-                                    * catch these
-                                    * exceptions. Therefore, we have
-                                    * to provide an exception handler
-                                    * in the top function of each
-                                    * sub-thread that at least catches
-                                    * the exception and prints some
-                                    * information, rather than letting
-                                    * the operating system to just
-                                    * kill the program without a
-                                    * message. In each of the
-                                    * functions we use as entry points
-                                    * to new threads, we therefore
-                                    * install a try-catch block, and
-                                    * if an exception of type
-                                    * @p{std::exception} is caught, it
-                                    * passes over control to this
-                                    * function, which will then
-                                    * provide some output.
-                                    */
-  void handle_std_exception (const std::exception &exc);
-
-                                   /**
-                                    * Same as above, but the type of
-                                    * the exception is not derived
-                                    * from @p{std::exception}, so
-                                    * there is little way to provide
-                                    * something more useful.
-                                    */
-  void handle_unknown_exception ();
-  
-}   // end declarations of namespace Threads
-
-
-
-
-
-
-
-/* ----------- implementation of functions in namespace Threads ---------- */
-namespace Threads 
-{
-
-/* ---------------------- FunData0 implementation ------------------------ */
-
-  template <typename RetType>
-  FunData0<RetType>::FunData0 (FunPtr fun_ptr) :
-                 FunDataBase (&FunData0<RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr)
-  {}
-
-
-
-  template <typename RetType>
-  FunData0<RetType>::FunData0 (const FunData0 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr)
-  {}
-
-
-
-  template <typename RetType>
-  FunDataBase *
-  FunData0<RetType>::clone () const 
-  {
-    return new FunData0 (*this);
-  }
-
-
-
-  template <typename RetType>
-  void *
-  FunData0<RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData0<RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)();
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-  
-    return 0;
-  }
-
-
-
-  template <typename RetType>
-  FunData0<RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-       
-
-  
-  template <typename RetType>
-  FunEncapsulation
-  FunData0<RetType>::ArgCollector::collect_args ()
-  {
-    return new FunData0<void>(fun_ptr);
-  }
-
-
-/* ---------------------- FunData1 implementation ------------------------ */
-
-  template <typename Arg1, typename RetType>
-  FunData1<Arg1,RetType>::FunData1 (FunPtr fun_ptr,
-                                   Arg1   arg1) :
-                 FunDataBase (&FunData1<Arg1,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1)
-  {}
-
-
-
-  template <typename Arg1, typename RetType>
-  FunData1<Arg1,RetType>::FunData1 (const FunData1 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1)
-  {}
-
-
-
-  template <typename Arg1, typename RetType>
-  FunDataBase *
-  FunData1<Arg1,RetType>::clone () const 
-  {
-    return new FunData1 (*this);
-  }
-
-
-
-  template <typename Arg1, typename RetType>
-  void *
-  FunData1<Arg1,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData1<Arg1,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-  
-    return 0;
-  }
-
-
-
-  template <typename Arg1, typename RetType>
-  FunData1<Arg1,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-       
-
-  template <typename Arg1, typename RetType>
-  FunEncapsulation
-  FunData1<Arg1,RetType>::ArgCollector::collect_args (Arg1 arg1)
-  {
-    return new FunData1<Arg1,void>(fun_ptr, arg1);
-  }
-  
-
-
-/* ---------------------- FunData2 implementation ------------------------ */
-
-  template <typename Arg1, typename Arg2, typename RetType>
-  FunData2<Arg1,Arg2,RetType>::FunData2 (FunPtr fun_ptr,
-                                        Arg1   arg1,
-                                        Arg2   arg2) :
-                 FunDataBase (&FunData2<Arg1,Arg2,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename RetType>
-  FunData2<Arg1,Arg2,RetType>::FunData2 (const FunData2 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename RetType>
-  FunDataBase *
-  FunData2<Arg1,Arg2,RetType>::clone () const 
-  {
-    return new FunData2 (*this);
-  }
-
-
-
-  template <typename Arg1, typename Arg2, typename RetType>
-  void *
-  FunData2<Arg1,Arg2,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData2<Arg1,Arg2,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-  
-    return 0;
-  }
-
-
-
-  template <typename Arg1, typename Arg2, typename RetType>
-  FunData2<Arg1,Arg2,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-       
-
-  
-  template <typename Arg1, typename Arg2, typename RetType>
-  FunEncapsulation
-  FunData2<Arg1,Arg2,RetType>::ArgCollector::collect_args (Arg1 arg1,
-                                                          Arg2 arg2)
-  {
-    return new FunData2<Arg1,Arg2,void>(fun_ptr, arg1, arg2);
-  }
-  
-
-
-/* ---------------------- FunData3 implementation ------------------------ */
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  FunData3<Arg1,Arg2,Arg3,RetType>::FunData3 (FunPtr fun_ptr,
-                                             Arg1   arg1,
-                                             Arg2   arg2,
-                                             Arg3   arg3) :
-                 FunDataBase (&FunData3<Arg1,Arg2,Arg3,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  FunData3<Arg1,Arg2,Arg3,RetType>::FunData3 (const FunData3 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  FunDataBase *
-  FunData3<Arg1,Arg2,Arg3,RetType>::clone () const 
-  {
-    return new FunData3 (*this);
-  }
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  void *
-  FunData3<Arg1,Arg2,Arg3,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData3<Arg1,Arg2,Arg3,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2, arg3);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-
-    return 0;
-  }
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  FunData3<Arg1,Arg2,Arg3,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-       
-
-  
-  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  FunEncapsulation
-  FunData3<Arg1,Arg2,Arg3,RetType>::ArgCollector::collect_args (Arg1 arg1,
-                                                               Arg2 arg2,
-                                                               Arg3 arg3)
-  {
-    return new FunData3<Arg1,Arg2,Arg3,void>(fun_ptr, arg1, arg2, arg3);
-  }
-  
-
-
-/* ---------------------- FunData4 implementation ------------------------ */
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::FunData4 (FunPtr fun_ptr,
-                                                  Arg1   arg1,
-                                                  Arg2   arg2,
-                                                  Arg3   arg3,
-                                                  Arg4   arg4) :
-                 FunDataBase (&FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::FunData4 (const FunData4 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  FunDataBase *
-  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::clone () const 
-  {
-    return new FunData4 (*this);
-  }
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  void *
-  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData4<Arg1,Arg2,Arg3,Arg4,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2, arg3, arg4);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-  
-    return 0;
+                                         /**
+                                          * Pointer to the function to
+                                          * be called on the new
+                                          * thread, as well as the
+                                          * object with which this has
+                                          * to happen.
+                                          */
+        C            &c;
+        MemFunPtr     mem_fun_ptr;
+
+                                         /**
+                                          * References to the
+                                          * arguments with which the
+                                          * function is to be called.
+                                          */
+        ArgReferences args;
+
+                                         /**
+                                          * Entry point for the new
+                                          * thread.
+                                          */
+        static void * entry_point (void *arg)
+          {
+            const wrapper_base<RT> *w
+              = reinterpret_cast<const wrapper_base<RT>*> (arg);
+            const mem_fun_wrapper *wrapper
+              = static_cast<const mem_fun_wrapper*> (w);
+
+                                             // copy information from
+                                             // the stack of the
+                                             // calling thread
+            MemFunPtr mem_fun_ptr = wrapper->mem_fun_ptr;
+            C        &c           = wrapper->c;
+            ArgList   args        = wrapper->args;
+
+            boost::shared_ptr<internal::thread_description<RT> >
+              thread_descriptor  = wrapper->thread_descriptor;
+
+                                             // signal the fact that
+                                             // we have copied all the
+                                             // information that is
+                                             // needed
+            {
+              ThreadMutex::ScopedLock lock (wrapper->mutex);
+              wrapper->condition.signal ();
+            }
+          
+                                             // call the
+                                             // function. since an
+                                             // exception that is
+                                             // thrown from one of the
+                                             // called functions will
+                                             // not propagate to the
+                                             // main thread, it will
+                                             // kill the program if
+                                             // not treated here
+                                             // before we return to
+                                             // the operating system's
+                                             // thread library
+            internal::register_thread ();
+            try 
+              {
+                internal::call (mem_fun_ptr, c, args,
+                                thread_descriptor->ret_val);
+              }
+            catch (const std::exception &exc)
+              {
+                internal::handle_std_exception (exc);
+              }
+            catch (...)
+              {
+                internal::handle_unknown_exception ();
+              }
+            internal::deregister_thread ();
+          
+            return 0;
+          };
+    };
   }
 
 
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
+  namespace internal
+  {
+                                     /**
+                                      * General template declaration
+                                      * of a class that is used to
+                                      * encapsulate arguments to
+                                      * global and static member
+                                      * functions, make sure a new
+                                      * thread is created and that
+                                      * function being run on that
+                                      * thread.
+                                      *
+                                      * Although this general template
+                                      * is not implemented at all, the
+                                      * default template argument
+                                      * makes sure that whenever using
+                                      * the name of this class, the
+                                      * last template argument will be
+                                      * computed correctly from the
+                                      * previous arguments, and the
+                                      * correct specialization for
+                                      * this last template argument be
+                                      * used, even though we need to
+                                      * specify it.
+                                      */
+    template <typename RT, typename ArgList,
+              int length = boost::tuples::length<ArgList>::value>
+    class fun_encapsulator;
+
+
+                                     /**
+                                      * General template declaration
+                                      * of a class that is used to
+                                      * encapsulate arguments to
+                                      * non-static member functions,
+                                      * make sure a new thread is
+                                      * created and that function
+                                      * being run on that thread.
+                                      *
+                                      * Although this general template
+                                      * is not implemented at all, the
+                                      * default template argument
+                                      * makes sure that whenever using
+                                      * the name of this class, the
+                                      * last template argument will be
+                                      * computed correctly from the
+                                      * previous arguments, and the
+                                      * correct specialization for
+                                      * this last template argument be
+                                      * used, even though we need to
+                                      * specify it.
+                                      */
+    template <typename RT, typename C, typename ArgList,
+              int length = boost::tuples::length<ArgList>::value>
+    class mem_fun_encapsulator;
+  }
 
 
+// ----------- encapsulators for member functions not taking any parameters
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  FunEncapsulation
-  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::collect_args (Arg1 arg1,
-                                                                    Arg2 arg2,
-                                                                    Arg3 arg3,
-                                                                    Arg4 arg4)
+  namespace internal
   {
-    return new FunData4<Arg1,Arg2,Arg3,Arg4,void>(fun_ptr, arg1, arg2, arg3, arg4);
-  }
-  
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with no arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 0>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
 
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
 
-/* ---------------------- FunData5 implementation ------------------------ */
+        inline
+        Thread<RT>
+        operator() () {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                ArgList()).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
+  
+  }
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::FunData5 (FunPtr fun_ptr,
-                                                       Arg1   arg1,
-                                                       Arg2   arg2,
-                                                       Arg3   arg3,
-                                                       Arg4   arg4,
-                                                       Arg5   arg5) :
-                 FunDataBase (&FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5)
-  {}
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * no arguments.
+                                    */
+  template <typename RT, typename C>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<> >
+  spawn (C &c, RT (C::*fun_ptr)()) {
+    return internal::mem_fun_encapsulator<RT, C, boost::tuple<> > (c,fun_ptr);
+  }
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with no
+                                    * arguments.
+                                    */
+  template <typename RT, typename C>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,boost::tuple<> >
+  spawn (const C &c, RT (C::*fun_ptr)() const) {
+    return internal::mem_fun_encapsulator<RT, const C, boost::tuple<> > (c,fun_ptr);
+  }
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::FunData5 (const FunData5 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5)
-  {}
 
 
+// ----------- encapsulators for unary member functions
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  FunDataBase *
-  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::clone () const 
+  namespace internal
   {
-    return new FunData5 (*this);
-  }
-
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 1 argument.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 1>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
 
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  void *
-  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 1 argument.
+                                    */
+  template <typename RT, typename C, typename Arg1>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1)) {
+    return internal::mem_fun_encapsulator<RT, C, boost::tuple<Arg1> > (c,fun_ptr);
+  }
+
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 1
+                                    * argument.
+                                    */
+  template <typename RT, typename C, typename Arg1>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,boost::tuple<Arg1> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1) const) {
+    return internal::mem_fun_encapsulator<RT, const C, boost::tuple<Arg1> > (c,fun_ptr);
+  }
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
 
 
+// ----------- encapsulators for binary member functions
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  FunEncapsulation
-  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::collect_args (Arg1 arg1,
-                                                                         Arg2 arg2,
-                                                                         Arg3 arg3,
-                                                                         Arg4 arg4,
-                                                                         Arg5 arg5)
+  namespace internal
   {
-    return new FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,void>(fun_ptr, arg1, arg2,
-                                                      arg3, arg4, arg5);
-  }
-
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 2 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 2>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
 
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,
+                                                           arg2)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-/* ---------------------- FunData6 implementation ------------------------ */
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::FunData6 (FunPtr fun_ptr,
-                                                            Arg1   arg1,
-                                                            Arg2   arg2,
-                                                            Arg3   arg3,
-                                                            Arg4   arg4,
-                                                            Arg5   arg5,
-                                                            Arg6   arg6) :
-                 FunDataBase (&FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::FunData6 (const FunData6 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  FunDataBase *
-  FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::clone () const 
-  {
-    return new FunData6 (*this);
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 2 arguments.
+                                    */
+  template <typename RT, typename C, typename Arg1, typename Arg2>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2)) {
+    return internal::mem_fun_encapsulator<RT, C, boost::tuple<Arg1, Arg2> > (c,fun_ptr);
+  }
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  void *
-  FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-  
-    return 0;
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 2
+                                    * arguments.
+                                    */
+  template <typename RT, typename C, typename Arg1, typename Arg2>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,boost::tuple<Arg1, Arg2> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2) const) {
+    return internal::mem_fun_encapsulator<RT, const C, boost::tuple<Arg1, Arg2> > (c,fun_ptr);
   }
 
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
+// ----------- encapsulators for ternary member functions
 
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 3 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 3>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
 
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  FunEncapsulation
-  FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::ArgCollector::collect_args (Arg1 arg1,
-                                                                              Arg2 arg2,
-                                                                              Arg3 arg3,
-                                                                              Arg4 arg4,
-                                                                              Arg5 arg5,
-                                                                              Arg6 arg6)
-  {
-    return new FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,void>(fun_ptr, arg1, arg2,
-                                                           arg3, arg4, arg5, arg6);
-  }
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,
+                                                           arg2,
+                                                           arg3)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
+  }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 3 arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2, Arg3> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3)) {
+    return internal::mem_fun_encapsulator<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3> > (c,fun_ptr);
+  }
 
-/* ---------------------- FunData7 implementation ------------------------ */
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::FunData7 (FunPtr fun_ptr,
-                                                                 Arg1   arg1,
-                                                                 Arg2   arg2,
-                                                                 Arg3   arg3,
-                                                                 Arg4   arg4,
-                                                                 Arg5   arg5,
-                                                                 Arg6   arg6,
-                                                                 Arg7   arg7) :
-                 FunDataBase (&FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6),
-                 arg7 (arg7)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::FunData7 (const FunData7 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6),
-                 arg7 (fun_data.arg7)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  FunDataBase *
-  FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::clone () const 
-  {
-    return new FunData7 (*this);
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 3
+                                    * arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,boost::tuple<Arg1, Arg2, Arg3> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const) {
+    return internal::mem_fun_encapsulator<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3> > (c,fun_ptr);
   }
 
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  void *
-  FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-    Arg7              arg7    = fun_data->arg7;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-  
-    return 0;
-  }
 
+// ----------- encapsulators for member functions with 4 arguments
 
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 4 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 4>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,arg2,
+                                                           arg3,arg4)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
+  
+  }
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  FunEncapsulation
-  FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::ArgCollector::collect_args (Arg1 arg1,
-                                                                                   Arg2 arg2,
-                                                                                   Arg3 arg3,
-                                                                                   Arg4 arg4,
-                                                                                   Arg5 arg5,
-                                                                                   Arg6 arg6,
-                                                                                   Arg7 arg7)
-  {
-    return new FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,void>(fun_ptr, arg1, arg2,
-                                                                arg3, arg4, arg5, arg6, arg7);
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 4 arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2, Arg3, Arg4> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4)) {
+    return internal::mem_fun_encapsulator<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3, Arg4> > (c,fun_ptr);
   }
-  
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 4
+                                    * arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,boost::tuple<Arg1, Arg2, Arg3, Arg4> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const) {
+    return internal::mem_fun_encapsulator<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3, Arg4> > (c,fun_ptr);
+  }
 
 
-/* ---------------------- FunData8 implementation ------------------------ */
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::
-  FunData8 (FunPtr fun_ptr,
-           Arg1   arg1,
-           Arg2   arg2,
-           Arg3   arg3,
-           Arg4   arg4,
-           Arg5   arg5,
-           Arg6   arg6,
-           Arg7   arg7,
-           Arg8   arg8) :
-                 FunDataBase (&FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6),
-                 arg7 (arg7),
-                 arg8 (arg8)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::
-  FunData8 (const FunData8 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6),
-                 arg7 (fun_data.arg7),
-                 arg8 (fun_data.arg8)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  FunDataBase *
-  FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::clone () const 
-  {
-    return new FunData8 (*this);
-  }
 
 
+// ----------- encapsulators for member functions with 5 arguments
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  void *
-  FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::thread_entry_point (void *arg) 
+  namespace internal
   {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-    Arg7              arg7    = fun_data->arg7;
-    Arg8              arg8    = fun_data->arg8;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 5 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 5>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,arg2,
+                                                           arg3,arg4,
+                                                           arg5)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 5 arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5)) {
+    return internal::mem_fun_encapsulator<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5> > (c,fun_ptr);
+  }
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 5
+                                    * arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const) {
+    return internal::mem_fun_encapsulator<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5> > (c,fun_ptr);
+  }
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  FunEncapsulation
-  FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::ArgCollector::collect_args (Arg1 arg1,
-                                                                                        Arg2 arg2,
-                                                                                        Arg3 arg3,
-                                                                                        Arg4 arg4,
-                                                                                        Arg5 arg5,
-                                                                                        Arg6 arg6,
-                                                                                        Arg7 arg7,
-                                                                                        Arg8 arg8)
-  {
-    return new FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,void>(fun_ptr, arg1, arg2,
-                                                                     arg3, arg4, arg5, arg6,
-                                                                     arg7, arg8);
-  }
+// ----------- encapsulators for member functions with 6 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 6 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 6>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,arg2,
+                                                           arg3,arg4,
+                                                           arg5,arg6)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
+  }
 
-/* ---------------------- FunData9 implementation ------------------------ */
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::
-  FunData9 (FunPtr fun_ptr,
-           Arg1   arg1,
-           Arg2   arg2,
-           Arg3   arg3,
-           Arg4   arg4,
-           Arg5   arg5,
-           Arg6   arg6,
-           Arg7   arg7,
-           Arg8   arg8,
-           Arg9   arg9) :
-                 FunDataBase (&FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6),
-                 arg7 (arg7),
-                 arg8 (arg8),
-                 arg9 (arg9)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::
-  FunData9 (const FunData9 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6),
-                 arg7 (fun_data.arg7),
-                 arg8 (fun_data.arg8),
-                 arg9 (fun_data.arg9)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  FunDataBase *
-  FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::clone () const 
-  {
-    return new FunData9 (*this);
+
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 6 arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6)) {
+    return internal::mem_fun_encapsulator<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6> > (c,fun_ptr);
   }
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 6
+                                    * arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,
+                               boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const) {
+    return internal::mem_fun_encapsulator<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6> > (c,fun_ptr);
+  }
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  void *
-  FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-    Arg7              arg7    = fun_data->arg7;
-    Arg8              arg8    = fun_data->arg8;
-    Arg9              arg9    = fun_data->arg9;    
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+// ----------- encapsulators for member functions with 7 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 7 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 7>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,arg2,
+                                                           arg3,arg4,
+                                                           arg5,arg6,
+                                                           arg7)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 7 arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2, Arg3,
+                                                 Arg4, Arg5, Arg6, Arg7> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7)) {
+    return internal::mem_fun_encapsulator<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7> > (c,fun_ptr);
+  }
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 7
+                                    * arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,
+                               boost::tuple<Arg1, Arg2, Arg3,
+                                            Arg4, Arg5, Arg6, Arg7> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const) {
+    return internal::mem_fun_encapsulator<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7> > (c,fun_ptr);
+  }
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  FunEncapsulation
-  FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::ArgCollector::
-  collect_args (Arg1 arg1,
-               Arg2 arg2,
-               Arg3 arg3,
-               Arg4 arg4,
-               Arg5 arg5,
-               Arg6 arg6,
-               Arg7 arg7,
-               Arg8 arg8,
-               Arg9 arg9)
-  {
-    return
-      new FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,void>
-      (fun_ptr, arg1, arg2,
-       arg3, arg4, arg5, arg6,
-       arg7, arg8, arg9);
-  }
+// ----------- encapsulators for member functions with 8 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 8 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 8>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,arg2,
+                                                           arg3,arg4,
+                                                           arg5,arg6,
+                                                           arg7,arg8)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
+  }
 
-/* ---------------------- FunData10 implementation ------------------------ */
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::
-  FunData10 (FunPtr fun_ptr,
-            Arg1   arg1,
-            Arg2   arg2,
-            Arg3   arg3,
-            Arg4   arg4,
-            Arg5   arg5,
-            Arg6   arg6,
-            Arg7   arg7,
-            Arg8   arg8,
-            Arg9   arg9,
-            Arg10  arg10) :
-                 FunDataBase (&FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6),
-                 arg7 (arg7),
-                 arg8 (arg8),
-                 arg9 (arg9),
-                 arg10 (arg10)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::
-  FunData10 (const FunData10 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6),
-                 arg7 (fun_data.arg7),
-                 arg8 (fun_data.arg8),
-                 arg9 (fun_data.arg9),
-                 arg10 (fun_data.arg10)
-  {}
-
-
-
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  FunDataBase *
-  FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::clone () const 
-  {
-    return new FunData10 (*this);
+
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 8 arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2, Arg3,
+                                                 Arg4, Arg5, Arg6,
+                                                 Arg7, Arg8> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                Arg6,Arg7,Arg8)) {
+    return internal::mem_fun_encapsulator<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8> > (c,fun_ptr);
   }
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 8
+                                    * arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,
+                               boost::tuple<Arg1, Arg2, Arg3,
+                                            Arg4, Arg5, Arg6,
+                                            Arg7, Arg8> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                      Arg6,Arg7,Arg8) const) {
+    return internal::mem_fun_encapsulator<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8> > (c,fun_ptr);
+  }
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  void *
-  FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-    Arg7              arg7    = fun_data->arg7;
-    Arg8              arg8    = fun_data->arg8;
-    Arg9              arg9    = fun_data->arg9;
-    Arg10             arg10   = fun_data->arg10;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+// ----------- encapsulators for member functions with 9 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 9 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 9>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8,
+                    typename boost::tuples::element<8,ArgList>::type arg9) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,arg2,
+                                                           arg3,arg4,
+                                                           arg5,arg6,
+                                                           arg7,arg8,
+                                                           arg9)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 9 arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2, Arg3,
+                                                 Arg4, Arg5, Arg6,
+                                                 Arg7, Arg8, Arg9> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                Arg6,Arg7,Arg8,Arg9)) {
+    return internal::mem_fun_encapsulator<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9> > (c,fun_ptr);
+  }
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 9
+                                    * arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,
+                               boost::tuple<Arg1, Arg2, Arg3,
+                                            Arg4, Arg5, Arg6,
+                                            Arg7, Arg8, Arg9> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                      Arg6,Arg7,Arg8,Arg9) const) {
+    return internal::mem_fun_encapsulator<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9> > (c,fun_ptr);
+  }
 
 
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  FunEncapsulation
-  FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::ArgCollector::
-  collect_args (Arg1 arg1,
-               Arg2 arg2,
-               Arg3 arg3,
-               Arg4 arg4,
-               Arg5 arg5,
-               Arg6 arg6,
-               Arg7 arg7,
-               Arg8 arg8,
-               Arg9 arg9,
-               Arg10 arg10)
-  {
-    return
-      new FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,void>
-      (fun_ptr, arg1, arg2,
-       arg3, arg4, arg5, arg6,
-       arg7, arg8, arg9, arg10);
-  }
+// ----------- encapsulators for member functions with 10 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for member
+                                      * functions with 10 arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_encapsulator<RT, C, ArgList, 10>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_encapsulator (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8,
+                    typename boost::tuples::element<8,ArgList>::type arg9,
+                    typename boost::tuples::element<9,ArgList>::type arg10) {
+          return mem_fun_wrapper<RT,C,ArgList> (mem_fun_ptr, c,
+                                                boost::tie(arg1,arg2,
+                                                           arg3,arg4,
+                                                           arg5,arg6,
+                                                           arg7,arg8,
+                                                           arg9, arg10)).fire_up ();
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
+  }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 10 arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9,
+            typename Arg10>
+  inline
+  internal::mem_fun_encapsulator<RT,C,boost::tuple<Arg1, Arg2, Arg3,
+                                                 Arg4, Arg5, Arg6,
+                                                 Arg7, Arg8, Arg9, Arg10> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                Arg6,Arg7,Arg8,Arg9,Arg10)) {
+    return internal::mem_fun_encapsulator<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9,
+      Arg10> > (c,fun_ptr);
+  }
 
-/* ---------------------- MemFunData0 implementation ------------------------ */
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 10
+                                    * arguments.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9,
+            typename Arg10>
+  inline
+  internal::mem_fun_encapsulator<RT,const C,
+                               boost::tuple<Arg1, Arg2, Arg3,
+                                            Arg4, Arg5, Arg6,
+                                            Arg7, Arg8, Arg9, Arg10> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                      Arg6,Arg7,Arg8,Arg9,Arg10) const) {
+    return internal::mem_fun_encapsulator<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9,
+      Arg10> > (c,fun_ptr);
+  }
 
-  template <class Class, typename RetType>
-  MemFunData0<Class,RetType>::MemFunData0 (FunPtr  fun_ptr,
-                                          Class  *object) :
-                 FunDataBase (&MemFunData0<Class,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object)
-  {}
 
 
+// ----------- encapsulators for functions not taking any parameters
 
-  template <class Class, typename RetType>
-  MemFunData0<Class,RetType>::MemFunData0 (const MemFunData0 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object)
-  {}
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with no arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 0>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() () {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          ArgList()).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
+  
+  }
 
-  template <class Class, typename RetType>
-  FunDataBase *
-  MemFunData0<Class,RetType>::clone () const 
-  {
-    return new MemFunData0 (*this);
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with no arguments.
+                                    */
+  template <typename RT>
+  inline
+  internal::fun_encapsulator<RT,boost::tuple<> >
+  spawn (RT (*fun_ptr)()) {
+    return internal::fun_encapsulator<RT, boost::tuple<> > (fun_ptr);
   }
 
 
 
-  template <class Class, typename RetType>
-  void *
-  MemFunData0<Class,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData0<Class,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)();
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-  
-    return 0;
-  }
 
+// ----------- encapsulators for unary functions
 
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 1 argument.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 1>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
-  template <class Class, typename RetType>
-  MemFunData0<Class,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-       
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename RetType>
-  FunEncapsulation
-  MemFunData0<Class,RetType>::ArgCollector::collect_args (Class *object)
-  {
-    return new MemFunData0<Class,void>(fun_ptr, object);
   }
 
-
-  template <class Class, typename RetType>
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 1 argument.
+                                    */
+  template <typename RT, typename Arg1>
   inline
-  FunEncapsulation
-  MemFunData0<Class,RetType>::ArgCollector::collect_args (Class &object)
-  {
-    return collect_args (&object);
+  internal::fun_encapsulator<RT,boost::tuple<Arg1> >
+  spawn (RT (*fun_ptr)(Arg1)) {
+    return internal::fun_encapsulator<RT, boost::tuple<Arg1> > (fun_ptr);
   }
 
 
-/* ---------------------- MemFunData1 implementation ------------------------ */
 
-  template <class Class, typename Arg1, typename RetType>
-  MemFunData1<Class,Arg1,RetType>::MemFunData1 (FunPtr  fun_ptr,
-                                               Class  *object,
-                                               Arg1    arg1) :
-                 FunDataBase (&MemFunData1<Class,Arg1,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1)
-  {}
 
+// ----------- encapsulators for binary functions
 
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 2 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 2>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
-  template <class Class, typename Arg1, typename RetType>
-  MemFunData1<Class,Arg1,RetType>::MemFunData1 (const MemFunData1 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1)
-  {}
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,
+                                                     arg2)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
+  
+  }
 
 
-  template <class Class, typename Arg1, typename RetType>
-  FunDataBase *
-  MemFunData1<Class,Arg1,RetType>::clone () const 
-  {
-    return new MemFunData1 (*this);
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 2 arguments.
+                                    */
+  template <typename RT, typename Arg1, typename Arg2>
+  inline
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2)) {
+    return internal::fun_encapsulator<RT, boost::tuple<Arg1, Arg2> > (fun_ptr);
   }
 
 
 
-  template <class Class, typename Arg1, typename RetType>
-  void *
-  MemFunData1<Class,Arg1,RetType>::thread_entry_point (void *arg) 
+// ----------- encapsulators for ternary functions
+
+  namespace internal
   {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData1<Class,Arg1,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 3 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 3>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,
+                                                     arg2,
+                                                     arg3)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 3 arguments.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3>
+  inline
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2, Arg3> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3)) {
+    return internal::fun_encapsulator<RT,
+      boost::tuple<Arg1, Arg2, Arg3> > (fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename RetType>
-  MemFunData1<Class,Arg1,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-       
 
-  template <class Class, typename Arg1, typename RetType>
-  FunEncapsulation
-  MemFunData1<Class,Arg1,RetType>::ArgCollector::collect_args (Class *object,
-                                                              Arg1   arg1)
-  {
-    return new MemFunData1<Class,Arg1,void>(fun_ptr, object, arg1);
-  }
-  
 
-  template <class Class, typename Arg1, typename RetType>
-  inline
-  FunEncapsulation
-  MemFunData1<Class,Arg1,RetType>::ArgCollector::collect_args (Class &object,
-                                                              Arg1   arg1)
+
+// ----------- encapsulators for functions with 4 arguments
+
+  namespace internal
   {
-    return collect_args (&object, arg1);
-  }
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 4 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 4>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,arg2,
+                                                     arg3,arg4)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-/* ---------------------- MemFunData2 implementation ------------------------ */
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename RetType>
-  MemFunData2<Class,Arg1,Arg2,RetType>::MemFunData2 (FunPtr  fun_ptr,
-                                                    Class  *object,
-                                                    Arg1    arg1,
-                                                    Arg2    arg2) :
-                 FunDataBase (&MemFunData2<Class,Arg1,Arg2,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2)
-  {}
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 4 arguments.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  inline
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2, Arg3, Arg4> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4)) {
+    return internal::fun_encapsulator<RT,
+      boost::tuple<Arg1, Arg2, Arg3, Arg4> > (fun_ptr);
+  }
 
 
-  template <class Class, typename Arg1, typename Arg2, typename RetType>
-  MemFunData2<Class,Arg1,Arg2,RetType>::MemFunData2 (const MemFunData2 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2)
-  {}
 
 
+// ----------- encapsulators for functions with 5 arguments
 
-  template <class Class, typename Arg1, typename Arg2, typename RetType>
-  FunDataBase *
-  MemFunData2<Class,Arg1,Arg2,RetType>::clone () const 
+  namespace internal
   {
-    return new MemFunData2 (*this);
-  }
-
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 5 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 5>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
-  template <class Class, typename Arg1, typename Arg2, typename RetType>
-  void *
-  MemFunData2<Class,Arg1,Arg2,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData2<Class,Arg1,Arg2,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,arg2,
+                                                     arg3,arg4,
+                                                     arg5)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 5 arguments.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5>
+  inline
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5)) {
+    return internal::fun_encapsulator<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5> > (fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename RetType>
-  MemFunData2<Class,Arg1,Arg2,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-       
 
+// ----------- encapsulators for functions with 6 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 6 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 6>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,arg2,
+                                                     arg3,arg4,
+                                                     arg5,arg6)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename RetType>
-  FunEncapsulation
-  MemFunData2<Class,Arg1,Arg2,RetType>::ArgCollector::collect_args (Class *object,
-                                                                   Arg1   arg1,
-                                                                   Arg2   arg2)
-  {
-    return new MemFunData2<Class,Arg1,Arg2,void>(fun_ptr, object, arg1, arg2);
   }
-  
-  template <class Class, typename Arg1, typename Arg2, typename RetType>
+
+
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 6 arguments.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6>
   inline
-  FunEncapsulation
-  MemFunData2<Class,Arg1,Arg2,RetType>::ArgCollector::collect_args (Class &object,
-                                                                   Arg1   arg1,
-                                                                   Arg2   arg2)
-  {
-    return collect_args (&object, arg1, arg2);
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6)) {
+    return internal::fun_encapsulator<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6> > (fun_ptr);
   }
-  
 
 
-/* ---------------------- MemFunData3 implementation ------------------------ */
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::MemFunData3 (FunPtr  fun_ptr,
-                                                         Class  *object,
-                                                         Arg1    arg1,
-                                                         Arg2    arg2,
-                                                         Arg3    arg3) :
-                 FunDataBase (&MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3)
-  {}
+// ----------- encapsulators for functions with 7 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 7 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 7>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,arg2,
+                                                     arg3,arg4,
+                                                     arg5,arg6,
+                                                     arg7)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
+  
+  }
 
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 7 arguments.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7>
+  inline
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2, Arg3,
+                                           Arg4, Arg5, Arg6, Arg7> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7)) {
+    return internal::fun_encapsulator<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7> > (fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::MemFunData3 (const MemFunData3 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3)
-  {}
 
+// ----------- encapsulators for functions with 8 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 8 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 8>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,arg2,
+                                                     arg3,arg4,
+                                                     arg5,arg6,
+                                                     arg7,arg8)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
+  
+  }
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  FunDataBase *
-  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::clone () const 
-  {
-    return new MemFunData3 (*this);
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 8 arguments.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8>
+  inline
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2, Arg3,
+                                           Arg4, Arg5, Arg6,
+                                           Arg7, Arg8> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                       Arg6,Arg7,Arg8)) {
+    return internal::fun_encapsulator<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8> > (fun_ptr);
   }
 
 
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  void *
-  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData3<Class,Arg1,Arg2,Arg3,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2, arg3);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+// ----------- encapsulators for functions with 9 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 9 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 9>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8,
+                    typename boost::tuples::element<8,ArgList>::type arg9) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,arg2,
+                                                     arg3,arg4,
+                                                     arg5,arg6,
+                                                     arg7,arg8,
+                                                     arg9)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 9 arguments.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9>
+  inline
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2, Arg3,
+                                           Arg4, Arg5, Arg6,
+                                           Arg7, Arg8, Arg9> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                       Arg6,Arg7,Arg8,Arg9)) {
+    return internal::fun_encapsulator<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9> > (fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-       
 
+// ----------- encapsulators for functions with 10 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Encapsulator class for
+                                      * functions with 10 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_encapsulator<RT, ArgList, 10>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_encapsulator (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8,
+                    typename boost::tuples::element<8,ArgList>::type arg9,
+                    typename boost::tuples::element<9,ArgList>::type arg10) {
+          return fun_wrapper<RT,ArgList> (fun_ptr,
+                                          boost::tie(arg1,arg2,
+                                                     arg3,arg4,
+                                                     arg5,arg6,
+                                                     arg7,arg8,
+                                                     arg9, arg10)).fire_up ();
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
-  FunEncapsulation
-  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::ArgCollector::collect_args (Class *object,
-                                                                        Arg1   arg1,
-                                                                        Arg2   arg2,
-                                                                        Arg3   arg3)
-  {
-    return new MemFunData3<Class,Arg1,Arg2,Arg3,void>(fun_ptr, object,
-                                                     arg1, arg2, arg3);
   }
-  
-  
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
+
+
+                                   /**
+                                    * Overload of the spawn function for
+                                    * non-member or static member
+                                    * functions with 10 arguments.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9,
+            typename Arg10>
   inline
-  FunEncapsulation
-  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::ArgCollector::collect_args (Class &object,
-                                                                        Arg1   arg1,
-                                                                        Arg2   arg2,
-                                                                        Arg3   arg3)
-  {
-    return collect_args (&object, arg1, arg2, arg3);
+  internal::fun_encapsulator<RT,boost::tuple<Arg1, Arg2, Arg3,
+                                           Arg4, Arg5, Arg6,
+                                           Arg7, Arg8, Arg9, Arg10> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                       Arg6,Arg7,Arg8,Arg9,Arg10)) {
+    return internal::fun_encapsulator<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9,
+      Arg10> > (fun_ptr);
   }
-  
 
+#else  // #if (DEAL_II_USE_MT == 1)
 
-/* ---------------------- MemFunData4 implementation ------------------------ */
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::MemFunData4 (FunPtr  fun_ptr,
-                                                              Class  *object,
-                                                              Arg1    arg1,
-                                                              Arg2    arg2,
-                                                              Arg3    arg3,
-                                                              Arg4    arg4) :
-                 FunDataBase (&MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4)
-  {}
+  template <typename RT = void>
+  class Thread 
+  {
+    public:
+                                       /**
+                                        * Default constructor.
+                                        */
+      Thread ()  {};
 
+                                       /**
+                                        * Initialize the return value
+                                        * of this object using the
+                                        * given member-function
+                                        * pointer, object, and
+                                        * argument list.
+                                        */
+      template <typename PFun, typename C, typename ArgRefs>
+      Thread (PFun     fun_ptr,
+              C       &obj,
+              ArgRefs  arg_refs)
+        {
+          internal::call (fun_ptr, obj, arg_refs, rv);
+        };
 
+                                       /**
+                                        * Initialize the return value
+                                        * of this object using the
+                                        * given function pointer, and
+                                        * argument list.
+                                        */
+      template <typename PFun, typename ArgRefs>
+      Thread (PFun    fun_ptr,
+              ArgRefs arg_refs)
+        {
+          internal::call (fun_ptr, arg_refs, rv);
+        };
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::MemFunData4 (const MemFunData4 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4)
-  {}
+                                       /**
+                                        * Get the return value of the
+                                        * function of the
+                                        * thread.
+                                        */
+      RT return_value () const 
+        {
+          return rv.get();
+        };
 
+                                       /**
+                                        * Join this thread. Is of
+                                        * course a no-op in this of no
+                                        * thread support.
+                                        */
+      void join () const {};
 
+                                       /**
+                                        * Compare for equality of
+                                        * threads. Since thrheads are
+                                        * not supported, there can
+                                        * only be exactly one thread,
+                                        * and the result is
+                                        * @p{true}. This function
+                                        * doesn't make much sense,
+                                        * though, when threads are not
+                                        * supported.
+                                        */
+      bool operator == (const Thread &)
+        {
+          return true;
+        };
+      
+    private:
+                                       /**
+                                        * Store the return value of
+                                        * the thread function.
+                                        */
+      internal::return_value<RT> rv;
+  };
+  
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  FunDataBase *
-  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::clone () const 
-  {
-    return new MemFunData4 (*this);
+  namespace internal
+  {
+                                     /**
+                                      * General template declaration
+                                      * of a class that is used to
+                                      * forward arguments to
+                                      * global and static member
+                                      * functions.
+                                      *
+                                      * Although this general template
+                                      * is not implemented at all, the
+                                      * default template argument
+                                      * makes sure that whenever using
+                                      * the name of this class, the
+                                      * last template argument will be
+                                      * computed correctly from the
+                                      * previous arguments, and the
+                                      * correct specialization for
+                                      * this last template argument be
+                                      * used, even though we need to
+                                      * specify it.
+                                      */
+    template <typename RT, typename ArgList,
+              int length = boost::tuples::length<ArgList>::value>
+    class fun_forwarder;
+
+                                     /**
+                                      * General template declaration
+                                      * of a class that is used to
+                                      * forward arguments to
+                                      * non-static member functions.
+                                      *
+                                      * Although this general template
+                                      * is not implemented at all, the
+                                      * default template argument
+                                      * makes sure that whenever using
+                                      * the name of this class, the
+                                      * last template argument will be
+                                      * computed correctly from the
+                                      * previous arguments, and the
+                                      * correct specialization for
+                                      * this last template argument be
+                                      * used, even though we need to
+                                      * specify it.
+                                      */
+    template <typename RT, typename C, typename ArgList,
+              int length = boost::tuples::length<ArgList>::value>
+    class mem_fun_forwarder;    
   }
 
 
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  void *
-  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::thread_entry_point (void *arg) 
+  namespace internal
   {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2, arg3, arg4);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with no arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 0>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() () {
+          return Thread<RT> (mem_fun_ptr, c,
+                             ArgList());
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with no arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C>
+  inline
+  internal::mem_fun_forwarder<RT,C,boost::tuple<> >
+  spawn (C &c, RT (C::*fun_ptr)()) {
+    return internal::mem_fun_forwarder<RT, C, boost::tuple<> > (c,fun_ptr);
+  }
+
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * no arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C>
+  inline
+  internal::mem_fun_forwarder<RT,const C,boost::tuple<> >
+  spawn (const C &c, RT (C::*fun_ptr)() const) {
+    return internal::mem_fun_forwarder<RT, const C, boost::tuple<> > (c,fun_ptr);
+  }
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
 
 
+// ----------- forwarders for unary member functions
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
-  FunEncapsulation
-  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::collect_args (Class *object,
-                                                                             Arg1   arg1,
-                                                                             Arg2   arg2,
-                                                                             Arg3   arg3,
-                                                                             Arg4   arg4)
+  namespace internal
   {
-    return new MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,void>(fun_ptr, object,
-                                                          arg1, arg2, arg3, arg4);
-  }
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 1 argument.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 1>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions with
+                                    * 1 argument. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C, typename Arg1>
   inline
-  FunEncapsulation
-  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::collect_args (Class &object,
-                                                                             Arg1   arg1,
-                                                                             Arg2   arg2,
-                                                                             Arg3   arg3,
-                                                                             Arg4   arg4)
-  {
-    return collect_args (&object, arg1, arg2, arg3, arg4);
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1)) {
+    return internal::mem_fun_forwarder<RT, C, boost::tuple<Arg1> > (c,fun_ptr);
   }
-  
 
-/* ---------------------- MemFunData5 implementation ------------------------ */
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::MemFunData5 (FunPtr  fun_ptr,
-                                                                   Class  *object,
-                                                                   Arg1    arg1,
-                                                                   Arg2    arg2,
-                                                                   Arg3    arg3,
-                                                                   Arg4    arg4,
-                                                                   Arg5    arg5) :
-                 FunDataBase (&MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::MemFunData5 (const MemFunData5 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  FunDataBase *
-  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::clone () const 
-  {
-    return new MemFunData5 (*this);
+                                   /**
+                                    * Overload of the spawn function for
+                                    * const member functions with 1
+                                    * argument. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C, typename Arg1>
+  inline
+  internal::mem_fun_forwarder<RT,const C,boost::tuple<Arg1> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1) const) {
+    return internal::mem_fun_forwarder<RT, const C, boost::tuple<Arg1> > (c,fun_ptr);
   }
 
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  void *
-  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::thread_entry_point (void *arg) 
+
+// ----------- forwarders for binary member functions
+
+  namespace internal
   {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 2
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 2>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,
+                                        arg2));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 2 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C, typename Arg1, typename Arg2>
+  inline
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2)) {
+    return internal::mem_fun_forwarder<RT, C, boost::tuple<Arg1, Arg2> > (c,fun_ptr);
+  }
+
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 2 arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT, typename C, typename Arg1, typename Arg2>
+  inline
+  internal::mem_fun_forwarder<RT,const C,boost::tuple<Arg1, Arg2> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2) const) {
+    return internal::mem_fun_forwarder<RT, const C, boost::tuple<Arg1, Arg2> > (c,fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
 
 
+// ----------- forwarders for ternary member functions
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
-  FunEncapsulation
-  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::collect_args (Class *object,
-                                                                                  Arg1   arg1,
-                                                                                  Arg2   arg2,
-                                                                                  Arg3   arg3,
-                                                                                  Arg4   arg4,
-                                                                                  Arg5   arg5)
+  namespace internal
   {
-    return new MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,void>(fun_ptr, object,
-                                                               arg1, arg2, arg3, arg4, arg5);
-  }
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 3
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 3>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,
+                                        arg2,
+                                        arg3));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  }
+
+
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 3 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3>
   inline
-  FunEncapsulation
-  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::collect_args (Class &object,
-                                                                                  Arg1   arg1,
-                                                                                  Arg2   arg2,
-                                                                                  Arg3   arg3,
-                                                                                  Arg4   arg4,
-                                                                                  Arg5   arg5)
-  {
-    return collect_args (&object, arg1, arg2, arg3, arg4, arg5);
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2, Arg3> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3)) {
+    return internal::mem_fun_forwarder<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3> > (c,fun_ptr);
   }
-  
 
-  
-/* ---------------------- MemFunData6 implementation ------------------------ */
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::MemFunData6 (FunPtr  fun_ptr,
-                                                                        Class  *object,
-                                                                        Arg1    arg1,
-                                                                        Arg2    arg2,
-                                                                        Arg3    arg3,
-                                                                        Arg4    arg4,
-                                                                        Arg5    arg5,
-                                                                        Arg6    arg6) :
-                 FunDataBase (&MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::MemFunData6 (const MemFunData6 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  FunDataBase *
-  MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::clone () const 
-  {
-    return new MemFunData6 (*this);
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 3 arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3>
+  inline
+  internal::mem_fun_forwarder<RT,const C,boost::tuple<Arg1, Arg2, Arg3> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const) {
+    return internal::mem_fun_forwarder<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3> > (c,fun_ptr);
   }
 
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  void *
-  MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::thread_entry_point (void *arg) 
+
+// ----------- forwarders for member functions with 4 arguments
+
+  namespace internal
   {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 4
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 4>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 4 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  inline
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2, Arg3, Arg4> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4)) {
+    return internal::mem_fun_forwarder<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3, Arg4> > (c,fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 4 arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  inline
+  internal::mem_fun_forwarder<RT,const C,boost::tuple<Arg1, Arg2, Arg3, Arg4> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const) {
+    return internal::mem_fun_forwarder<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3, Arg4> > (c,fun_ptr);
+  }
 
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  FunEncapsulation
-  MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::ArgCollector::collect_args (Class *object,
-                                                                                       Arg1   arg1,
-                                                                                       Arg2   arg2,
-                                                                                       Arg3   arg3,
-                                                                                       Arg4   arg4,
-                                                                                       Arg5   arg5,
-                                                                                       Arg6   arg6)
-  {
-    return new MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,void>(fun_ptr, object,
-                                                                    arg1, arg2, arg3, arg4, arg5, arg6);
-  }
-  
 
+// ----------- forwarders for member functions with 5 arguments
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename RetType>
-  inline
-  FunEncapsulation
-  MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,RetType>::ArgCollector::collect_args (Class &object,
-                                                                                       Arg1   arg1,
-                                                                                       Arg2   arg2,
-                                                                                       Arg3   arg3,
-                                                                                       Arg4   arg4,
-                                                                                       Arg5   arg5,
-                                                                                       Arg6   arg6)
+  namespace internal
   {
-    return collect_args (&object, arg1, arg2, arg3, arg4, arg5, arg6);
-  }
-
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 5
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 5>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
 
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
+  }
 
-/* ---------------------- MemFunData7 implementation ------------------------ */
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::MemFunData7 (FunPtr  fun_ptr,
-                                                                             Class  *object,
-                                                                             Arg1    arg1,
-                                                                             Arg2    arg2,
-                                                                             Arg3    arg3,
-                                                                             Arg4    arg4,
-                                                                             Arg5    arg5,
-                                                                             Arg6    arg6,
-                                                                             Arg7    arg7) :
-                 FunDataBase (&MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6),
-                 arg7 (arg7)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::MemFunData7 (const MemFunData7 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6),
-                 arg7 (fun_data.arg7)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  FunDataBase *
-  MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::clone () const 
-  {
-    return new MemFunData7 (*this);
+
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 5 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5>
+  inline
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5)) {
+    return internal::mem_fun_forwarder<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5> > (c,fun_ptr);
   }
 
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 5 arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5>
+  inline
+  internal::mem_fun_forwarder<RT,const C,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const) {
+    return internal::mem_fun_forwarder<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5> > (c,fun_ptr);
+  }
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  void *
-  MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-    Arg7              arg7    = fun_data->arg7;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+// ----------- forwarders for member functions with 6 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 6
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 6>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 6 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6>
+  inline
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6)) {
+    return internal::mem_fun_forwarder<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6> > (c,fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
-
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 6 arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6>
+  inline
+  internal::mem_fun_forwarder<RT,const C,
+                              boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const) {
+    return internal::mem_fun_forwarder<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6> > (c,fun_ptr);
+  }
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
-  FunEncapsulation
-  MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::ArgCollector::collect_args (Class *object,
-                                                                                            Arg1   arg1,
-                                                                                            Arg2   arg2,
-                                                                                            Arg3   arg3,
-                                                                                            Arg4   arg4,
-                                                                                            Arg5   arg5,
-                                                                                            Arg6   arg6,
-                                                                                            Arg7   arg7)
-  {
-    return new MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,void>(fun_ptr, object,
-                                                                         arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-  }
+// ----------- forwarders for member functions with 7 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 7
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 7>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6,
+                                        arg7));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
+  }
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename RetType>
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 7 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7>
   inline
-  FunEncapsulation
-  MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,RetType>::ArgCollector::collect_args (Class &object,
-                                                                                            Arg1   arg1,
-                                                                                            Arg2   arg2,
-                                                                                            Arg3   arg3,
-                                                                                            Arg4   arg4,
-                                                                                            Arg5   arg5,
-                                                                                            Arg6   arg6,
-                                                                                            Arg7   arg7)
-  {
-    return collect_args (&object, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2, Arg3,
+                                                Arg4, Arg5, Arg6, Arg7> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7)) {
+    return internal::mem_fun_forwarder<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7> > (c,fun_ptr);
   }
-  
 
-/* ---------------------- MemFunData8 implementation ------------------------ */
-  
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::MemFunData8 (FunPtr  fun_ptr,
-                                                                                  Class  *object,
-                                                                                  Arg1    arg1,
-                                                                                  Arg2    arg2,
-                                                                                  Arg3    arg3,
-                                                                                  Arg4    arg4,
-                                                                                  Arg5    arg5,
-                                                                                  Arg6    arg6,
-                                                                                  Arg7    arg7,
-                                                                                  Arg8    arg8) :
-                 FunDataBase (&MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6),
-                 arg7 (arg7),
-                 arg8 (arg8)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::MemFunData8 (const MemFunData8 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6),
-                 arg7 (fun_data.arg7),
-                 arg8 (fun_data.arg8)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  FunDataBase *
-  MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::clone () const 
-  {
-    return new MemFunData8 (*this);
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 7 arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7>
+  inline
+  internal::mem_fun_forwarder<RT,const C,
+                              boost::tuple<Arg1, Arg2, Arg3,
+                                           Arg4, Arg5, Arg6, Arg7> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const) {
+    return internal::mem_fun_forwarder<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7> > (c,fun_ptr);
   }
 
 
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  void *
-  MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-    Arg7              arg7    = fun_data->arg7;
-    Arg8              arg8    = fun_data->arg8;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+// ----------- forwarders for member functions with 8 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 8
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 8>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6,
+                                        arg7,arg8));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-    return 0;
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 8 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8>
+  inline
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2, Arg3,
+                                                Arg4, Arg5, Arg6,
+                                                Arg7, Arg8> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                Arg6,Arg7,Arg8)) {
+    return internal::mem_fun_forwarder<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8> > (c,fun_ptr);
+  }
+
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 8 arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8>
+  inline
+  internal::mem_fun_forwarder<RT,const C,
+                              boost::tuple<Arg1, Arg2, Arg3,
+                                           Arg4, Arg5, Arg6,
+                                           Arg7, Arg8> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                      Arg6,Arg7,Arg8) const) {
+    return internal::mem_fun_forwarder<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8> > (c,fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
 
+// ----------- forwarders for member functions with 9 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 9
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 9>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8,
+                    typename boost::tuples::element<8,ArgList>::type arg9) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6,
+                                        arg7,arg8,
+                                        arg9));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
+  
+  }
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
-  FunEncapsulation
-  MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::ArgCollector::collect_args (Class *object,
-                                                                                                 Arg1   arg1,
-                                                                                                 Arg2   arg2,
-                                                                                                 Arg3   arg3,
-                                                                                                 Arg4   arg4,
-                                                                                                 Arg5   arg5,
-                                                                                                 Arg6   arg6,
-                                                                                                 Arg7   arg7,
-                                                                                                 Arg8   arg8)
-  {
-    return new MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,void>(fun_ptr, object,
-                                                                              arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 9 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9>
+  inline
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2, Arg3,
+                                                Arg4, Arg5, Arg6,
+                                                Arg7, Arg8, Arg9> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                Arg6,Arg7,Arg8,Arg9)) {
+    return internal::mem_fun_forwarder<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9> > (c,fun_ptr);
   }
-  
 
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename RetType>
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 9 arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9>
   inline
-  FunEncapsulation
-  MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,RetType>::ArgCollector::collect_args (Class &object,
-                                                                                                 Arg1   arg1,
-                                                                                                 Arg2   arg2,
-                                                                                                 Arg3   arg3,
-                                                                                                 Arg4   arg4,
-                                                                                                 Arg5   arg5,
-                                                                                                 Arg6   arg6,
-                                                                                                 Arg7   arg7,
-                                                                                                 Arg8   arg8)
-  {
-    return collect_args (&object, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+  internal::mem_fun_forwarder<RT,const C,
+                              boost::tuple<Arg1, Arg2, Arg3,
+                                           Arg4, Arg5, Arg6,
+                                           Arg7, Arg8, Arg9> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                      Arg6,Arg7,Arg8,Arg9) const) {
+    return internal::mem_fun_forwarder<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9> > (c,fun_ptr);
   }
 
 
-/* ---------------------- MemFunData9 implementation ------------------------ */
+// ----------- forwarders for member functions with 10 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for member
+                                      * functions with 10
+                                      * arguments.
+                                      */
+    template <typename RT, typename C, typename ArgList>
+    class mem_fun_forwarder<RT, C, ArgList, 10>
+    {
+        typedef typename internal::mem_fun_ptr<RT,C,ArgList>::type MemFunPtr;      
+
+      public:
+        inline mem_fun_forwarder (C &c, MemFunPtr mem_fun_ptr)
+                        : c (c), mem_fun_ptr(mem_fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8,
+                    typename boost::tuples::element<8,ArgList>::type arg9,
+                    typename boost::tuples::element<9,ArgList>::type arg10) {
+          return Thread<RT> (mem_fun_ptr, c,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6,
+                                        arg7,arg8,
+                                        arg9, arg10));
+        };
+    
+      private:
+        C         &c;
+        MemFunPtr  mem_fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::MemFunData9 (FunPtr  fun_ptr,
-                                                                                       Class  *object,
-                                                                                       Arg1    arg1,
-                                                                                       Arg2    arg2,
-                                                                                       Arg3    arg3,
-                                                                                       Arg4    arg4,
-                                                                                       Arg5    arg5,
-                                                                                       Arg6    arg6,
-                                                                                       Arg7    arg7,
-                                                                                       Arg8    arg8,
-                                                                                       Arg9    arg9) :
-                 FunDataBase (&MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6),
-                 arg7 (arg7),
-                 arg8 (arg8),
-                 arg9 (arg9)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::MemFunData9 (const MemFunData9 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6),
-                 arg7 (fun_data.arg7),
-                 arg8 (fun_data.arg8),
-                 arg9 (fun_data.arg9)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  FunDataBase *
-  MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::clone () const 
-  {
-    return new MemFunData9 (*this);
   }
 
 
+                                   /**
+                                    * Overload of the non-const spawn
+                                    * function for member functions
+                                    * with 10 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9,
+            typename Arg10>
+  inline
+  internal::mem_fun_forwarder<RT,C,boost::tuple<Arg1, Arg2, Arg3,
+                                                Arg4, Arg5, Arg6,
+                                                Arg7, Arg8, Arg9, Arg10> >
+  spawn (C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                Arg6,Arg7,Arg8,Arg9,Arg10)) {
+    return internal::mem_fun_forwarder<RT, C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9,
+      Arg10> > (c,fun_ptr);
+  }
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  void *
-  MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::thread_entry_point (void *arg) 
-  {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-    Arg7              arg7    = fun_data->arg7;
-    Arg8              arg8    = fun_data->arg8;
-    Arg9              arg9    = fun_data->arg9;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2, arg3, arg4,
-                           arg5, arg6, arg7, arg8, arg9);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
-  
-    return 0;
+                                   /**
+                                    * Overload of the spawn function
+                                    * for const member functions with
+                                    * 10 arguments. This is the
+                                    * version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename C,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9,
+            typename Arg10>
+  inline
+  internal::mem_fun_forwarder<RT,const C,
+                              boost::tuple<Arg1, Arg2, Arg3,
+                                           Arg4, Arg5, Arg6,
+                                           Arg7, Arg8, Arg9, Arg10> >
+  spawn (const C &c, RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                                      Arg6,Arg7,Arg8,Arg9,Arg10) const) {
+    return internal::mem_fun_forwarder<RT, const C,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9,
+      Arg10> > (c,fun_ptr);
   }
 
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
+// ----------- forwarders for functions not taking any parameters
 
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for functions
+                                      * with no arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 0>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
-  FunEncapsulation
-  MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::ArgCollector::collect_args (Class *object,
-                                                                                                      Arg1   arg1,
-                                                                                                      Arg2   arg2,
-                                                                                                      Arg3   arg3,
-                                                                                                      Arg4   arg4,
-                                                                                                      Arg5   arg5,
-                                                                                                      Arg6   arg6,
-                                                                                                      Arg7   arg7,
-                                                                                                      Arg8   arg8,
-                                                                                                      Arg9   arg9)
-  {
-    return new MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,void>(fun_ptr, object,
-                                                                                   arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
-  }
+        inline
+        Thread<RT>
+        operator() () {
+          return Thread<RT> (fun_ptr,
+                             ArgList());
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
+  }
 
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename RetType>
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with no
+                                    * arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT>
   inline
-  FunEncapsulation
-  MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,RetType>::ArgCollector::collect_args (Class &object,
-                                                                                                      Arg1   arg1,
-                                                                                                      Arg2   arg2,
-                                                                                                      Arg3   arg3,
-                                                                                                      Arg4   arg4,
-                                                                                                      Arg5   arg5,
-                                                                                                      Arg6   arg6,
-                                                                                                      Arg7   arg7,
-                                                                                                      Arg8   arg8,
-                                                                                                      Arg9   arg9)
-  {
-    return collect_args (&object, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+  internal::fun_forwarder<RT,boost::tuple<> >
+  spawn (RT (*fun_ptr)()) {
+    return internal::fun_forwarder<RT, boost::tuple<> > (fun_ptr);
   }
 
 
-/* ---------------------- MemFunData10 implementation ------------------------ */
-  
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::MemFunData10 (FunPtr  fun_ptr,
-                                                                                               Class  *object,
-                                                                                               Arg1    arg1,
-                                                                                               Arg2    arg2,
-                                                                                               Arg3    arg3,
-                                                                                               Arg4    arg4,
-                                                                                               Arg5    arg5,
-                                                                                               Arg6    arg6,
-                                                                                               Arg7    arg7,
-                                                                                               Arg8    arg8,
-                                                                                               Arg9    arg9,
-                                                                                               Arg10   arg10) :
-                 FunDataBase (&MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::thread_entry_point),
-                 fun_ptr (fun_ptr),
-                 object (object),
-                 arg1 (arg1),
-                 arg2 (arg2),
-                 arg3 (arg3),
-                 arg4 (arg4),
-                 arg5 (arg5),
-                 arg6 (arg6),
-                 arg7 (arg7),
-                 arg8 (arg8),
-                 arg9 (arg9),
-                 arg10 (arg10)
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::MemFunData10 (const MemFunData10 &fun_data) :
-                 FunDataBase (fun_data),
-                 fun_ptr (fun_data.fun_ptr),
-                 object (fun_data.object),
-                 arg1 (fun_data.arg1),
-                 arg2 (fun_data.arg2),
-                 arg3 (fun_data.arg3),
-                 arg4 (fun_data.arg4),
-                 arg5 (fun_data.arg5),
-                 arg6 (fun_data.arg6),
-                 arg7 (fun_data.arg7),
-                 arg8 (fun_data.arg8),
-                 arg9 (fun_data.arg9),
-                 arg10(fun_data.arg10)           
-  {}
-
-
-
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  FunDataBase *
-  MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::clone () const 
-  {
-    return new MemFunData10 (*this);
-  }
 
 
+// ----------- forwarders for unary functions
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  void *
-  MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::thread_entry_point (void *arg) 
+  namespace internal
   {
-                                    // convenience typedef, since we
-                                    // will need that class name
-                                    // several times below
-    typedef MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType> ThisClass;
-  
-    FunEncapsulation *fun_encapsulation
-      = reinterpret_cast<FunEncapsulation*>(arg);
-    const ThisClass *fun_data
-      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
-
-                                    // copy the parameters
-    typename ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
-    Class            *object  = fun_data->object;
-    Arg1              arg1    = fun_data->arg1;
-    Arg2              arg2    = fun_data->arg2;
-    Arg3              arg3    = fun_data->arg3;
-    Arg4              arg4    = fun_data->arg4;
-    Arg5              arg5    = fun_data->arg5;
-    Arg6              arg6    = fun_data->arg6;
-    Arg7              arg7    = fun_data->arg7;
-    Arg8              arg8    = fun_data->arg8;
-    Arg9              arg9    = fun_data->arg9;
-    Arg10             arg10   = fun_data->arg10;
-
-
-                                    // copying of parameters is done,
-                                    // now we can release the lock on
-                                    // @p{fun_data}, by first making
-                                    // sure that the main thread is
-                                    // hanging in the condition
-                                    // variable's wait() function,
-                                    // and then signalling that the
-                                    // condition has been met,
-                                    // i.e. that the data has been
-                                    // copied. (note that there can
-                                    // be only one listener, so
-                                    // signal() is fine and we don't
-                                    // need broadcast())
-    fun_data->lock.acquire ();
-    fun_data->condition.signal ();
-    fun_data->lock.release ();
-
-                                     // register new thread, call the
-                                    // function, and upon its return,
-                                    // de-register it again. since an
-                                    // exception that is thrown from
-                                    // one of the called functions
-                                    // will not propagate to the main
-                                    // thread, it will kill the
-                                    // program if not treated here
-                                    // before we return to the
-                                    // operating system's thread
-                                    // library
-    register_new_thread ();
-    try 
-      {
-        (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5,
-                           arg6, arg7, arg8, arg9, arg10);
-      }
-    catch (const std::exception &exc)
-      {
-        handle_std_exception (exc);
-      }
-    catch (...)
-      {
-        handle_unknown_exception ();
-      };
-    deregister_new_thread ();
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 1 argument.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 1>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-    return 0;
   }
 
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 1 argument. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename Arg1>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1> >
+  spawn (RT (*fun_ptr)(Arg1)) {
+    return internal::fun_forwarder<RT, boost::tuple<Arg1> > (fun_ptr);
+  }
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
-                 fun_ptr (fun_ptr)
-  {}
 
 
+// ----------- forwarders for binary functions
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  FunEncapsulation
-  MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::ArgCollector::collect_args (Class *object,
-                                                                                                             Arg1   arg1,
-                                                                                                             Arg2   arg2,
-                                                                                                             Arg3   arg3,
-                                                                                                             Arg4   arg4,
-                                                                                                             Arg5   arg5,
-                                                                                                             Arg6   arg6,
-                                                                                                             Arg7   arg7,
-                                                                                                             Arg8   arg8,
-                                                                                                             Arg9   arg9,
-                                                                                                             Arg10  arg10)
+  namespace internal
   {
-    return new MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,void>(fun_ptr, object,
-                                                                                   arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
-  }
-  
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 2 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 2>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10, typename RetType>
-  inline
-  FunEncapsulation
-  MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,RetType>::ArgCollector::collect_args (Class &object,
-                                                                                                             Arg1   arg1,
-                                                                                                             Arg2   arg2,
-                                                                                                             Arg3   arg3,
-                                                                                                             Arg4   arg4,
-                                                                                                             Arg5   arg5,
-                                                                                                             Arg6   arg6,
-                                                                                                             Arg7   arg7,
-                                                                                                             Arg8   arg8,
-                                                                                                             Arg9   arg9,
-                                                                                                             Arg10  arg10)
-  {
-    return collect_args (&object, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,
+                                        arg2));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
+  
   }
 
 
-/* ---------------------------------------------------------------- */
-
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 2 arguments. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT, typename Arg1, typename Arg2>
   inline
-  FunData0<void>::ArgCollector
-  encapsulate (void (*fun_ptr)())
-  {
-    return fun_ptr;
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2)) {
+    return internal::fun_forwarder<RT, boost::tuple<Arg1, Arg2> > (fun_ptr);
   }
 
 
 
-  template <typename Arg1>
-  typename FunData1<Arg1,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1))
-  {
-    return fun_ptr;
-  }
-  
-
-  
-  template <typename Arg1, typename Arg2>
-  typename FunData2<Arg1,Arg2,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2))
-  {
-    return fun_ptr;
-  }
-  
+// ----------- forwarders for ternary functions
 
-  
-  template <typename Arg1, typename Arg2, typename Arg3>
-  typename FunData3<Arg1,Arg2,Arg3,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3))
+  namespace internal
   {
-    return fun_ptr;
-  }
-  
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 3 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 3>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
-  
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-  typename FunData4<Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4))
-  {
-    return fun_ptr;
-  }
-  
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,
+                                        arg2,
+                                        arg3));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-  typename FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5))
-  {
-    return fun_ptr;
   }
 
 
-  
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
-  typename FunData6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6))
-  {
-    return fun_ptr;
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 3 arguments. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2, Arg3> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3)) {
+    return internal::fun_forwarder<RT,
+      boost::tuple<Arg1, Arg2, Arg3> > (fun_ptr);
   }
 
 
-  
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7>
-  typename FunData7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7))
-  {
-    return fun_ptr;
-  }
-
 
-  
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8>
-  typename FunData8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8))
-  {
-    return fun_ptr;
-  }
 
+// ----------- forwarders for functions with 4 arguments
 
-  
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9>
-  typename FunData9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5,
-                              Arg6, Arg7, Arg8, Arg9))
+  namespace internal
   {
-    return fun_ptr;
-  }
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 4 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 4>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10>
-  typename FunData10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,void>::ArgCollector
-  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5,
-                              Arg6, Arg7, Arg8, Arg9, Arg10))
-  {
-    return fun_ptr;
   }
 
 
-  
-  template <class Class>
-  typename MemFunData0<Class,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)())
-  {
-    return fun_ptr;
-  }
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class>
-  typename MemFunData0<const Class,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)() const)
-  {
-    return fun_ptr;
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 4 arguments. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2, Arg3, Arg4> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4)) {
+    return internal::fun_forwarder<RT,
+      boost::tuple<Arg1, Arg2, Arg3, Arg4> > (fun_ptr);
   }
-#endif
 
 
 
-  template <class Class, typename Arg1>
-  typename MemFunData1<Class,Arg1,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1))
-  {
-    return fun_ptr;
-  }
 
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1>
-  typename MemFunData1<const Class,Arg1,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1) const)
-  {
-    return fun_ptr;
-  }
-#endif
-  
+// ----------- forwarders for functions with 5 arguments
 
-  
-  template <class Class, typename Arg1, typename Arg2>
-  typename MemFunData2<Class,Arg1,Arg2,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2))
+  namespace internal
   {
-    return fun_ptr;
-  }
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 5 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 5>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
 
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2>
-  typename MemFunData2<const Class,Arg1,Arg2,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2) const)
-  {
-    return fun_ptr;
-  }
-#endif
-  
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
 
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3>
-  typename MemFunData3<Class,Arg1,Arg2,Arg3,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3))
-  {
-    return fun_ptr;
-  }
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2, typename Arg3>
-  typename MemFunData3<const Class,Arg1,Arg2,Arg3,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3) const)
-  {
-    return fun_ptr;
   }
-#endif
-  
 
-  
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-  typename MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4))
-  {
-    return fun_ptr;
-  }
 
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-  typename MemFunData4<const Class,Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4) const)
-  {
-    return fun_ptr;
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 5 arguments. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5)) {
+    return internal::fun_forwarder<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5> > (fun_ptr);
   }
-#endif
 
 
+// ----------- forwarders for functions with 6 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 6 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 6>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-  typename MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5))
-  {
-    return fun_ptr;
   }
 
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-  typename MemFunData5<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5) const)
-  {
-    return fun_ptr;
+
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 6 arguments. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6)) {
+    return internal::fun_forwarder<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6> > (fun_ptr);
   }
-#endif
 
 
+// ----------- forwarders for functions with 7 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 7 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 7>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6,
+                                        arg7));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
-  typename MemFunData6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6))
-  {
-    return fun_ptr;
   }
 
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
-  typename MemFunData6<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const)
-  {
-    return fun_ptr;
+
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 7 arguments. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2, Arg3,
+                                          Arg4, Arg5, Arg6, Arg7> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7)) {
+    return internal::fun_forwarder<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7> > (fun_ptr);
   }
-#endif
 
 
+// ----------- forwarders for functions with 8 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 8 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 8>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6,
+                                        arg7,arg8));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7>
-  typename MemFunData7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7))
-  {
-    return fun_ptr;
   }
 
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7>
-  typename MemFunData7<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const)
-  {
-    return fun_ptr;
+
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 8 arguments. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2, Arg3,
+                                          Arg4, Arg5, Arg6,
+                                          Arg7, Arg8> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                       Arg6,Arg7,Arg8)) {
+    return internal::fun_forwarder<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8> > (fun_ptr);
   }
-#endif
 
 
+// ----------- forwarders for functions with 9 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 9 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 9>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8,
+                    typename boost::tuples::element<8,ArgList>::type arg9) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6,
+                                        arg7,arg8,
+                                        arg9));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8>
-  typename MemFunData8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8))
-  {
-    return fun_ptr;
-  }
-
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8>
-  typename MemFunData8<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) const)
-  {
-    return fun_ptr;
   }
-#endif
-
 
 
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9>
-  typename MemFunData9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9))
-  {
-    return fun_ptr;
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 9 arguments. This
+                                    * is the version of the @p{spawn}
+                                    * function for the case that
+                                    * threading is not enabled.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2, Arg3,
+                                          Arg4, Arg5, Arg6,
+                                          Arg7, Arg8, Arg9> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                       Arg6,Arg7,Arg8,Arg9)) {
+    return internal::fun_forwarder<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9> > (fun_ptr);
   }
 
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9>
-  typename MemFunData9<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) const)
-  {
-    return fun_ptr;
-  }
-#endif
-  
 
+// ----------- forwarders for functions with 10 arguments
+
+  namespace internal
+  {
+                                     /**
+                                      * Forwarder class for functions
+                                      * with 10 arguments.
+                                      */
+    template <typename RT, typename ArgList>
+    class fun_forwarder<RT, ArgList, 10>
+    {
+        typedef typename internal::fun_ptr<RT,ArgList>::type FunPtr;      
+
+      public:
+        inline fun_forwarder (FunPtr fun_ptr)
+                        : fun_ptr(fun_ptr) {};
+
+        inline
+        Thread<RT>
+        operator() (typename boost::tuples::element<0,ArgList>::type arg1,
+                    typename boost::tuples::element<1,ArgList>::type arg2,
+                    typename boost::tuples::element<2,ArgList>::type arg3,
+                    typename boost::tuples::element<3,ArgList>::type arg4,
+                    typename boost::tuples::element<4,ArgList>::type arg5,
+                    typename boost::tuples::element<5,ArgList>::type arg6,
+                    typename boost::tuples::element<6,ArgList>::type arg7,
+                    typename boost::tuples::element<7,ArgList>::type arg8,
+                    typename boost::tuples::element<8,ArgList>::type arg9,
+                    typename boost::tuples::element<9,ArgList>::type arg10) {
+          return Thread<RT> (fun_ptr,
+                             boost::tie(arg1,arg2,
+                                        arg3,arg4,
+                                        arg5,arg6,
+                                        arg7,arg8,
+                                        arg9, arg10));
+        };
+    
+      private:
+        FunPtr  fun_ptr;
+    };
   
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10>
-  typename MemFunData10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10))
-  {
-    return fun_ptr;
   }
 
-#ifdef DEAL_II_TEMPL_CONST_MEM_PTR_BUG
-  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6, typename Arg7, typename Arg8, typename Arg9, typename Arg10>
-  typename MemFunData10<const Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10,void>::ArgCollector
-  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10) const)
-  {
-    return fun_ptr;
+
+                                   /**
+                                    * Overload of the spawn function
+                                    * for non-member or static member
+                                    * functions with 10
+                                    * arguments. This is the version
+                                    * of the @p{spawn} function for
+                                    * the case that threading is not
+                                    * enabled.
+                                    */
+  template <typename RT,
+            typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4, typename Arg5, typename Arg6,
+            typename Arg7, typename Arg8, typename Arg9,
+            typename Arg10>
+  inline
+  internal::fun_forwarder<RT,boost::tuple<Arg1, Arg2, Arg3,
+                                          Arg4, Arg5, Arg6,
+                                          Arg7, Arg8, Arg9, Arg10> >
+  spawn (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
+                       Arg6,Arg7,Arg8,Arg9,Arg10)) {
+    return internal::fun_forwarder<RT,
+      boost::tuple<Arg1, Arg2, Arg3,
+      Arg4, Arg5, Arg6,
+      Arg7, Arg8, Arg9,
+      Arg10> > (fun_ptr);
   }
-#endif
   
 
   
-  template <typename ForwardIterator>
-  std::vector<std::pair<ForwardIterator,ForwardIterator> >
-  split_range (const ForwardIterator &begin,
-              const ForwardIterator &end,
-              const unsigned int     n_intervals)
-  {
-    typedef std::pair<ForwardIterator,ForwardIterator> IteratorPair;
+#endif // #if (DEAL_II_USE_MT == 1)
 
-                                    // in non-multithreaded mode, we
-                                    // often have the case that this
-                                    // function is called with
-                                    // n_intervals==1, so have a
-                                    // shortcut here to handle that
-                                    // case efficiently
-    
-    if (n_intervals==1)
-      return (std::vector<IteratorPair>
-             (1, IteratorPair(begin, end)));
-    
-                                    // if more than one interval
-                                    // requested, do the full work
-    const unsigned int n_elements              = distance (begin, end);
-    const unsigned int n_elements_per_interval = n_elements / n_intervals;
-    const unsigned int residual                = n_elements % n_intervals;
-    
-    std::vector<IteratorPair> return_values (n_intervals);
 
-    return_values[0].first = begin;
-    for (unsigned int i=0; i<n_intervals; ++i)
-      {
-       if (i != n_intervals-1) 
-         {
-           return_values[i].second = return_values[i].first;
-                                            // note: the cast is
-                                            // performed to avoid a
-                                            // warning of gcc that in
-                                            // the library `dist>=0'
-                                            // is checked (dist has a
-                                            // template type, which
-                                            // here is unsigned if no
-                                            // cast is performed)
-           std::advance (return_values[i].second,
-                         static_cast<signed int>(n_elements_per_interval));
-                                            // distribute residual in
-                                            // division equally among
-                                            // the first few
-                                            // subintervals
-           if (i < residual)
-             ++return_values[i].second;
-           
-           return_values[i+1].first = return_values[i].second;
-         }
-       else
-         return_values[i].second = end;
-      }
-    return return_values;
-  }  
 
+                                   /**
+                                    * A container for thread
+                                    * objects. Allows to add new
+                                    * thread objects and wait for them
+                                    * all together. The thread objects
+                                    * need to have the same return
+                                    * value for the called function.
+                                    *
+                                    * @author Wolfgang Bangerth, 2003
+                                    */
+  template <typename RT = void>
+  class ThreadGroup 
+  {
+    public:
+                                       /**
+                                        * Add another thread object to
+                                        * the collection.
+                                        */
+      ThreadGroup & operator += (const Thread<RT> &t) {
+        threads.push_back (t);
+        return *this;
+      };
 
-           
+                                       /**
+                                        * Wait for all threads in the
+                                        * collection to finish. It is
+                                        * not a problem if some of
+                                        * them have already been
+                                        * waited for, i.e. you may
+                                        * call this function more than
+                                        * once, and you can also add
+                                        * new thread objects between
+                                        * subsequent calls to this
+                                        * function if you want.
+                                        */
+      void join_all () const {
+        for (typename std::list<Thread<RT> >::const_iterator
+               t=threads.begin(); t!=threads.end(); ++t)
+          t->join ();
+      };
+    
+    private:
+                                       /**
+                                        * List of thread objects.
+                                        */
+      std::list<Thread<RT> > threads;
+  };
+  
+  
 }   // end of implementation of namespace Threads
 
 
index 425823c4d03cae3b19f55e26088bd6d9b5582737..37feed730bc1159584ebd6c41716543cee1c694a 100644 (file)
@@ -2497,13 +2497,10 @@ void DataOutBase::write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
                                   // to write out the data, we wait
                                   // for that thread to finish
   Table<2,double> data_vectors (n_data_sets, n_nodes);
-  Threads::ThreadManager thread_manager;
   void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
                   Table<2,double> &)
     = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-  Threads::spawn (thread_manager,
-                 Threads::encapsulate (fun_ptr)
-                 .collect_args(patches, data_vectors));
+  Threads::Thread<> reorder_thread = Threads::spawn (fun_ptr)(patches, data_vectors);
 
                                   ///////////////////////////////
                                   // first make up a list of used
@@ -2702,7 +2699,7 @@ void DataOutBase::write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
                                   // now write the data vectors to
                                   // @p{out} first make sure that all
                                   // data is in place
-  thread_manager.wait ();
+  reorder_thread.join ();
 
                                   // then write data.
                                   // the '1' means: node data (as opposed
@@ -2877,13 +2874,10 @@ void DataOutBase::write_tecplot (const std::vector<Patch<dim,spacedim> > &patche
   
   Table<2,double> data_vectors (n_data_sets, n_nodes);
 
-  Threads::ThreadManager thread_manager;
   void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
                    Table<2,double> &)
     = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-  Threads::spawn (thread_manager,
-                  Threads::encapsulate (fun_ptr)
-                  .collect_args(patches, data_vectors));
+  Threads::Thread<> reorder_thread = Threads::spawn (fun_ptr)(patches, data_vectors);
 
                                    ///////////////////////////////
                                    // first make up a list of used
@@ -2977,7 +2971,7 @@ void DataOutBase::write_tecplot (const std::vector<Patch<dim,spacedim> > &patche
                                    // now write the data vectors to
                                    // @p{out} first make sure that all
                                    // data is in place
-  thread_manager.wait ();
+  reorder_thread.join ();
 
                                    // then write data.
   for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
@@ -3305,13 +3299,10 @@ void DataOutBase::write_tecplot_binary (const std::vector<Patch<dim,spacedim> >
   
   Table<2,double> data_vectors (n_data_sets, n_nodes);
 
-   Threads::ThreadManager thread_manager;
-   void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
-                   Table<2,double> &)
-     = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-   Threads::spawn (thread_manager,
-                  Threads::encapsulate (fun_ptr)
-                  .collect_args(patches, data_vectors));
+  void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+                   Table<2,double> &)
+    = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
+  Threads::Thread<> reorder_thread = Threads::spawn (fun_ptr)(patches, data_vectors);
 
                                    ///////////////////////////////
                                    // first make up a list of used
@@ -3319,7 +3310,7 @@ void DataOutBase::write_tecplot_binary (const std::vector<Patch<dim,spacedim> >
                                    // coordinates
 
   
-   for (unsigned int d=1; d<=spacedim; ++d)
+  for (unsigned int d=1; d<=spacedim; ++d)
      {       
        unsigned int entry=0;
        
@@ -3395,7 +3386,7 @@ void DataOutBase::write_tecplot_binary (const std::vector<Patch<dim,spacedim> >
                                    ///////////////////////////////////////
                                    // data output.
                                    //
-   thread_manager.wait ();
+   reorder_thread.join ();
 
                                    // then write data.
    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
@@ -3629,13 +3620,10 @@ void DataOutBase::write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
                                   // for that thread to finish
   Table<2,double> data_vectors (n_data_sets, n_nodes);
 
-  Threads::ThreadManager thread_manager;
   void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
                   Table<2,double> &)
     = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-  Threads::spawn (thread_manager,
-                 Threads::encapsulate (fun_ptr)
-                 .collect_args(patches, data_vectors));
+  Threads::Thread<> reorder_thread = Threads::spawn (fun_ptr)(patches, data_vectors);
 
                                   ///////////////////////////////
                                   // first make up a list of used
@@ -3832,7 +3820,7 @@ void DataOutBase::write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
                                   // now write the data vectors to
                                   // @p{out} first make sure that all
                                   // data is in place
-  thread_manager.wait ();
+  reorder_thread.join ();
 
                                   // then write data.  the
                                   // 'POINTD_DATA' means: node data
index 8fdf6941fb394e2d6747bb5d08fe9f23ce94b600..ab7c5b3a4de378514456427f5501ad348575a210 100644 (file)
@@ -1,3 +1,6 @@
+// files on the new-threads branch: base/include/base/thread_management.h base/source/data_out_base.cc base/source/thread_management.cc deal.II/source/dofs/dof_tools.cc deal.II/source/grid/grid_generator.cc deal.II/source/multigrid/mg_dof_tools.cc deal.II/source/numerics/data_out.cc deal.II/source/numerics/data_out_faces.cc deal.II/source/numerics/data_out_rotation.cc deal.II/source/numerics/derivative_approximation.cc deal.II/source/numerics/error_estimator.cc deal.II/source/numerics/matrices.cc deal.II/source/numerics/time_dependent.cc examples/step-13/step-13.cc examples/step-14/step-14.cc examples/step-9/step-9.cc lac/include/lac/sparse_matrix.templates.h lac/include/lac/sparse_vanka.templates.h lac/include/lac/swappable_vector.h lac/include/lac/swappable_vector.templates.h configure configure.in aclocal.m4 common/Make.global_options.in contrib/hsl/source/detached_ma27.cc base/include/base/config.h.in
+
+
 //----------------------------  thread_management.cc  ---------------------------
 //    $Id$
 //    Version: $Name$
 
 namespace Threads 
 {
-                                   // counter and access mutex for the
-                                   // number of threads
-  volatile unsigned int n_existing_threads_counter = 1;
-  ThreadMutex  n_existing_threads_mutex;
-
-  
-  void register_new_thread () 
+  namespace internal
   {
-    ThreadMutex::ScopedLock lock (n_existing_threads_mutex);
-    ++n_existing_threads_counter;
-  }
-
+                                     // counter and access mutex for the
+                                     // number of threads
+    volatile unsigned int n_existing_threads_counter = 1;
+    ThreadMutex  n_existing_threads_mutex;
 
   
-  void deregister_new_thread () 
-  {
-    ThreadMutex::ScopedLock lock (n_existing_threads_mutex);
-    --n_existing_threads_counter;
-    Assert (n_existing_threads_counter >= 1,
-            ExcInternalError());
-  }
+    void register_thread () 
+    {
+      ThreadMutex::ScopedLock lock (n_existing_threads_mutex);
+      ++n_existing_threads_counter;
+    }
 
 
-
-  void handle_std_exception (const std::exception &exc) 
-  {
-    std::cerr << std::endl << std::endl
-              << "---------------------------------------------------------"
-              << std::endl
-              << "In one of the sub-threads of this program, an exception\n"
-              << "was thrown and not caught. Since exceptions do not\n"
-              << "propagate to the main thread, the library has caught it.\n"
-              << "The information carried by this exception is given below.\n"
-              << std::endl
-              << "---------------------------------------------------------"
-              << std::endl;
-    std::cerr << "Exception on processing: " << std::endl
-              << exc.what() << std::endl
-              << "Aborting!" << std::endl
-              << "---------------------------------------------------------"
-              << std::endl;
-    std::abort ();
-  }
-
-
-
-  void handle_unknown_exception ()
-  {
-    std::cerr << std::endl << std::endl
-              << "---------------------------------------------------------"
-              << std::endl
-              << "In one of the sub-threads of this program, an exception\n"
-              << "was thrown and not caught. Since exceptions do not\n"
-              << "propagate to the main thread, the library has caught it.\n"
-              << "The information carried by this exception is given below.\n"
-              << std::endl
-              << "---------------------------------------------------------"
-              << std::endl;
-    std::cerr << "Type of exception is unknown, but not std::exception.\n"
-              << "No additional information is available.\n"
-              << "---------------------------------------------------------"
-              << std::endl;
-    std::abort ();
+  
+    void deregister_thread () 
+    {
+      ThreadMutex::ScopedLock lock (n_existing_threads_mutex);
+      --n_existing_threads_counter;
+      Assert (n_existing_threads_counter >= 1,
+              ExcInternalError());
+    }
+
+
+
+    void handle_std_exception (const std::exception &exc) 
+    {
+      std::cerr << std::endl << std::endl
+                << "---------------------------------------------------------"
+                << std::endl
+                << "In one of the sub-threads of this program, an exception\n"
+                << "was thrown and not caught. Since exceptions do not\n"
+                << "propagate to the main thread, the library has caught it.\n"
+                << "The information carried by this exception is given below.\n"
+                << std::endl
+                << "---------------------------------------------------------"
+                << std::endl;
+      std::cerr << "Exception on processing: " << std::endl
+                << exc.what() << std::endl
+                << "Aborting!" << std::endl
+                << "---------------------------------------------------------"
+                << std::endl;
+      std::abort ();
+    }
+
+
+
+    void handle_unknown_exception ()
+    {
+      std::cerr << std::endl << std::endl
+                << "---------------------------------------------------------"
+                << std::endl
+                << "In one of the sub-threads of this program, an exception\n"
+                << "was thrown and not caught. Since exceptions do not\n"
+                << "propagate to the main thread, the library has caught it.\n"
+                << "The information carried by this exception is given below.\n"
+                << std::endl
+                << "---------------------------------------------------------"
+                << std::endl;
+      std::cerr << "Type of exception is unknown, but not std::exception.\n"
+                << "No additional information is available.\n"
+                << "---------------------------------------------------------"
+                << std::endl;
+      std::abort ();
+    }
   }
   
 
   
   unsigned int n_existing_threads () 
   {
-    ThreadMutex::ScopedLock lock (n_existing_threads_mutex);
-    const unsigned int n = n_existing_threads_counter;
+    ThreadMutex::ScopedLock lock (internal::n_existing_threads_mutex);
+    const unsigned int n = internal::n_existing_threads_counter;
     return n;
   }
   
   
 #if DEAL_II_USE_MT != 1
-  void DummyThreadManager::spawn (const FunPtr fun_ptr,
-                                 void *       fun_data,
-                                 int          /*flags*/) const
-  {
-    (*fun_ptr) (fun_data);
-  }
-  
-
-  
   DummyBarrier::DummyBarrier (const unsigned int  count,
                              const char         *,
                              void               *)
@@ -219,256 +216,10 @@ namespace Threads
   
 
 
-  PosixThreadManager::PosixThreadManager ()
-                 :
-                 thread_id_list (new std::list<pthread_t>())
-  {}
-
-
-  PosixThreadManager::~PosixThreadManager ()
-  {
-                                    // wait for all threads, and
-                                    // release memory
-    wait ();
-    ThreadMutex::ScopedLock lock (list_mutex);
-    if (thread_id_list != 0)
-      delete reinterpret_cast<std::list<pthread_t>*>(thread_id_list);
-  }
-
-
-
-  void
-  PosixThreadManager::spawn (const FunPtr fun_ptr,
-                            void *       fun_data,
-                            int)
-  {
-    std::list<pthread_t> &tid_list
-      = *reinterpret_cast<std::list<pthread_t>*>(thread_id_list);
-    
-    list_mutex.acquire ();
-    tid_list.push_back (pthread_t());
-    pthread_t *tid = &tid_list.back();
-    list_mutex.release ();
-    
-                                     // start new thread. retry until
-                                     // we either succeed or get an
-                                     // error other than EAGAIN
-    int error = 0;
-    do 
-      {
-       error = pthread_create (tid, 0, fun_ptr, fun_data);
-      }
-    while (error == EAGAIN);
-
-    AssertThrow (error == 0, ExcInternalError());
-  }
-  
-
-
-  void
-  PosixThreadManager::wait () const
-  {
-    ThreadMutex::ScopedLock lock (list_mutex);
-    std::list<pthread_t> &tid_list
-      = *reinterpret_cast<std::list<pthread_t>*>(thread_id_list);
-
-                                    // wait for all the threads in
-                                    // turn
-    for (std::list<pthread_t>::iterator i=tid_list.begin();
-        i != tid_list.end(); ++i)
-      pthread_join (*i, 0);
-
-                                    // now we know that these threads
-                                    // have finished, remove their
-                                    // tid's from the list. this way,
-                                    // when new threads are spawned
-                                    // and waited for, we won't wait
-                                    // for expired threads with their
-                                    // invalid handles again
-    tid_list.clear ();
-  }
   
 #  endif
 #endif  
   
-  FunDataCounter::FunDataCounter () :
-                 n_fun_encapsulation_objects (0),
-                 n_fun_data_base_objects (0)
-  {}
-  
-
-  
-  FunDataCounter::~FunDataCounter () 
-  {   
-    AssertThrow (n_fun_encapsulation_objects == 0,
-                ExcObjectsExist("FunEncapsulation", n_fun_encapsulation_objects));
-    AssertThrow (n_fun_data_base_objects == 0,
-                ExcObjectsExist("FunDataBase", n_fun_data_base_objects));
-  }
-      
-
-
-/**
- * This is the global object which we will use to count the number of
- * threads generated, and which is used to complain when there is a
- * memory leak.
- */
-  FunDataCounter fun_data_counter;
-
-
-  FunEncapsulation::FunEncapsulation () :
-                 fun_data_base (0)
-  {
-                                    // keep some statistics on the
-                                    // number of variables around
-    ++fun_data_counter.n_fun_encapsulation_objects;
-  }
-
-
-
-  FunEncapsulation::FunEncapsulation (FunDataBase *fun_data_base) :
-                 fun_data_base (fun_data_base)
-  {
-                                    // keep some statistics on the
-                                    // number of variables around
-    ++fun_data_counter.n_fun_encapsulation_objects;
-  }
-
-
-
-  FunEncapsulation::FunEncapsulation (const FunEncapsulation &fun_data) :
-                 fun_data_base (fun_data.fun_data_base->clone ())
-  {
-                                    // keep some statistics on the
-                                    // number of variables around
-    ++fun_data_counter.n_fun_encapsulation_objects;
-  }
-
-
-  FunEncapsulation::~FunEncapsulation ()
-  {
-                                     // note that the spawn() function
-                                     // makes sure that we only get
-                                     // here if the data has already
-                                     // been copied by the spawned
-                                     // thread, so destruction is safe
-                                     // here.
-                                     //
-                                     // so do so.
-    delete fun_data_base;
-    fun_data_base = 0;
-
-                                  // keep some statistics on the
-                                  // number of variables around
-    --fun_data_counter.n_fun_encapsulation_objects;
-  }
-    
-
-  const FunEncapsulation &
-  FunEncapsulation::operator = (const FunEncapsulation &/*fun_data*/)
-  {
-                                    // this is not implemented at
-                                    // present. return dummy value
-                                    // instead
-    Assert (false, ExcNotImplemented());
-    const FunEncapsulation * const p = 0;
-    return *p;
-  }
-
-
-
-  FunDataBase::FunDataBase (const ThreadEntryPoint thread_entry_point) :
-                 thread_entry_point (thread_entry_point)
-  {
-                                    // keep some statistics on the
-                                    // number of variables around
-    ++fun_data_counter.n_fun_data_base_objects;
-  }
-
-
-
-  FunDataBase::FunDataBase (const FunDataBase &fun_data_base) :
-                 thread_entry_point (fun_data_base.thread_entry_point)
-  {
-                                    // keep some statistics on the
-                                    // number of variables around
-    ++fun_data_counter.n_fun_data_base_objects;
-  }
-
-
-
-  FunDataBase::~FunDataBase ()
-  {
-                                    // invalidate pointer for security
-                                    // reasons. accesses to this
-                                    // pointer after lifetime of this
-                                    // object will then fail
-    thread_entry_point = 0;
-
-                                    // keep some statistics on the
-                                    // number of variables around
-    --fun_data_counter.n_fun_data_base_objects;
-  }
-
-
-    
-  void spawn (ThreadManager          &thread_manager,
-             const FunEncapsulation &fun_data)
-  {
-                                    // lock the @p{fun_data_base} object
-                                    // to avoid destruction while its
-                                    // data is still accessed. the lock
-                                    // is released by the new thread
-                                    // once it has copied all data
-    fun_data.fun_data_base->lock.acquire ();
-                                    // now start the new thread
-#if DEAL_II_USE_MT == 1
-#  if defined(DEAL_II_USE_MT_POSIX)
-    thread_manager.spawn (*fun_data.fun_data_base->thread_entry_point,
-                         (void*)&fun_data,
-                         0);
-#  else
-#    error Not implemented
-#  endif
-#else
-                                     // if not in MT mode, then simply
-                                     // call the respective
-                                     // serializing function, that
-                                     // executes the given function
-                                     // and return
-    thread_manager.spawn (*fun_data.fun_data_base->thread_entry_point,
-                         (void*)&fun_data,
-                         0);
-#endif
-
-                                     // unlock the mutex and wait for
-                                     // the condition that the data
-                                     // has been copied to be
-                                     // signalled. unlocking the mutex
-                                     // will allow the other thread to
-                                     // proceed to the signal() call,
-                                     // which we want to catch here
-                                     //
-                                     // the mutex will subsequently be
-                                     // locked again, but since we
-                                     // don't need it any more, we can
-                                     // go on unlocking it immediately
-                                     // again
-    fun_data.fun_data_base->condition.wait(fun_data.fun_data_base->lock);
-    fun_data.fun_data_base->lock.release ();
-  }
-
-
-  
-  void spawn_n (ThreadManager          &thread_manager,
-               const FunEncapsulation &fun_data,
-               const unsigned int      n_threads)
-  {
-    for (unsigned int i=0; i<n_threads; ++i)
-      spawn (thread_manager, fun_data);
-  }
-  
-
 
 
   std::vector<std::pair<unsigned int,unsigned int> >
@@ -504,5 +255,159 @@ namespace Threads
       };
     return return_values;
   } 
+
+
+#if (DEAL_II_USE_MT == 1) && defined(DEAL_II_USE_MT_POSIX)
+
+  namespace internal
+  {
+    thread_description_base::~thread_description_base ()
+    {
+                                       // if we are here, then the
+                                       // last listener is just about
+                                       // to cease to exists. there
+                                       // are two possibilities (since
+                                       // there are two types of
+                                       // possible listeners, and
+                                       // exactly one listener is
+                                       // around):
+                                       //
+                                       // 1. there are no Thread<>
+                                       // objects around any more, but
+                                       // we are at the end of the
+                                       // entry_point function of the
+                                       // new thread; the thread is
+                                       // still running, though, and
+                                       // we are called from this new
+                                       // thread.
+                                       //
+                                       // if this is the case,
+                                       // apparently none of the
+                                       // orginal listeners has called
+                                       // join(), otherwise the thread
+                                       // would not be running any
+                                       // more. since there are no
+                                       // listeners any more, nobody
+                                       // will ever call join() on
+                                       // this thread any
+                                       // more. however, to avoid a
+                                       // resource leak, somebody has
+                                       // to do something like that --
+                                       // on the other hand, we can't
+                                       // since calling pthread_join()
+                                       // on ourself will create a
+                                       // deadlock, of course. so
+                                       // detach the thread.
+                                       //
+                                       // note that in this case,
+                                       // since nobody has ever called
+                                       // join(), was_joined must be
+                                       // false
+                                       //
+                                       // 2. the thread has already
+                                       // ended. in this case, the
+                                       // last Thread<> object
+                                       // refering to it just went out
+                                       // of scope. If this is the
+                                       // case, to prevent a memory
+                                       // leak, we have to call join
+                                       // on the thread, if this has
+                                       // not yet happened, i.e. if
+                                       // was_joined is false.
+                                       //
+                                       // if we are in case 2, then
+                                       // the destructor is called
+                                       // from another than the
+                                       // presently running thread
+                                       //
+                                       //
+                                       // now: how do we find out
+                                       // which case we're in? we
+                                       // could either call
+                                       // pthread_join and see whether
+                                       // we get an error back, or if
+                                       // we get back an error on
+                                       // pthread_detach. from the man
+                                       // pages, the second way seems
+                                       // a little bit safer, so go it:
+      if (was_joined == false)
+        {
+                                           // assume case 1:
+          int error = pthread_detach (thread);
+          if (error == 0)
+            return;
+
+                                           // ouch, could not
+                                           // detach. see if thread
+                                           // could not be found any
+                                           // more:
+          if (error == ESRCH)
+                                             // ok, this is the
+                                             // case. then we are in
+                                             // branch 2, and need to
+                                             // join the thread
+            join ();
+          else
+                                             // something went
+                                             // terribly wrong
+            AssertThrow (false, ExcInternalError());
+        }
+    }
+
+    
+    void
+    thread_description_base::create (void * (*p) (void *), void *d)
+    {
+                                       // start new thread. retry until
+                                       // we either succeed or get an
+                                       // error other than EAGAIN
+      int error = 0;
+      do
+        {
+          error = pthread_create (&thread, 0, p, d);
+        }
+      while (error == EAGAIN);
+
+      AssertThrow (error == 0, ExcInternalError());
+    }
+      
+    
+
+    void
+    thread_description_base::join () const
+    {
+                                       // use Schmidt's double
+                                       // checking pattern: if thread
+                                       // was already joined, then
+                                       // return immediately
+      if (was_joined)
+        return;
+
+                                       // otherwise make sure that
+                                       // only one thread can enter
+                                       // the following section at a
+                                       // time
+      ThreadMutex::ScopedLock lock(join_mutex);
+                                       // while getting the lock,
+                                       // another thread may have set
+                                       // was_joined to true, so check
+                                       // again (this is the double
+                                       // checking pattern) and only
+                                       // if we are really sure that
+                                       // this has not happened, call
+                                       // pthread_join
+      if (!was_joined)
+        {
+          const int error = pthread_join (thread, 0);
+          AssertThrow (error == 0, ExcInternalError());
+        }
+
+                                       // set the flag
+      was_joined = true;
+    }
+    
+  } // end namespace internal
+
+#endif  // (DEAL_II_USE_MT == 1) && defined(DEAL_II_USE_MT_POSIX)
+  
 }   // end namespace Thread
index 8636d7ba1037c8e273e5281b2a722638ab8333bf..2468a4522267313fecdb605ab8b162b5286d6ab1 100644 (file)
@@ -95,17 +95,19 @@ endif
 # environment variable, since the compiler will evaluate the value of
 # that anyway at compile time
 
-include-path-base        = $D/base/include
-include-path-lac         = $D/lac/include
-include-path-deal2       = $D/deal.II/include
-include-path-contrib-hsl = $D/contrib/hsl/include
-include-path-tecplot     = $(TECIO_INCLUDE)
+include-path-base          = $D/base/include
+include-path-lac           = $D/lac/include
+include-path-deal2         = $D/deal.II/include
+include-path-contrib-hsl   = $D/contrib/hsl/include
+include-path-contrib-boost = $D/contrib/boost/include
+include-path-tecplot       = $(TECIO_INCLUDE)
 
 
 INCLUDE           = $(addprefix -I, $(include-path-base) \
                                     $(include-path-lac)  \
                                     $(include-path-deal2)\
                                    $(include-path-contrib-hsl)\
+                                   $(include-path-contrib-boost)\
                                    $(include-path-tecplot))
 
 # compiler flags for debug and optimized mode
index 5cfbf55db5243deb7a157ba0f50948ef32f48859..66fa4cb198f2a9f72be2a0c1927a8025ccf86e6c 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.141 .
+# From configure.in Revision: 1.141.2.1 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.57.
 #
@@ -2807,18 +2807,26 @@ echo "${ECHO_T}C++ compiler is HP aCC" >&6
                    GXX_VERSION=hp_aCC
                  else
 
-                                                                                                                                                                                   is_kai_cc="`($CXX --version 2>&1) | grep 'KAI C++'`"
-                   is_kai_cc="$is_kai_cc`($CXX -v 2>&1) | grep /KCC/`"
-                   if test "x$is_kai_cc" != "x" ; then
-                     echo "$as_me:$LINENO: result: C++ compiler is KAI C++" >&5
-echo "${ECHO_T}C++ compiler is KAI C++" >&6
-                     GXX_VERSION=kai_cc
+                                   is_bcc="`($CXX -h 2>&1) | grep 'Borland'`"
+                   if test "x$is_bcc" != "x" ; then
+                     echo "$as_me:$LINENO: result: C++ compiler is Borland C++" >&5
+echo "${ECHO_T}C++ compiler is Borland C++" >&6
+                     GXX_VERSION=borland_bcc
                    else
 
-                                            { { echo "$as_me:$LINENO: error: Unrecognized compiler -- sorry" >&5
+                                                                                                                                                                                             is_kai_cc="`($CXX --version 2>&1) | grep 'KAI C++'`"
+                     is_kai_cc="$is_kai_cc`($CXX -v 2>&1) | grep /KCC/`"
+                     if test "x$is_kai_cc" != "x" ; then
+                       echo "$as_me:$LINENO: result: C++ compiler is KAI C++" >&5
+echo "${ECHO_T}C++ compiler is KAI C++" >&6
+                       GXX_VERSION=kai_cc
+                     else
+
+                                                { { echo "$as_me:$LINENO: error: Unrecognized compiler -- sorry" >&5
 echo "$as_me: error: Unrecognized compiler -- sorry" >&2;}
    { (exit 1); exit 1; }; }
-                      exit 1
+                        exit 1
+                      fi
                     fi
                   fi
                 fi
@@ -2836,6 +2844,8 @@ echo "$as_me: error: Unrecognized compiler -- sorry" >&2;}
     CXXFLAGSO="$CXXFLAGS -O2 -Wuninitialized -felide-constructors -ftemplate-depth-32"
     CXXFLAGSG="$CXXFLAGS -DDEBUG -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Winline -Woverloaded-virtual -Wstrict-prototypes -Wsynth -Wsign-compare -Wconversion -Wswitch -ftemplate-depth-32"
 
+        CXXFLAGSG="$CXXFLAGSG -Wno-long-long"
+
             case "$target" in
       *aix* )
        CXXFLAGSPIC=
@@ -2879,6 +2889,8 @@ echo "$as_me: error: Unrecognized compiler -- sorry" >&2;}
     esac
 
 
+  echo "$as_me:$LINENO: checking for std::advance warning" >&5
+echo $ECHO_N "checking for std::advance warning... $ECHO_C" >&6
   ac_ext=cc
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2886,8 +2898,6 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
   CXXFLAGS="$CXXFLAGSG -Werror"
-  echo "$as_me:$LINENO: checking for std::advance warning" >&5
-echo $ECHO_N "checking for std::advance warning... $ECHO_C" >&6
   cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
@@ -2946,9 +2956,62 @@ rm -f conftest.$ac_objext conftest.$ac_ext
     fi
 
         case "$target" in
-      *apple-darwin*)
+            *apple-darwin*)
        CXXFLAGSG="$CXXFLAGSG -Wno-long-double"
        CXXFLAGSO="$CXXFLAGSO -Wno-long-double"
+        ;;
+
+                              *dec-osf*)
+        echo "$as_me:$LINENO: checking for preprocessor warning with cuserid" >&5
+echo $ECHO_N "checking for preprocessor warning with cuserid... $ECHO_C" >&6
+       CXXFLAGS="$CXXFLAGSG -Werror"
+       cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#          include <stdio.h>
+#          include <unistd.h>
+
+int
+main ()
+{
+;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+            echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+            echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+            CXXFLAGSG="$CXXFLAGSG -Wp,-w"
+            CXXFLAGSO="$CXXFLAGSO -Wp,-w"
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
         ;;
     esac
 
@@ -3003,11 +3066,12 @@ rm -f conftest.$ac_objext conftest.$ac_ext
           CXXFLAGSG="$CXXFLAGS -model ansi -std strict_ansi -w1 -msg_display_number -timplicit_local -DDEBUG"
           CXXFLAGSO="$CXXFLAGS -model ansi -std strict_ansi -w2 -msg_display_number -timplicit_local -fast"
 
-          for i in 175 236 237 381 487 1136 1156 111 1182 265 ; do
+          for i in 175 236 237 381 487 1136 1156 111 1182 265 450 ; do
             CXXFLAGSG="$CXXFLAGSG -msg_disable $i"
             CXXFLAGSO="$CXXFLAGSO -msg_disable $i"
           done
 
+
                               LDFLAGS="$LDFLAGS -model ansi"
 
                               LDFLAGS="$LDFLAGS -lm"
@@ -3042,6 +3106,13 @@ rm -f conftest.$ac_objext conftest.$ac_ext
          # for linking shared libs, -b is also necessary...
           ;;
 
+      borland_bcc)
+          CXXFLAGSG="$CXXFLAGS -q -DDEBUG -w -w-use -w-amp -w-prc"
+          CXXFLAGSO="$CXXFLAGS -q -O2"
+          CXXFLAGSPIC=""
+          LDFLAGSPIC=""
+          ;;
+
       *)
           { { echo "$as_me:$LINENO: error: No compiler options for this C++ compiler
                        specified at present" >&5
@@ -3174,7 +3245,15 @@ rm -f conftest.$ac_objext conftest.$ac_ext
     esac
 
   else
-        CXXFLAGSG="-g $CXXFLAGSG"
+            case "$GXX_VERSION" in
+      borland_bcc)
+       CXXFLAGSG="-v -y $CXXFLAGSG"
+       ;;
+
+      *)
+       CXXFLAGSG="-g $CXXFLAGSG"
+       ;;
+    esac
   fi
 
 
@@ -3261,6 +3340,7 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
+  CXXFLAGS="$CXXFLAGSG"
   cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
@@ -3357,13 +3437,13 @@ echo "$as_me: error: No threading compiler options for this C++ compiler
       gcc*)
        echo "$as_me:$LINENO: checking for only partly bracketed mutex initializer" >&5
 echo $ECHO_N "checking for only partly bracketed mutex initializer... $ECHO_C" >&6
-       CXXFLAGS="$CXXFLAGSG -Werror"
        ac_ext=cc
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
+       CXXFLAGS="$CXXFLAGSG -Werror"
        cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
@@ -3443,6 +3523,7 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
+  CXXFLAGS="$CXXFLAGSG"
   cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
@@ -4173,8 +4254,8 @@ _ACEOF
 
 
 
-  echo "$as_me:$LINENO: checking for template friend in namespace bug" >&5
-echo $ECHO_N "checking for template friend in namespace bug... $ECHO_C" >&6
+  echo "$as_me:$LINENO: checking for 1st template friend in namespace bug" >&5
+echo $ECHO_N "checking for 1st template friend in namespace bug... $ECHO_C" >&6
   ac_ext=cc
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4250,6 +4331,78 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+
+  echo "$as_me:$LINENO: checking for 2nd template friend in namespace bug" >&5
+echo $ECHO_N "checking for 2nd template friend in namespace bug... $ECHO_C" >&6
+  ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  CXXFLAGS="$CXXFLAGSG -Werror"
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+       namespace NS {
+         template <typename> struct Foo;
+       }
+
+       class Bar {
+           template <typename Y> friend struct NS::Foo;
+       };
+
+       namespace NS {
+         template <typename> struct Foo { Foo (); };
+       }
+
+       template struct NS::Foo<int>;
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: yes. using workaround" >&5
+echo "${ECHO_T}yes. using workaround" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define DEAL_II_NAMESP_TEMPL_FRIEND_BUG2 1
+_ACEOF
+
+
 fi
 rm -f conftest.$ac_objext conftest.$ac_ext
 
@@ -4817,6 +4970,67 @@ fi
 rm -f conftest.$ac_objext conftest.$ac_ext
 
 
+  if test "x$GXX_VERSION" != "x" ; then
+    echo "$as_me:$LINENO: checking for boost::shared_ptr assignment operator= template buglet" >&5
+echo $ECHO_N "checking for boost::shared_ptr assignment operator= template buglet... $ECHO_C" >&6
+    ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    CXXFLAGS="-Wsynth -Werror -I `pwd`/contrib/boost/include"
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#       include <boost_local/shared_ptr.hpp>
+
+int
+main ()
+{
+
+        boost::shared_ptr<int> a,b;
+        a = b;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+        echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+        echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       CXXFLAGSG="`echo $CXXFLAGSG | perl -pi -e 's/-Wsynth\s*//g;'`"
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  fi
+
+
   echo "$as_me:$LINENO: checking for __PRETTY_FUNCTION__" >&5
 echo $ECHO_N "checking for __PRETTY_FUNCTION__... $ECHO_C" >&6
   ac_ext=cc
@@ -5385,6 +5599,7 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
+  CXXFLAGS="$CXXFLAGSG"
   cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
@@ -5863,6 +6078,8 @@ echo "${ECHO_T}using $testflag" >&6
 
 
 
+  echo "$as_me:$LINENO: checking for rand_r" >&5
+echo $ECHO_N "checking for rand_r... $ECHO_C" >&6
   ac_ext=cc
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5870,8 +6087,6 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
   CXXFLAGS=$CXXFLAGSG
-  echo "$as_me:$LINENO: checking for rand_r" >&5
-echo $ECHO_N "checking for rand_r... $ECHO_C" >&6
   cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
@@ -5988,8 +6203,8 @@ fi
 rm -f conftest.$ac_objext conftest.$ac_ext
 
 
-  echo "$as_me:$LINENO: checking for defintions of error codes in errno.h" >&5
-echo $ECHO_N "checking for defintions of error codes in errno.h... $ECHO_C" >&6
+  echo "$as_me:$LINENO: checking for definitions of error codes in errno.h" >&5
+echo $ECHO_N "checking for definitions of error codes in errno.h... $ECHO_C" >&6
   ac_ext=cc
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -6798,6 +7013,8 @@ echo "$as_me:$LINENO: result: ------------------ checking compiler flags -------
 echo "${ECHO_T}------------------ checking compiler flags ------------------" >&6
 
 
+  echo "$as_me:$LINENO: checking for consistency of CXXFLAGSG flags" >&5
+echo $ECHO_N "checking for consistency of CXXFLAGSG flags... $ECHO_C" >&6
   ac_ext=cc
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -6805,8 +7022,6 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
   CXXFLAGS="$CXXFLAGSG"
-  echo "$as_me:$LINENO: checking for consistency of CXXFLAGSG flags" >&5
-echo $ECHO_N "checking for consistency of CXXFLAGSG flags... $ECHO_C" >&6
   cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
@@ -6852,9 +7067,9 @@ echo "$as_me: error: invalid combination of flags!" >&2;}
 fi
 rm -f conftest.$ac_objext conftest.$ac_ext
 
-  CXXFLAGS="$CXXFLAGSO"
   echo "$as_me:$LINENO: checking for consistency of CXXFLAGSO flags" >&5
 echo $ECHO_N "checking for consistency of CXXFLAGSO flags... $ECHO_C" >&6
+  CXXFLAGS="$CXXFLAGSO"
   cat >conftest.$ac_ext <<_ACEOF
 #line $LINENO "configure"
 /* confdefs.h.  */
index 00f68ec07d9d7686bbe55ac8f6242d55bfc04951..1593df5c551e0732a3876bc14feab6a73ea0f5b5 100644 (file)
@@ -167,6 +167,7 @@ DEAL_II_CHECK_LOCAL_TYPEDEF_COMP
 DEAL_II_CHECK_TEMPLATE_SPEC_ACCESS
 DEAL_II_CHECK_MEMBER_OP_TEMPLATE_INST
 DEAL_II_CHECK_NAMESP_TEMPL_FRIEND_BUG
+DEAL_II_CHECK_NAMESP_TEMPL_FRIEND_BUG2
 DEAL_II_CHECK_TEMPL_SPEC_FRIEND_BUG
 DEAL_II_CHECK_TEMPL_CONST_MEM_PTR_BUG
 DEAL_II_CHECK_CONST_MEM_FUN_PTR_BUG
@@ -175,6 +176,7 @@ DEAL_II_CHECK_TEMPLATE_TEMPLATE_TYPEDEF_BUG
 DEAL_II_CHECK_NESTED_CLASS_FRIEND_BUG
 DEAL_II_CHECK_MEMBER_VAR_SPECIALIZATION_BUG
 DEAL_II_CHECK_LONG_DOUBLE_LOOP_BUG
+DEAL_II_CHECK_BOOST_SHARED_PTR_ASSIGNMENT
 DEAL_II_HAVE_PRETTY_FUNCTION
 DEAL_II_HAVE_STD_ITERATOR
 DEAL_II_HAVE_STD_STRINGSTREAM
index 9b619410ff5f3d844a146cbcd451d24ddb192553..91f34ef2e827b07e974e3a7efdaab0df04c9c82e 100644 (file)
@@ -243,11 +243,12 @@ int main ()
   pid_t master_pid;
   get (&master_pid, 1, "master_pid");
                                    // ...and start off a thread that
-                                   // actually checks that
-  Threads::ThreadManager thread_manager;
-  Threads::spawn (thread_manager,
-                  Threads::encapsulate (&monitor_parent_liveness)
-                  .collect_args(master_pid, getpid()));
+                                   // actually checks that. this
+                                   // second process will eventually
+                                   // be kill when we exit the main
+                                   // program, but part from that we
+                                   // create it detached
+  Threads::spawn (&monitor_parent_liveness)(master_pid, getpid());
   
                                    // then go into the action loop...
   unsigned int N, NZ, NSTEPS, LA, MAXFRT, LIW;
@@ -373,14 +374,11 @@ int main ()
                     getpid());
         };
     };
-                                   // exit here explicitly, without
-                                   // giving the thread manager a
-                                   // chance to wait for the child
-                                   // thread, since that will loop
-                                   // forever. however, we should
+                                   // exit without waiting for the
+                                   // child thread, since that will
+                                   // loop forever. however, we should
                                    // never be able to get to this
                                    // point anyway...
-  exit (1);
 }
 
                 
index d05aa72fda2850033c7b4cffaba7524454618457..b4202eb69e6734ae570f0f279580df8e3c0e9f8c 100644 (file)
@@ -1550,7 +1550,7 @@ count_dofs_per_component (const DoFHandler<dim>     &dof_handler,
   std::vector<std::vector<bool> >
     component_select (n_components,
                       std::vector<bool>(n_components, false));
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
   for (unsigned int i=0; i<n_components; ++i)
     {
       void (*fun_ptr) (const DoFHandler<dim>      &,
@@ -1558,12 +1558,10 @@ count_dofs_per_component (const DoFHandler<dim>     &dof_handler,
                       std::vector<bool>          &)
         = &DoFTools::template extract_dofs<dim>;
       component_select[i][i] = true;
-      Threads::spawn (thread_manager,
-                     Threads::encapsulate (fun_ptr)
-                     .collect_args (dof_handler, component_select[i],
-                                    dofs_in_component[i]));
+      threads += Threads::spawn (fun_ptr)(dof_handler, component_select[i],
+                                          dofs_in_component[i]);
     };
-  thread_manager.wait();
+  threads.join_all ();
 
                                   // next count what we got
   for (unsigned int i=0; i<n_components; ++i)
@@ -2167,7 +2165,7 @@ DoFTools::compute_intergrid_weights_2 (const DoFHandler<dim>              &coars
                                                                 coarse_grid.end(),
                                                                 multithread_info.n_default_threads);
 
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
   void (*fun_ptr) (const DoFHandler<dim>              &,
                   const unsigned int                  ,
                   const InterGridMap<DoFHandler,dim> &,
@@ -2178,16 +2176,14 @@ DoFTools::compute_intergrid_weights_2 (const DoFHandler<dim>              &coars
                   const typename DoFHandler<dim>::active_cell_iterator &)
     = &DoFTools::template compute_intergrid_weights_3<dim>;
   for (unsigned int i=0; i<multithread_info.n_default_threads; ++i)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (fun_ptr)
-                   .collect_args (coarse_grid, coarse_component,
-                                  coarse_to_fine_grid_map, parameter_dofs,
-                                  weight_mapping, weights,
-                                  cell_intervals[i].first,
-                                  cell_intervals[i].second));
+    threads += Threads::spawn (fun_ptr)(coarse_grid, coarse_component,
+                                        coarse_to_fine_grid_map, parameter_dofs,
+                                        weight_mapping, weights,
+                                        cell_intervals[i].first,
+                                        cell_intervals[i].second);
 
                                   // wait for the threads to finish
-  thread_manager.wait ();
+  threads.join_all ();
 }
 
 
index 1501ffeeb192e8db3bbc831c7286a944456c464b..9ce2b3521f5e73c9042fb953480de07b18f0c9e0 100644 (file)
@@ -955,12 +955,10 @@ void GridGenerator::laplace_transformation (Triangulation<dim> &tria,
   std::vector<Vector<double> > us(dim, Vector<double> (dof_handler.n_dofs()));
   
                                   // solve linear systems in parallel
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
   for (unsigned int i=0; i<dim; ++i)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (&GridGenerator::laplace_solve)
-                   .collect_args (S, m[i], us[i]));
-  thread_manager.wait ();
+    threads += Threads::spawn (&GridGenerator::laplace_solve)(S, m[i], us[i]);
+  threads.join_all ();
   
                                   // change the coordinates of the
                                   // points of the triangulation
index 493194639374b3ed1379357db15001af5ff803a4..8d3e0105bfc4d12ad3d8d0a3f9197bb4f1172ecf 100644 (file)
@@ -321,7 +321,7 @@ MGTools::count_dofs_per_component (const MGDoFHandler<dim>& dof_handler,
          std::vector<std::vector<bool> >
            component_select (n_components,
                              std::vector<bool>(n_components, false));
-         Threads::ThreadManager thread_manager;
+         Threads::ThreadGroup<> threads;
          for (unsigned int i=0; i<n_components; ++i)
            {
              void (*fun_ptr) (const unsigned int       level,
@@ -330,12 +330,10 @@ MGTools::count_dofs_per_component (const MGDoFHandler<dim>& dof_handler,
                               std::vector<bool>          &)
                = &DoFTools::template extract_level_dofs<dim>;
              component_select[i][i] = true;
-             Threads::spawn (thread_manager,
-                             Threads::encapsulate (fun_ptr)
-                             .collect_args (l, dof_handler, component_select[i],
-                                            dofs_in_component[i]));
+             threads += Threads::spawn (fun_ptr)(l, dof_handler, component_select[i],
+                                                  dofs_in_component[i]);
            };
-         thread_manager.wait();
+         threads.join_all();
          
                                           // next count what we got
          for (unsigned int i=0; i<n_components; ++i)
index a2d7a01317834f4c100741e287f46d64d9c1b4d3..0571e0f9d41dd7a033e28712657eaeb9295c7a10 100644 (file)
@@ -628,12 +628,10 @@ void DataOut<dim>::build_patches (const unsigned int n_subdivisions,
        thread_data[i].patch_values_system[k].reinit(n_components);
     }
 
-  Threads::ThreadManager thread_manager;  
+  Threads::ThreadGroup<> threads;  
   for (unsigned int l=0; l<n_threads; ++l)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (&DataOut<dim>::build_some_patches)
-                   .collect_args (this, thread_data[l]));
-  thread_manager.wait();
+    threads += Threads::spawn (*this, &DataOut<dim>::build_some_patches)(thread_data[l]);
+  threads.join_all();
 }
 
 
index 1ce9a141c0aeab4adbdc31d263fabcebf729710d..b56dea8934ff86da4483716a6d11090e07bce19e 100644 (file)
@@ -201,12 +201,10 @@ void DataOutFaces<dim>::build_patches (const unsigned int n_subdivisions,
 
   if (DEAL_II_USE_MT)
     {
-      Threads::ThreadManager thread_manager;  
+      Threads::ThreadGroup<> threads;  
       for (unsigned int l=0;l<n_threads;++l)
-        Threads::spawn (thread_manager,
-                        Threads::encapsulate (&DataOutFaces<dim>::build_some_patches)
-                        .collect_args (this, thread_data[l]));
-      thread_manager.wait();
+        threads += Threads::spawn (*this, &DataOutFaces<dim>::build_some_patches)(thread_data[l]);
+      threads.join_all();
     }
   else
                                   // just one thread
index e15a615de8d7dd4baafba0548de1d3bb25fa07f4..c91ef5c30ddc8e9bcdeb909af8b2b2b0a64970d1 100644 (file)
@@ -385,12 +385,11 @@ void DataOutRotation<dim>::build_patches (const unsigned int n_patches_per_circl
 
   if (DEAL_II_USE_MT)
     {
-      Threads::ThreadManager thread_manager;  
+      Threads::ThreadGroup<> threads;  
       for (unsigned int l=0;l<n_threads;++l)
-        Threads::spawn (thread_manager,
-                        Threads::encapsulate (&DataOutRotation<dim>::build_some_patches)
-                        .collect_args (this, thread_data[l]));
-      thread_manager.wait();
+        threads += Threads::spawn (*this, &DataOutRotation<dim>::build_some_patches)
+                   (thread_data[l]);
+      threads.join_all();
     }
   else
                                      // just one thread
index 34ad0e83bbb0e9257792548a8ea339e601aae8bf..7549c9b07975f308a798a402cdfc376001d1a96b 100644 (file)
@@ -468,7 +468,7 @@ approximate_derivative (const Mapping<dim>    &mapping,
   std::vector<IndexInterval> index_intervals
     = Threads::split_interval (0, dof_handler.get_tria().n_active_cells(),
                               n_threads);
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
   void (*fun_ptr) (const Mapping<dim>    &,
                   const DoFHandler<dim> &,
                   const Vector<double>  &,
@@ -477,12 +477,10 @@ approximate_derivative (const Mapping<dim>    &mapping,
                   Vector<float>         &)
     = &DerivativeApproximation::template approximate<DerivativeDescription,dim>;
   for (unsigned int i=0; i<n_threads; ++i)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate(fun_ptr)
-                   .collect_args (mapping, dof_handler, solution, component,
-                                  index_intervals[i],
-                                  derivative_norm));
-  thread_manager.wait ();
+    threads += Threads::spawn (fun_ptr)(mapping, dof_handler, solution, component,
+                                        index_intervals[i],
+                                        derivative_norm);
+  threads.join_all ();
 }
 
 
index b027777bf96402f9d9fea8cb7922e4e5a303ec65..51fe74f0c8409f4f15b0a7719bde9584aabc5d53 100644 (file)
@@ -634,17 +634,16 @@ KellyErrorEstimator<dim>::estimate (const Mapping<dim>                  &mapping
                                   // split all cells into threads if
                                   // multithreading is used and run
                                   // the whole thing
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
   for (unsigned int i=0; i<n_threads; ++i)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (&KellyErrorEstimator<dim>::estimate_some)
-                   .collect_args (mapping, dof_handler,
-                                   quadrature, neumann_bc, solutions,
-                                   component_mask, coefficients,
-                                   std::make_pair(i, n_threads),
-                                   face_integrals,
-                                   *data_structures[i]));
-  thread_manager.wait();
+    threads += Threads::spawn (&KellyErrorEstimator<dim>::estimate_some)
+               (mapping, dof_handler,
+                quadrature, neumann_bc, solutions,
+                component_mask, coefficients,
+                std::make_pair(i, n_threads),
+                face_integrals,
+                *data_structures[i]);
+  threads.join_all();
 
                                   // delete the structures for the
                                   // different threads again. the
index 861d3f02baf4a58183180e039b81a02ee8415fc8..faa104f129bafbc1a1ff1e4e3ab35e473c3102bd 100644 (file)
@@ -71,7 +71,7 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
          ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
 
   const unsigned int n_threads = multithread_info.n_default_threads;
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
 
                                   // define starting and end point
                                   // for each thread
@@ -94,11 +94,9 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
                                          Threads::ThreadMutex     &mutex);
   create_mass_matrix_1_t p = &MatrixCreator::template create_mass_matrix_1<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate(p)
-                   .collect_args (mapping, dof, q, matrix, coefficient,
-                                  thread_ranges[thread], mutex));
-  thread_manager.wait ();  
+    threads += Threads::spawn (p)(mapping, dof, q, matrix, coefficient,
+                                  thread_ranges[thread], mutex);
+  threads.join_all ();  
 }
 
 
@@ -251,7 +249,7 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
          ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
 
   const unsigned int n_threads = multithread_info.n_default_threads;
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
 
                                   // define starting and end point
                                   // for each thread
@@ -276,12 +274,10 @@ void MatrixCreator::create_mass_matrix (const Mapping<dim>       &mapping,
                                          Threads::ThreadMutex     &mutex);
   create_mass_matrix_2_t p = &MatrixCreator::template create_mass_matrix_2<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate(p)
-                   .collect_args (mapping, dof, q, matrix, rhs,
-                                  rhs_vector, coefficient,
-                                  thread_ranges[thread], mutex));
-  thread_manager.wait ();  
+    threads += Threads::spawn (p)(mapping, dof, q, matrix, rhs,
+                                  rhs_vector, coefficient,
+                                  thread_ranges[thread], mutex);
+  threads.join_all ();  
 }
 
 
@@ -470,7 +466,7 @@ MatrixCreator::create_boundary_mass_matrix (const Mapping<dim>        &mapping,
                                            const Function<dim> * const coefficient)
 {
   const unsigned int n_threads = multithread_info.n_default_threads;
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
 
                                   // define starting and end point
                                   // for each thread
@@ -497,13 +493,11 @@ MatrixCreator::create_boundary_mass_matrix (const Mapping<dim>        &mapping,
        Threads::ThreadMutex      &mutex);
   create_boundary_mass_matrix_1_t p = &MatrixCreator::template create_boundary_mass_matrix_1<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate(p)
-                   .collect_args (mapping, dof, q, matrix,
-                                  boundary_functions, rhs_vector,
-                                  dof_to_boundary_mapping, coefficient,
-                                  thread_ranges[thread], mutex));
-  thread_manager.wait ();  
+    threads += Threads::spawn (p)(mapping, dof, q, matrix,
+                                  boundary_functions, rhs_vector,
+                                  dof_to_boundary_mapping, coefficient,
+                                  thread_ranges[thread], mutex);
+  threads.join_all ();  
 }
 
 
@@ -898,7 +892,7 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
          ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
 
   const unsigned int n_threads = multithread_info.n_default_threads;
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
 
                                   // define starting and end point
                                   // for each thread
@@ -921,11 +915,9 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
                                             Threads::ThreadMutex     &mutex);
   create_laplace_matrix_1_t p = &MatrixCreator::template create_laplace_matrix_1<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate(p)
-                   .collect_args (mapping, dof, q, matrix, coefficient,
-                                  thread_ranges[thread], mutex));
-  thread_manager.wait ();  
+    threads += Threads::spawn (p)(mapping, dof, q, matrix, coefficient,
+                                  thread_ranges[thread], mutex);
+  threads.join_all ();  
 }
 
 
@@ -1081,7 +1073,7 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
          ExcDimensionMismatch (matrix.n(), dof.n_dofs()));
 
   const unsigned int n_threads = multithread_info.n_default_threads;
-  Threads::ThreadManager thread_manager;
+  Threads::ThreadGroup<> threads;
 
                                   // define starting and end point
                                   // for each thread
@@ -1106,12 +1098,10 @@ void MatrixCreator::create_laplace_matrix (const Mapping<dim>       &mapping,
                                             Threads::ThreadMutex     &mutex);
   create_laplace_matrix_2_t p = &MatrixCreator::template create_laplace_matrix_2<dim>;
   for (unsigned int thread=0; thread<n_threads; ++thread)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate(p)
-                   .collect_args (mapping, dof, q, matrix, rhs,
-                                  rhs_vector, coefficient,
-                                  thread_ranges[thread], mutex));
-  thread_manager.wait ();  
+    threads += Threads::spawn (p)(mapping, dof, q, matrix, rhs,
+                                  rhs_vector, coefficient,
+                                  thread_ranges[thread], mutex);
+  threads.join_all ();  
 }
 
 
index 8ac6682f516467476906ecf12c0faa174d3b446b..641746e35b42b09cf90bca4fa3f427e77bb13e7e 100644 (file)
@@ -205,17 +205,15 @@ void TimeDependent::end_sweep (const unsigned int n_threads)
   if (DEAL_II_USE_MT && (n_threads > 1))
     {
       const unsigned int stride = timesteps.size() / n_threads;
-      Threads::ThreadManager thread_manager;
+      Threads::ThreadGroup<> threads;
       void (TimeDependent::*p) (const unsigned int, const unsigned int)
         = &TimeDependent::end_sweep;
       for (unsigned int i=0; i<n_threads; ++i)
-        Threads::spawn (thread_manager,
-                        Threads::encapsulate (p)
-                        .collect_args (this, i*stride,
-                                       (i == n_threads-1 ?
-                                        timesteps.size() :
-                                        (i+1)*stride)));
-      thread_manager.wait();
+        threads += Threads::spawn (*this, p)(i*stride,
+                                             (i == n_threads-1 ?
+                                              timesteps.size() :
+                                              (i+1)*stride));
+      threads.join_all();
     }
   else
                                      // now do the work
index d550b40139d81a170991a31503bc0e78fa7875a5..acab8e761be69e233b699073a590f1b0a10d0daf 100644 (file)
@@ -1197,7 +1197,7 @@ namespace LaplaceSolver
 
                                     // These ranges are then assigned
                                     // to a number of threads which
-                                    // we create next, which each
+                                    // we create next. Each will
                                     // assemble the local cell
                                     // matrices on the assigned
                                     // cells, and fill the matrix
@@ -1207,15 +1207,13 @@ namespace LaplaceSolver
                                     // different threads, we need a
                                     // mutex here:
     Threads::ThreadMutex mutex;
-    Threads::ThreadManager thread_manager;
+    Threads::ThreadGroup<> threads;
     for (unsigned int thread=0; thread<n_threads; ++thread)
-      Threads::spawn (thread_manager,
-                     Threads::encapsulate(&Solver<dim>::assemble_matrix)
-                     .collect_args (this,
-                                    linear_system,
-                                    thread_ranges[thread].first,
-                                    thread_ranges[thread].second,
-                                    mutex));
+      threads += Threads::spawn (*this, &Solver<dim>::assemble_matrix)
+                 (linear_system,
+                  thread_ranges[thread].first,
+                  thread_ranges[thread].second,
+                  mutex);
 
                                     // While the spawned threads
                                     // assemble the system matrix, we
@@ -1244,7 +1242,7 @@ namespace LaplaceSolver
                                     // matrix assembling threads, and
                                     // condense the constraints in
                                     // the matrix as well:
-    thread_manager.wait ();
+    threads.join_all ();
     linear_system.hanging_node_constraints.condense (linear_system.matrix);
 
                                     // Now that we have the linear
@@ -1420,7 +1418,13 @@ namespace LaplaceSolver
                                   // performed sequentially). Note
                                   // that we spawn only one thread,
                                   // and do the second action in the
-                                  // main thread.
+                                  // main thread. Since only one
+                                  // thread is generated, we don't
+                                  // use the ``Threads::ThreadGroup''
+                                  // class here, but rather use the
+                                  // one created thread object
+                                  // directly to wait for this
+                                  // particular thread's exit.
                                   //
                                   // Note that taking up the address
                                   // of the
@@ -1468,11 +1472,9 @@ namespace LaplaceSolver
                    ConstraintMatrix      &)
       = &DoFTools::make_hanging_node_constraints;
     
-    Threads::ThreadManager thread_manager;
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (mhnc_p)
-                   .collect_args (dof_handler,
-                                  hanging_node_constraints));
+    Threads::Thread<>
+      mhnc_thread = Threads::spawn (mhnc_p)(dof_handler,
+                                            hanging_node_constraints);
 
     sparsity_pattern.reinit (dof_handler.n_dofs(),
                             dof_handler.n_dofs(),
@@ -1484,7 +1486,7 @@ namespace LaplaceSolver
                                     // object is fully set up, then
                                     // close it and use it to
                                     // condense the sparsity pattern:
-    thread_manager.wait ();
+    mhnc_thread.join ();
     hanging_node_constraints.close ();
     hanging_node_constraints.condense (sparsity_pattern);
 
index 6b2b02af5adf213ece0d6d059e087afd2112543a..ea5cc546e4a2195d397013bfbda24f565835fab3 100644 (file)
@@ -656,15 +656,13 @@ namespace LaplaceSolver
                                                    n_threads);
 
     Threads::ThreadMutex mutex;
-    Threads::ThreadManager thread_manager;
+    Threads::ThreadGroup<> threads;
     for (unsigned int thread=0; thread<n_threads; ++thread)
-      Threads::spawn (thread_manager,
-                     Threads::encapsulate(&Solver<dim>::assemble_matrix)
-                     .collect_args (this,
-                                    linear_system,
-                                    thread_ranges[thread].first,
-                                    thread_ranges[thread].second,
-                                    mutex));
+      threads += Threads::spawn (*this, &Solver<dim>::assemble_matrix)
+                 (linear_system,
+                  thread_ranges[thread].first,
+                  thread_ranges[thread].second,
+                  mutex);
 
     assemble_rhs (linear_system.rhs);
     linear_system.hanging_node_constraints.condense (linear_system.rhs);
@@ -675,7 +673,7 @@ namespace LaplaceSolver
                                              *boundary_values,
                                              boundary_value_map);
     
-    thread_manager.wait ();
+    threads.join_all ();
     linear_system.hanging_node_constraints.condense (linear_system.matrix);
 
     MatrixTools::apply_boundary_values (boundary_value_map,
@@ -739,18 +737,15 @@ namespace LaplaceSolver
                    ConstraintMatrix      &)
       = &DoFTools::make_hanging_node_constraints;
     
-    Threads::ThreadManager thread_manager;
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (mhnc_p)
-                   .collect_args (dof_handler,
-                                  hanging_node_constraints));
+    Threads::Thread<>
+      mhnc_thread = Threads::spawn (mhnc_p)(dof_handler, hanging_node_constraints);
 
     sparsity_pattern.reinit (dof_handler.n_dofs(),
                             dof_handler.n_dofs(),
                             dof_handler.max_couplings_between_dofs());
     DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
 
-    thread_manager.wait ();
+    mhnc_thread.join ();
     hanging_node_constraints.close ();
     hanging_node_constraints.condense (sparsity_pattern);
 
@@ -2651,14 +2646,10 @@ namespace LaplaceSolver
   void
   WeightedResidual<dim>::solve_problem ()
   {
-    Threads::ThreadManager thread_manager;
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (&WeightedResidual<2>::solve_primal_problem)
-                   .collect_args (this));
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (&WeightedResidual<2>::solve_dual_problem)
-                   .collect_args (this));
-    thread_manager.wait ();
+    Threads::ThreadGroup<> threads;
+    threads += Threads::spawn (*this, &WeightedResidual<2>::solve_primal_problem)();
+    threads += Threads::spawn (*this, &WeightedResidual<2>::solve_dual_problem)();
+    threads.join_all ();
   }
 
   
@@ -3007,7 +2998,8 @@ namespace LaplaceSolver
                                     // us from the necessity to
                                     // synchronise the threads
                                     // through a mutex each time they
-                                    // write to this map.
+                                    // write to (and modify the
+                                    // structure of) this map.
     FaceIntegrals face_integrals;
     for (active_cell_iterator cell=dual_solver.dof_handler.begin_active();
         cell!=dual_solver.dof_handler.end();
@@ -3031,18 +3023,15 @@ namespace LaplaceSolver
                                     // started wait until they have
                                     // all finished:
     const unsigned int n_threads = multithread_info.n_default_threads;
-    Threads::ThreadManager thread_manager;
+    Threads::ThreadGroup<> threads;
     for (unsigned int i=0; i<n_threads; ++i)
-      Threads::spawn (thread_manager,
-                     Threads::encapsulate (&WeightedResidual<dim>::
-                                           estimate_some)
-                     .collect_args (this,
-                                    primal_solution,
-                                    dual_weights,
-                                    n_threads, i,
-                                    error_indicators,
-                                    face_integrals));
-    thread_manager.wait();    
+      threads += Threads::spawn (*this, &WeightedResidual<dim>::estimate_some)
+                 (primal_solution,
+                  dual_weights,
+                  n_threads, i,
+                  error_indicators,
+                  face_integrals);
+    threads.join_all();    
 
                                     // Once the error contributions
                                     // are computed, sum them up. For
index 3be63565dce3c487e74899ea10bb82a61cc2605e..bedbda9b031d40ce773834cd0ad52a17bcc597cc 100644 (file)
                                 // functions are declared which we
                                 // need to start new threads and to
                                 // wait for threads to return
-                                // (i.e. the ``ThreadManager'' class
-                                // and the ``spawn'',
-                                // ``encapsulate'', and
-                                // ``collect_args'' functions). The
+                                // (i.e. the ``Thread'' class
+                                // and the ``spawn'' functions). The
                                 // second file has a class
                                 // ``MultithreadInfo'' (and a global
                                 // object ``multithread_info'' of
@@ -162,8 +160,8 @@ class AdvectionProblem
                                     // local contributions of a cell
                                     // to the global matrix at the
                                     // same time. This is done using
-                                    // a ``Mutex'', which is a kind
-                                    // of lock that can be owned by
+                                    // a ``Mutex'', which is an
+                                    // object that can be owned by
                                     // only one thread at a time. If
                                     // a thread wants to write to the
                                     // matrix, it has to acquire this
@@ -744,33 +742,53 @@ void AdvectionProblem<dim>::assemble_system ()
                                   // many threads they shall spawn.
   const unsigned int n_threads = multithread_info.n_default_threads;
                                   // Next, we need an object which is
-                                  // capable of starting new threads
-                                  // and waiting for them to
-                                  // finish. This is done using the
-                                  // ``Threads::ThreadManager''
-                                  // typedef. If the library is
-                                  // configured to support
-                                  // multi-threading, then this
-                                  // typedef points to a class in the
-                                  // ACE library which provides this
-                                  // functionality. If you did not
-                                  // configure for multi-threading,
-                                  // then the typedef points to a
-                                  // dummy class in which the
+                                  // capable of keeping track of the
+                                  // threads we created, and allows
+                                  // us to wait until they all have
+                                  // finished (to ``join'' them in
+                                  // the language of threads). The
+                                  // ``Threads::ThreadGroup'' class
+                                  // does this, which is basically
+                                  // just a container for objects of
+                                  // type ``Threads::Thread'' that
+                                  // represent a single thread;
+                                  // ``Threads::Thread'' is what the
+                                  // ``spawn'' function below will
+                                  // return when we start a new
+                                  // thread.
+                                  //
+                                  // Note that both ``ThreadGroup''
+                                  // and ``Thread'' have a template
+                                  // argument that represents the
+                                  // return type of the function
+                                  // being called on a separate
+                                  // thread. Since most of the
+                                  // functions that we will call on
+                                  // different threads have return
+                                  // type ``void'', the template
+                                  // argument has a default value
+                                  // ``void'', so that in that case
+                                  // it can be omitted. (However, you
+                                  // still need to write the angle
+                                  // brackets, even if they are
+                                  // empty.)
+                                  //
+                                  // If you did not configure for
+                                  // multi-threading, then the
                                   // ``spawn'' function that is
                                   // supposed to start a new thread
                                   // in parallel only executes the
                                   // function which should be run in
-                                  // parallel and waits for it to
-                                  // return (i.e. the function is
-                                  // executed
-                                  // sequentially). Likewise, the
-                                  // function ``wait'' that is
-                                  // supposed to wait for all spawned
-                                  // threads to return, returns
-                                  // immediately, as there can't be
-                                  // threads running.
-  Threads::ThreadManager thread_manager;
+                                  // parallel, waits for it to return
+                                  // (i.e. the function is executed
+                                  // sequentially), and puts the
+                                  // return value into the ``Thread''
+                                  // object. Likewise, the function
+                                  // ``join'' that is supposed to
+                                  // wait for all spawned threads to
+                                  // return, returns immediately, as
+                                  // there can't be threads running.
+  Threads::ThreadGroup<> threads;
 
                                   // Now we have to split the range
                                   // of cells into chunks of
@@ -827,8 +845,8 @@ void AdvectionProblem<dim>::assemble_system ()
                                                  dof_handler.end (),
                                                  n_threads);
 
-                                  // Now, for each of the chunks of
-                                  // iterators we have computed,
+                                  // Finally, for each of the chunks
+                                  // of iterators we have computed,
                                   // start one thread (or if not in
                                   // multi-thread mode: execute
                                   // assembly on these chunks
@@ -836,11 +854,9 @@ void AdvectionProblem<dim>::assemble_system ()
                                   // using the following sequence of
                                   // function calls:
   for (unsigned int thread=0; thread<n_threads; ++thread)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate(&AdvectionProblem<dim>::assemble_system_interval)
-                   .collect_args (this,
-                                  thread_ranges[thread].first,
-                                  thread_ranges[thread].second));
+    threads += Threads::spawn (*this, &AdvectionProblem<dim>::assemble_system_interval)
+               (thread_ranges[thread].first,
+                thread_ranges[thread].second);
                                   // The reasons and internal
                                   // workings of these functions can
                                   // be found in the report on the
@@ -851,11 +867,25 @@ void AdvectionProblem<dim>::assemble_system ()
                                   // the ``assemble_system_interval''
                                   // function on the present object
                                   // (the ``this'' pointer), with the
-                                  // next to arguments passed as
-                                  // parameters. Each thread's number
-                                  // is entered into an array
-                                  // administered by the
-                                  // ``thread_manager'' object.
+                                  // arguments following in the
+                                  // second set of parentheses passed
+                                  // as parameters. The ``spawn''
+                                  // function return an object of
+                                  // type ``Threads::Thread'', which
+                                  // we put into the ``threads''
+                                  // container. If a thread exits,
+                                  // the return value of the function
+                                  // being called is put into a place
+                                  // such that the thread objects can
+                                  // access it using their
+                                  // ``return_value'' function; since
+                                  // the function we call doesn't
+                                  // have a return value, this does
+                                  // not apply here. Note that you
+                                  // can copy around thread objects
+                                  // freely, and that of course they
+                                  // will still represent the same
+                                  // thread.
 
                                   // When all the threads are
                                   // running, the only thing we have
@@ -866,18 +896,18 @@ void AdvectionProblem<dim>::assemble_system ()
                                   // right hand side are
                                   // assemblesd. Waiting for all the
                                   // threads to finish can be done
-                                  // using the following function
-                                  // call, which uses the facts that
-                                  // the identification number of the
-                                  // spawned threads are stored in
-                                  // the ``thread_manager''
-                                  // object. Again, if the library
-                                  // was not configured to use
+                                  // using the ``joint_all'' function
+                                  // in the ``ThreadGroup''
+                                  // container, which just calls
+                                  // ``join'' on each of the thread
+                                  // objects it stores.
+                                  //
+                                  // Again, if the library was not
+                                  // configured to use
                                   // multi-threading, then no threads
                                   // can run in parallel and the
-                                  // following function returns
-                                  // immediately.
-  thread_manager.wait ();  
+                                  // function returns immediately.
+  threads.join_all ();  
 
 
                                   // After the matrix has been
@@ -1190,13 +1220,13 @@ assemble_system_interval (const typename DoFHandler<dim>::active_cell_iterator &
                                       // the information on the grid,
                                       // the DoF handler, or the DoF
                                       // numbers) they are only
-                                      // read. This, the different
+                                      // read. Thus, the different
                                       // threads do not disturb each
                                       // other.
                                       //
                                       // On the other hand, we would
                                       // now like to write the local
-                                      // contributions to the glbal
+                                      // contributions to the global
                                       // system of equations into the
                                       // global objects. This needs
                                       // some kind of
@@ -1452,15 +1482,17 @@ GradientEstimation::estimate (const DoFHandler<dim> &dof_handler,
     = Threads::split_interval (0, dof_handler.get_tria().n_active_cells(),
                               n_threads);
 
-                                  // Now we need a thread management
-                                  // object, and then we can spawn
-                                  // the threads which each work on
-                                  // their assigned chunk of
-                                  // cells. Note that as the function
-                                  // called is not a member function,
-                                  // but rather a static function, we
-                                  // need not (and can not) pass a
-                                  // ``this'' function in this case.
+                                  // In the same way as before, we
+                                  // use a ``Threads::ThreadGroup''
+                                  // object to collect the descriptor
+                                  // objects of different
+                                  // threads. Note that as the
+                                  // function called is not a member
+                                  // function, but rather a static
+                                  // function, we need not (and can
+                                  // not) pass a ``this'' pointer to
+                                  // the ``spawn'' function in this
+                                  // case.
                                   //
                                   // Taking pointers to templated
                                   // functions seems to be
@@ -1477,28 +1509,27 @@ GradientEstimation::estimate (const DoFHandler<dim> &dof_handler,
                                   // to take a temporary variable for
                                   // that purpose. Here, in this
                                   // case, Compaq's ``cxx'' compiler
-                                  // choked on the code so we use the
-                                  // workaround with the function
-                                  // pointer:
-  Threads::ThreadManager thread_manager;
+                                  // choked on the code so we use
+                                  // this workaround with the
+                                  // function pointer:
+  Threads::ThreadGroup<> threads;
   void (*estimate_interval_ptr) (const DoFHandler<dim> &,
                                 const Vector<double> &,
                                 const IndexInterval &,
                                 Vector<float> &)
     = &GradientEstimation::template estimate_interval<dim>;
   for (unsigned int i=0; i<n_threads; ++i)
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (estimate_interval_ptr)
-                   .collect_args (dof_handler, solution, index_intervals[i],
-                                  error_per_cell));
+    threads += Threads::spawn (estimate_interval_ptr)(dof_handler, solution,
+                                                      index_intervals[i],
+                                                      error_per_cell);
                                   // Ok, now the threads are at work,
                                   // and we only have to wait for
                                   // them to finish their work:
-  thread_manager.wait ();
+  threads.join_all ();
                                   // Note that if the value of the
                                   // variable
                                   // ``multithread_info.n_default_threads''
-                                  // was one, of if the library was
+                                  // was one, or if the library was
                                   // not configured to use threads,
                                   // then the sequence of commands
                                   // above reduced to a complicated
index 134413ed3eb7558d75cd0989cc52e94e3190d960..3464c7da3e418160be1d837a12b374572ae363bd 100644 (file)
@@ -315,14 +315,12 @@ SparseMatrix<number>::vmult (Vector<somenumber>& dst,
       const mem_fun_p comp
        = (&SparseMatrix<number>::
            template threaded_vmult<somenumber>);
-      Threads::ThreadManager thread_manager;
+      Threads::ThreadGroup<> threads;
       for (unsigned int i=0; i<n_threads; ++i)
-       Threads::spawn (thread_manager,
-                       Threads::encapsulate (comp)
-                       .collect_args (this, dst, src,
-                                      n_rows * i / n_threads,
-                                      n_rows * (i+1) / n_threads));
-      thread_manager.wait ();
+       threads += Threads::spawn (*this, comp) (dst, src,
+                                                 n_rows * i / n_threads,
+                                                 n_rows * (i+1) / n_threads);
+      threads.join_all();
 
       return;
     }
@@ -464,7 +462,6 @@ SparseMatrix<number>::matrix_norm_square (const Vector<somenumber>& v) const
                                       // space for the norms of
                                       // the different parts
       std::vector<somenumber> partial_sums (n_threads, 0);
-      Threads::ThreadManager thread_manager;
                                       // then spawn threads. since
                                       // some compilers have trouble
                                       // finding out which
@@ -485,16 +482,15 @@ SparseMatrix<number>::matrix_norm_square (const Vector<somenumber>& v) const
       const mem_fun_p comp
        = (&SparseMatrix<number>::
            template threaded_matrix_norm_square<somenumber>);
+      Threads::ThreadGroup<> threads;
       for (unsigned int i=0; i<n_threads; ++i)
-       Threads::spawn (thread_manager,
-                       Threads::encapsulate (comp)
-                       .collect_args (this, v,
-                                      n_rows * i / n_threads,
-                                      n_rows * (i+1) / n_threads,
-                                      &partial_sums[i]));
+       threads += Threads::spawn (*this, comp)(v,
+                                                n_rows * i / n_threads,
+                                                n_rows * (i+1) / n_threads,
+                                                &partial_sums[i]);
 
                                       // ... and wait until they're finished
-      thread_manager.wait ();
+      threads.join_all ();
                                       // accumulate the partial results
       return std::accumulate (partial_sums.begin(),
                              partial_sums.end(),
@@ -577,7 +573,6 @@ SparseMatrix<number>::matrix_scalar_product (const Vector<somenumber>& u,
                                       // space for the norms of
                                       // the different parts
       std::vector<somenumber> partial_sums (n_threads, 0);
-      Threads::ThreadManager thread_manager;
                                       // then spawn threads. since
                                       // some compilers have trouble
                                       // finding out which
@@ -599,16 +594,15 @@ SparseMatrix<number>::matrix_scalar_product (const Vector<somenumber>& u,
       const mem_fun_p comp
        = (&SparseMatrix<number>::
            template threaded_matrix_scalar_product<somenumber>);
+      Threads::ThreadGroup<> threads;
       for (unsigned int i=0; i<n_threads; ++i)
-       Threads::spawn (thread_manager,
-                       Threads::encapsulate (comp)
-                       .collect_args (this, u, v,
-                                      n_rows * i / n_threads,
-                                      n_rows * (i+1) / n_threads,
-                                      &partial_sums[i]));
-
+       threads += Threads::spawn (*this, comp)(u, v,
+                                                n_rows * i / n_threads,
+                                                n_rows * (i+1) / n_threads,
+                                                &partial_sums[i]);
+  
                                       // ... and wait until they're finished
-      thread_manager.wait ();
+      threads.join_all ();
                                       // accumulate the partial results
       return std::accumulate (partial_sums.begin(),
                              partial_sums.end(),
@@ -756,18 +750,16 @@ SparseMatrix<number>::residual (Vector<somenumber>       &dst,
         somenumber               *) const;
       const mem_fun_p comp_residual = &SparseMatrix<number>::
                                     template threaded_residual<somenumber>;
-      Threads::ThreadManager thread_manager;
+      Threads::ThreadGroup<> threads;
       for (unsigned int i=0; i<n_threads; ++i)
-       Threads::spawn (thread_manager,
-                       Threads::encapsulate (comp_residual)
-                       .collect_args (this, dst, u, b,
-                                      std::pair<unsigned int,unsigned int>
-                                      (n_rows * i / n_threads,
-                                       n_rows * (i+1) / n_threads),
-                                      &partial_norms[i]));
+       threads += Threads::spawn (*this, comp_residual)(dst, u, b,
+                                                         std::pair<unsigned int,unsigned int>
+                                                         (n_rows * i / n_threads,
+                                                          n_rows * (i+1) / n_threads),
+                                                         &partial_norms[i]);
 
                                       // ... and wait until they're finished
-      thread_manager.wait ();
+      threads.join_all ();
                                       // accumulate the partial results
       return std::sqrt(std::accumulate (partial_norms.begin(),
                                        partial_norms.end(),
index de3a0631484335fd2d24faa3f9a355f9d2744309..4f3831955e22feb1e4dcd60e7807d88b4b6b86d6 100644 (file)
@@ -112,16 +112,14 @@ SparseVanka<number>::compute_inverses ()
 
       typedef void (SparseVanka<number>::*FunPtr)(const unsigned int,
                                                   const unsigned int);
-      FunPtr fun_ptr = &SparseVanka<number>::compute_inverses;
+      const FunPtr fun_ptr = &SparseVanka<number>::compute_inverses;
   
                                        // Now spawn the threads
-      Threads::ThreadManager thread_manager;
+      Threads::ThreadGroup<> threads;
       for (unsigned int i=0; i<n_threads; ++i)
-        Threads::spawn (thread_manager,
-                        Threads::encapsulate (fun_ptr)
-                        .collect_args (this, blocking[i].first, blocking[i].second));
-  
-      thread_manager.wait ();
+        threads += Threads::spawn (*this, fun_ptr)(blocking[i].first,
+                                                   blocking[i].second);
+      threads.join_all ();
     };
 }
 
@@ -594,13 +592,11 @@ void SparseBlockVanka<number>::vmult (Vector<number2>       &dst,
              const std::vector<bool> * const) const;
           const mem_fun_p comp
             = &SparseVanka<number>::template apply_preconditioner<number2>;
-          Threads::ThreadManager thread_manager;
+          Threads::ThreadGroup<> threads;
           for (unsigned int block=0; block<n_blocks; ++block)
-            Threads::spawn (thread_manager,
-                            Threads::encapsulate (comp)
-                            .collect_args (this, dst, src, &dof_masks[block]));
-          
-          thread_manager.wait ();
+            threads += Threads::spawn(*static_cast<const SparseVanka<number>*>(this), comp)
+                       (dst, src,&dof_masks[block]);
+          threads.join_all ();
         }
       else
         for (unsigned int block=0; block<n_blocks; ++block)
index 453f4022115799322101dedd8b00c7bae3c873c8..7f4cf9687fe9ca511dd0e605ba18f55e97a25bec 100644 (file)
@@ -277,18 +277,6 @@ class SwappableVector : public Vector<number>
                                      */
     Threads::ThreadMutex lock;
 
-                                    /**
-                                     * Declare a thread manager that
-                                     * is used to spawn threads in
-                                     * @p{alert} detached.
-                                     *
-                                     * If not in MT mode, then the
-                                     * class used here is empty, and
-                                     * we can as well get away
-                                     * without it.
-                                     */
-    static Threads::ThreadManager thread_manager;
-
                                     /**
                                      * Flag by which the @p{alert}
                                      * function signifies that the
index da9995a90d06d4fac78cf93b47058350d199efd5..a6f38266b2d936982bd33d27329af02fff74df99 100644 (file)
 
 
 
-                                // allocate static variable
-template <typename number>
-Threads::ThreadManager SwappableVector<number>::thread_manager;
-
-
-
-
 template <typename number>
 SwappableVector<number>::SwappableVector ()
                :
@@ -172,10 +165,9 @@ void SwappableVector<number>::alert ()
     lock.release ();
   else
                                     // data has not been preloaded so
-                                    // far, so go on!
-    Threads::spawn (thread_manager,
-                   Threads::encapsulate (&SwappableVector<number>::reload_vector)
-                   .collect_args(this, true));
+                                    // far, so go on! For this, start
+                                    // a detached thread
+    Threads::spawn (*this, &SwappableVector<number>::reload_vector)(true);
                                   // note that reload_vector also
                                   // releases the lock
 }
index 643c0529dab4583cc119eb0f43a3c5b810afdaab..2747de2d9afce883e87b0c73218571e9f91f3ef3 100644 (file)
@@ -20,6 +20,10 @@ default: run-tests
 
 ############################################################
 
+threads.cc : threads.pl
+       @echo =====regenerating== $@
+       @$(PERL) $^ > $@
+
 logtest.exe        : logtest.g.$(OBJEXT)                            $(lib-base.g)
 polynomial_test.exe: polynomial_test.g.$(OBJEXT) abort.g.$(OBJEXT)  $(lib-base.g)
 polynomial1d.exe   : polynomial1d.g.$(OBJEXT)                       $(lib-base.g)
@@ -28,12 +32,14 @@ reference.exe      : reference.g.$(OBJEXT) abort.g.$(OBJEXT)        $(libraries)
 table.exe          : table.g.$(OBJEXT)                              $(libraries)
 tensor.exe         : tensor.g.$(OBJEXT)                             $(libraries)
 timer.exe          : timer.g.$(OBJEXT)                              $(libraries)
+threads.exe        : threads.g.$(OBJEXT)                            $(libraries)
 auto_derivative_function.exe : auto_derivative_function.g.$(OBJEXT) $(libraries)
 
 
 tests = $(sort \
           logtest reference quadrature_test table tensor \
-          timer polynomial1d polynomial_test auto_derivative_function)
+          timer threads polynomial1d polynomial_test \
+         auto_derivative_function)
 
 ############################################################
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.