$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: dgregor_at_[hidden]
Date: 2008-04-14 10:14:53
Author: dgregor
Date: 2008-04-14 10:14:53 EDT (Mon, 14 Apr 2008)
New Revision: 44414
URL: http://svn.boost.org/trac/boost/changeset/44414
Log:
Merge Boost.MPI datatype fixes from the trunk
Text files modified: 
   branches/release/boost/mpi/datatype.hpp                  |    29 +++++++++++++++++++----                 
   branches/release/boost/mpi/detail/mpi_datatype_cache.hpp |    45 +++++++++++++-----------------------    
   branches/release/libs/mpi/src/mpi_datatype_cache.cpp     |    49 ++++++++++++++++++++++++++++++++++++++- 
   3 files changed, 87 insertions(+), 36 deletions(-)
Modified: branches/release/boost/mpi/datatype.hpp
==============================================================================
--- branches/release/boost/mpi/datatype.hpp	(original)
+++ branches/release/boost/mpi/datatype.hpp	2008-04-14 10:14:53 EDT (Mon, 14 Apr 2008)
@@ -181,7 +181,7 @@
 template<typename T> MPI_Datatype get_mpi_datatype(const T& x)
 {
   BOOST_MPL_ASSERT((is_mpi_datatype<T>));
-  return detail::mpi_datatype_cache.datatype(x);
+  return detail::mpi_datatype_cache().datatype(x);
 }
 
 // Don't parse this part when we're generating Doxygen documentation.
@@ -252,15 +252,34 @@
 BOOST_MPI_DATATYPE(std::pair<BOOST_MPI_LIST2(int, int>), MPI_2INT, builtin);
 #undef BOOST_MPI_LIST2
 
-#if 0
-#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+// Define wchar_t specialization of is_mpi_datatype, if possible.
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && \
+  (defined(MPI_WCHAR) || (defined(MPI_VERSION) && MPI_VERSION >= 2))
 BOOST_MPI_DATATYPE(wchar_t, MPI_WCHAR, builtin);
 #endif
 
-#ifdef BOOST_HAS_LONG_LONG
+// Define long long or __int64 specialization of is_mpi_datatype, if possible.
+#if defined(BOOST_HAS_LONG_LONG) && \
+  (defined(MPI_LONG_LONG_INT) || (defined(MPI_VERSION) && MPI_VERSION >= 2))
 BOOST_MPI_DATATYPE(long long, MPI_LONG_LONG_INT, builtin);
-BOOST_MPI_DATATYPE(unsigned long long, MPI_UNSIGNED_LONG_LONG, builtin);
+#elif defined(BOOST_HAS_MS_INT64) && \
+  (defined(MPI_LONG_LONG_INT) || (defined(MPI_VERSION) && MPI_VERSION >= 2))
+BOOST_MPI_DATATYPE(__int64, MPI_LONG_LONG_INT, builtin); 
 #endif
+
+// Define unsigned long long or unsigned __int64 specialization of
+// is_mpi_datatype, if possible. We separate this from the check for
+// the (signed) long long/__int64 because some MPI implementations
+// (e.g., MPICH-MX) have MPI_LONG_LONG_INT but not
+// MPI_UNSIGNED_LONG_LONG.
+#if defined(BOOST_HAS_LONG_LONG) && \
+  (defined(MPI_UNSIGNED_LONG_LONG) \
+   || (defined(MPI_VERSION) && MPI_VERSION >= 2))
+BOOST_MPI_DATATYPE(unsigned long long, MPI_UNSIGNED_LONG_LONG, builtin);
+#elif defined(BOOST_HAS_MS_INT64) && \
+  (defined(MPI_UNSIGNED_LONG_LONG) \
+   || (defined(MPI_VERSION) && MPI_VERSION >= 2))
+BOOST_MPI_DATATYPE(unsigned __int64, MPI_UNSIGNED_LONG_LONG, builtin); 
 #endif
 
 #endif // Doxygen
Modified: branches/release/boost/mpi/detail/mpi_datatype_cache.hpp
==============================================================================
--- branches/release/boost/mpi/detail/mpi_datatype_cache.hpp	(original)
+++ branches/release/boost/mpi/detail/mpi_datatype_cache.hpp	2008-04-14 10:14:53 EDT (Mon, 14 Apr 2008)
@@ -15,7 +15,6 @@
 #include <boost/utility/enable_if.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/noncopyable.hpp>
