211 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
// Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com>
 | 
						|
 | 
						|
// Use, modification and distribution is subject to the Boost Software
 | 
						|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | 
						|
// http://www.boost.org/LICENSE_1_0.txt)
 | 
						|
 | 
						|
/** @file allocator.hpp
 | 
						|
 *
 | 
						|
 *  This header provides an STL-compliant allocator that uses the
 | 
						|
 *  MPI-2 memory allocation facilities.
 | 
						|
 */
 | 
						|
#ifndef BOOST_MPI_ALLOCATOR_HPP
 | 
						|
#define BOOST_MPI_ALLOCATOR_HPP
 | 
						|
 | 
						|
#include <boost/mpi/config.hpp>
 | 
						|
#include <boost/mpi/exception.hpp>
 | 
						|
#include <cstddef>
 | 
						|
#include <memory>
 | 
						|
#include <boost/limits.hpp>
 | 
						|
 | 
						|
namespace boost { namespace mpi {
 | 
						|
 | 
						|
#if defined(BOOST_MPI_HAS_MEMORY_ALLOCATION)
 | 
						|
template<typename T> class allocator;
 | 
						|
 | 
						|
/** @brief Allocator specialization for @c void value types.
 | 
						|
 *
 | 
						|
 *  The @c void specialization of @c allocator is useful only for
 | 
						|
 *  rebinding to another, different value type.
 | 
						|
 */
 | 
						|
template<> 
 | 
						|
class BOOST_MPI_DECL allocator<void> 
 | 
						|
{ 
 | 
						|
public: 
 | 
						|
  typedef void* pointer; 
 | 
						|
  typedef const void* const_pointer; 
 | 
						|
  typedef void value_type; 
 | 
						|
 | 
						|
  template <class U> 
 | 
						|
  struct rebind 
 | 
						|
  { 
 | 
						|
    typedef allocator<U> other; 
 | 
						|
  }; 
 | 
						|
};
 | 
						|
 | 
						|
/** @brief Standard Library-compliant allocator for the MPI-2 memory
 | 
						|
 *  allocation routines.
 | 
						|
 *
 | 
						|
 *  This allocator provides a standard C++ interface to the @c
 | 
						|
 *  MPI_Alloc_mem and @c MPI_Free_mem routines of MPI-2. It is
 | 
						|
 *  intended to be used with the containers in the Standard Library
 | 
						|
 *  (@c vector, in particular) in cases where the contents of the
 | 
						|
 *  container will be directly transmitted via MPI. This allocator is
 | 
						|
 *  also used internally by the library for character buffers that
 | 
						|
 *  will be used in the transmission of data.
 | 
						|
 *
 | 
						|
 *  The @c allocator class template only provides MPI memory
 | 
						|
 *  allocation when the underlying MPI implementation is either MPI-2
 | 
						|
 *  compliant or is known to provide @c MPI_Alloc_mem and @c
 | 
						|
 *  MPI_Free_mem as extensions. When the MPI memory allocation
 | 
						|
 *  routines are not available, @c allocator is brought in directly
 | 
						|
 *  from namespace @c std, so that standard allocators are used
 | 
						|
 *  throughout. The macro @c BOOST_MPI_HAS_MEMORY_ALLOCATION will be
 | 
						|
 *  defined when the MPI-2 memory allocation facilities are available.
 | 
						|
 */
 | 
						|
template<typename T> 
 | 
						|
class BOOST_MPI_DECL allocator 
 | 
						|
{
 | 
						|
public:
 | 
						|
  /// Holds the size of objects
 | 
						|
  typedef std::size_t     size_type;
 | 
						|
 | 
						|
  /// Holds the number of elements between two pointers
 | 
						|
  typedef std::ptrdiff_t  difference_type;
 | 
						|
 | 
						|
  /// A pointer to an object of type @c T
 | 
						|
  typedef T*              pointer;
 | 
						|
 | 
						|
  /// A pointer to a constant object of type @c T
 | 
						|
  typedef const T*        const_pointer;
 | 
						|
 | 
						|
  /// A reference to an object of type @c T
 | 
						|
  typedef T&              reference;
 | 
						|
 | 
						|
  /// A reference to a constant object of type @c T
 | 
						|
  typedef const T&        const_reference;
 | 
						|
 | 
						|
  /// The type of memory allocated by this allocator
 | 
						|
  typedef T               value_type;
 | 
						|
 | 
						|
  /** @brief Retrieve the type of an allocator similar to this
 | 
						|
   * allocator but for a different value type.
 | 
						|
   */
 | 
						|
  template <typename U> 
 | 
						|
  struct rebind 
 | 
						|
  { 
 | 
						|
    typedef allocator<U> other; 
 | 
						|
  };
 | 
						|
 | 
						|
  /** Default-construct an allocator. */
 | 
						|
  allocator() throw() { }
 | 
						|
 | 
						|
  /** Copy-construct an allocator. */
 | 
						|
  allocator(const allocator&) throw() { }
 | 
						|
 | 
						|
  /** 
 | 
						|
   * Copy-construct an allocator from another allocator for a
 | 
						|
   * different value type.
 | 
						|
   */
 | 
						|
  template <typename U> 
 | 
						|
  allocator(const allocator<U>&) throw() { }
 | 
						|
 | 
						|
  /** Destroy an allocator. */
 | 
						|
  ~allocator() throw() { }
 | 
						|
 | 
						|
  /** Returns the address of object @p x. */
 | 
						|
  pointer address(reference x) const
 | 
						|
  {
 | 
						|
    return &x;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Returns the address of object @p x. */
 | 
						|
  const_pointer address(const_reference x) const
 | 
						|
  {
 | 
						|
    return &x;
 | 
						|
  }
 | 
						|
 | 
						|
  /** 
 | 
						|
   *  Allocate enough memory for @p n elements of type @c T.
 | 
						|
   *
 | 
						|
   *  @param n The number of elements for which memory should be
 | 
						|
   *  allocated.
 | 
						|
   *
 | 
						|
   *  @return a pointer to the newly-allocated memory
 | 
						|
   */
 | 
						|
  pointer allocate(size_type n, allocator<void>::const_pointer /*hint*/ = 0)
 | 
						|
  {
 | 
						|
    pointer result;
 | 
						|
    BOOST_MPI_CHECK_RESULT(MPI_Alloc_mem,
 | 
						|
                           (static_cast<MPI_Aint>(n * sizeof(T)), 
 | 
						|
                            MPI_INFO_NULL, 
 | 
						|
                            &result));
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   *  Deallocate memory referred to by the pointer @c p.
 | 
						|
   *
 | 
						|
   *  @param p The pointer whose memory should be deallocated. This
 | 
						|
   *  pointer shall have been returned from the @c allocate() function
 | 
						|
   *  and not have already been freed.
 | 
						|
   */
 | 
						|
  void deallocate(pointer p, size_type /*n*/)
 | 
						|
  {
 | 
						|
    BOOST_MPI_CHECK_RESULT(MPI_Free_mem, (p));
 | 
						|
  }
 | 
						|
 | 
						|
  /** 
 | 
						|
   * Returns the maximum number of elements that can be allocated
 | 
						|
   * with @c allocate().
 | 
						|
   */
 | 
						|
  size_type max_size() const throw()
 | 
						|
  {
 | 
						|
    return (std::numeric_limits<std::size_t>::max)() / sizeof(T);
 | 
						|
  }
 | 
						|
 | 
						|
  /** Construct a copy of @p val at the location referenced by @c p. */
 | 
						|
  void construct(pointer p, const T& val)
 | 
						|
  {
 | 
						|
    new ((void *)p) T(val);
 | 
						|
  }
 | 
						|
 | 
						|
  /** Destroy the object referenced by @c p. */
 | 
						|
  void destroy(pointer p)
 | 
						|
  {
 | 
						|
    ((T*)p)->~T();
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
/** @brief Compare two allocators for equality.
 | 
						|
 *
 | 
						|
 *  Since MPI allocators have no state, all MPI allocators are equal.
 | 
						|
 *
 | 
						|
 *  @returns @c true
 | 
						|
 */
 | 
						|
template<typename T1, typename T2>
 | 
						|
inline bool operator==(const allocator<T1>&, const allocator<T2>&) throw()
 | 
						|
{
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
/** @brief Compare two allocators for inequality.
 | 
						|
 *
 | 
						|
 *  Since MPI allocators have no state, all MPI allocators are equal.
 | 
						|
 *
 | 
						|
 *  @returns @c false
 | 
						|
 */
 | 
						|
template<typename T1, typename T2>
 | 
						|
inline bool operator!=(const allocator<T1>&, const allocator<T2>&) throw()
 | 
						|
{
 | 
						|
  return false;
 | 
						|
}
 | 
						|
#else
 | 
						|
// Bring in the default allocator from namespace std.
 | 
						|
using std::allocator;
 | 
						|
#endif
 | 
						|
 | 
						|
} } /// end namespace boost::mpi
 | 
						|
 | 
						|
#endif // BOOST_MPI_ALLOCATOR_HPP
 |