From c59fe09921831dad13258436118f02634522ed63 Mon Sep 17 00:00:00 2001
From: bangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Date: Thu, 8 Sep 2011 00:10:27 +0000
Subject: [PATCH] Add member functions that make the TLS object look more like
 the underlying object on the current thread.

git-svn-id: https://svn.dealii.org/trunk@24283 0785d39b-7218-0410-832d-ea1e28bc413d
---
 .../deal.II/base/thread_local_storage.h       | 38 +++++++++
 tests/base/thread_local_storage_03.cc         | 66 ++++++++++++++++
 .../base/thread_local_storage_03/cmp/generic  |  2 +
 tests/base/thread_local_storage_04.cc         | 78 +++++++++++++++++++
 .../base/thread_local_storage_04/cmp/generic  |  2 +
 5 files changed, 186 insertions(+)
 create mode 100644 tests/base/thread_local_storage_03.cc
 create mode 100644 tests/base/thread_local_storage_03/cmp/generic
 create mode 100644 tests/base/thread_local_storage_04.cc
 create mode 100644 tests/base/thread_local_storage_04/cmp/generic

diff --git a/deal.II/include/deal.II/base/thread_local_storage.h b/deal.II/include/deal.II/base/thread_local_storage.h
index e59d0dad2b..692f267742 100644
--- a/deal.II/include/deal.II/base/thread_local_storage.h
+++ b/deal.II/include/deal.II/base/thread_local_storage.h
@@ -98,6 +98,27 @@ namespace Threads
      */
     T & get ();
     
+    /**
+     * Conversion operator that simply converts the thread-local object
+     * to the data type that it stores. This function is equivalent to
+     * calling the get() member function; it's purpose is to make the
+     * TLS object look more like the object it is storing.
+     */
+    operator T & ();
+    
+    /**
+     * Copy the given argument into the storage space used to represent
+     * the current thread. Calling this function as <code>tls_data = object</code>
+     * is equivalent to calling <code>tls_data.get() = object</code>. The
+     * intent of this operator is to make the ThreadLocalStorage object
+     * look more like the object it represents on the current thread.
+     *
+     * @param t The object to be copied into the storage space used 
+     * for the current thread.
+     * 
+     * @return The current object, after the changes have been made
+     **/
+    ThreadLocalStorage<T> & operator = (const T &t);
   private:
 #if DEAL_II_USE_MT == 1
     /**
@@ -148,7 +169,24 @@ namespace Threads
 #endif        
   }
 
+
+
+  template <typename T>
+  inline
+  ThreadLocalStorage<T>::operator T& ()
+  {
+    return get();
+  }
   
+
+  template <typename T>
+  inline
+  ThreadLocalStorage<T> &
+  ThreadLocalStorage<T>::operator = (const T &t)
+  {
+    get() = t;
+    return *this;
+  }
 }   // end of implementation of namespace Threads
 
 /**
diff --git a/tests/base/thread_local_storage_03.cc b/tests/base/thread_local_storage_03.cc
new file mode 100644
index 0000000000..65fb1eb751
--- /dev/null
+++ b/tests/base/thread_local_storage_03.cc
@@ -0,0 +1,66 @@
+//-----------------------------------------------------------------------------
+//    $Id$
+//    Version: $Name$
+//
+//    Copyright (C) 2008, 2011 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//-----------------------------------------------------------------------------
+
+// test ThreadLocalStorage::operator T&
+
+#include "../tests.h"
+#include <iomanip>
+#include <fstream>
+
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/thread_local_storage.h>
+
+
+struct X
+{
+    Threads::ThreadLocalStorage<int> tls_data;
+
+    X ()
+		    :
+		    tls_data (42)
+      {}
+
+    int f ()
+      {
+					 // access TLS data and have it
+					 // converted to the right data type
+					 // without the need to call
+					 // tls_data.get()
+	return tls_data;
+      }
+};
+
+
+void test ()
+{
+  X x;
+  Threads::Thread<int> t;
+  t = Threads::new_thread (&X::f, x);
+
+  Assert (t.return_value() == 42,
+	  ExcInternalError());
+}
+
+
+
+
+int main()
+{
+  std::ofstream logfile("thread_local_storage_03/output");
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test ();
+  deallog << "OK" << std::endl;
+}
diff --git a/tests/base/thread_local_storage_03/cmp/generic b/tests/base/thread_local_storage_03/cmp/generic
new file mode 100644
index 0000000000..0fd8fc12f0
--- /dev/null
+++ b/tests/base/thread_local_storage_03/cmp/generic
@@ -0,0 +1,2 @@
+
+DEAL::OK
diff --git a/tests/base/thread_local_storage_04.cc b/tests/base/thread_local_storage_04.cc
new file mode 100644
index 0000000000..aa9b53d9d3
--- /dev/null
+++ b/tests/base/thread_local_storage_04.cc
@@ -0,0 +1,78 @@
+//-----------------------------------------------------------------------------
+//    $Id$
+//    Version: $Name$
+//
+//    Copyright (C) 2008, 2011 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//-----------------------------------------------------------------------------
+
+// test ThreadLocalStorage::operator= (const T&)
+
+#include "../tests.h"
+#include <iomanip>
+#include <fstream>
+
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/thread_local_storage.h>
+
+int counter = 10;
+
+struct X
+{
+    Threads::ThreadLocalStorage<int> tls_data;
+
+    X ()
+		    :
+		    tls_data (42)
+      {}
+
+    int f ()
+      {
+					 // use TLS::operator=
+	tls_data = counter++;
+					 // access TLS data and have it
+					 // converted to the right data type
+					 // without the need to call
+					 // tls_data.get()
+	return tls_data;
+      }
+};
+
+
+void test ()
+{
+  X x;
+  {
+    Threads::Thread<int> t;
+    t = Threads::new_thread (&X::f, x);
+    Assert (t.return_value() == 10,
+	    ExcInternalError());
+  }
+  {
+    Threads::Thread<int> t;
+    t = Threads::new_thread (&X::f, x);
+    Assert (t.return_value() == 11,
+	    ExcInternalError());
+  }
+
+  Assert (counter == 12, ExcInternalError());
+}
+
+
+
+
+int main()
+{
+  std::ofstream logfile("thread_local_storage_04/output");
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test ();
+  deallog << "OK" << std::endl;
+}
diff --git a/tests/base/thread_local_storage_04/cmp/generic b/tests/base/thread_local_storage_04/cmp/generic
new file mode 100644
index 0000000000..0fd8fc12f0
--- /dev/null
+++ b/tests/base/thread_local_storage_04/cmp/generic
@@ -0,0 +1,2 @@
+
+DEAL::OK
-- 
2.39.5