-#include <map>
 #include <typeinfo>
 
 // The std::type_info::before function in Visual C++ 8.0 (and probably earlier)
@@ -47,21 +46,15 @@
 ///
 ///
 class BOOST_MPI_DECL mpi_datatype_map
- : private std::map<std::type_info const*,MPI_Datatype,type_info_compare>,
-   public boost::noncopyable
+ : public boost::noncopyable
 {
-public:
-  mpi_datatype_map()
-  {}
+  struct implementation;
 
-  ~mpi_datatype_map()
-  {
-    // do not free after call to MPI_FInalize
-    int finalized=0;
-    BOOST_MPI_CHECK_RESULT(MPI_Finalized,(&finalized));
-    if (!finalized)
-      free();
-  }
+  implementation *impl;
+
+public:
+  mpi_datatype_map();
+  ~mpi_datatype_map();
 
   template <class T>
   MPI_Datatype datatype(const T& x = T(), typename boost::enable_if<is_mpi_builtin_datatype<T> >::type* =0)
@@ -76,30 +69,24 @@
 
     // check whether the type already exists
     std::type_info const* t = &typeid(T);
-    const_iterator it = find(t);
-    if(it ==end())
-    {
+	MPI_Datatype datatype = get(t);
+	if (datatype == MPI_DATATYPE_NULL) {
       // need to create a type
       mpi_datatype_oarchive ar(x);
-      insert(std::make_pair(t,ar.get_mpi_datatype()));
-      it = find(t);
+	  datatype = ar.get_mpi_datatype();
+	  set(t, datatype);
     }
 
-  return it->second;
+    return datatype;
   }
 
 private:
-  // free all MPI data types
-  void free()
-  {
-    // ignore errors in the destructor
-    for (iterator it=begin(); it !=end(); ++it)
-          MPI_Type_free(&(it->second));
-  }
-
+  MPI_Datatype get(const std::type_info* t);
+  void set(const std::type_info* t, MPI_Datatype datatype);
 };
 
-extern mpi_datatype_map mpi_datatype_cache;
+/// Retrieve the MPI datatype cache
+mpi_datatype_map& mpi_datatype_cache();
 
 } } } // end namespace boost::mpi::detail
 
Modified: branches/release/libs/mpi/src/mpi_datatype_cache.cpp
==============================================================================
--- branches/release/libs/mpi/src/mpi_datatype_cache.cpp	(original)
+++ branches/release/libs/mpi/src/mpi_datatype_cache.cpp	2008-04-14 10:14:53 EDT (Mon, 14 Apr 2008)
@@ -8,9 +8,54 @@
 
 #include <boost/archive/impl/archive_pointer_oserializer.ipp>
 #include <boost/mpi/detail/mpi_datatype_cache.hpp>
+#include <map>
 
 namespace boost { namespace mpi { namespace detail {
 
-mpi_datatype_map mpi_datatype_cache;
-  
+  typedef std::map<std::type_info const*,MPI_Datatype,type_info_compare>
+	  stored_map_type;
+
+  struct mpi_datatype_map::implementation
+  {
+	stored_map_type map;
+  };
+
+  mpi_datatype_map::mpi_datatype_map()
+  {
+	  impl = new implementation();
+  }
+
+  mpi_datatype_map::~mpi_datatype_map()
+  {
+    // do not free after call to MPI_FInalize
+    int finalized=0;
+    BOOST_MPI_CHECK_RESULT(MPI_Finalized,(&finalized));
+	if (!finalized) {
+	  // ignore errors in the destructor
+	  for (stored_map_type::iterator it=impl->map.begin(); it != impl->map.end(); ++it) {
+ 	    MPI_Type_free(&(it->second));
+	  }
+	}
+	delete impl;
+  }
+
+  MPI_Datatype mpi_datatype_map::get(const std::type_info* t)
+  {
+	  stored_map_type::iterator pos = impl->map.find(t);
+	  if (pos != impl->map.end())
+		  return pos->second;
+	  else
+		  return MPI_DATATYPE_NULL;
+  }
+
+  void mpi_datatype_map::set(const std::type_info* t, MPI_Datatype datatype)
+  {
+	  impl->map[t] = datatype;
+  }
+
+  mpi_datatype_map& mpi_datatype_cache()
+  {
+	static mpi_datatype_map cache;
+	return cache;
+  }
 } } }