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
							 |