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