| // 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 |