// Copyright (C) 2006 Douglas Gregor // 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 #include #include #include #include namespace boost { namespace mpi { #if defined(BOOST_MPI_HAS_MEMORY_ALLOCATION) template 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 { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { typedef allocator 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 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 struct rebind { typedef allocator 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 allocator(const allocator&) 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::const_pointer /*hint*/ = 0) { pointer result; BOOST_MPI_CHECK_RESULT(MPI_Alloc_mem, (static_cast(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::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 inline bool operator==(const allocator&, const allocator&) throw() { return true; } /** @brief Compare two allocators for inequality. * * Since MPI allocators have no state, all MPI allocators are equal. * * @returns @c false */ template inline bool operator!=(const allocator&, const allocator&) 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