allocator.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com>
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. /** @file allocator.hpp
  6. *
  7. * This header provides an STL-compliant allocator that uses the
  8. * MPI-2 memory allocation facilities.
  9. */
  10. #ifndef BOOST_MPI_ALLOCATOR_HPP
  11. #define BOOST_MPI_ALLOCATOR_HPP
  12. #include <boost/mpi/config.hpp>
  13. #include <boost/mpi/exception.hpp>
  14. #include <cstddef>
  15. #include <memory>
  16. #include <boost/limits.hpp>
  17. namespace boost { namespace mpi {
  18. #if defined(BOOST_MPI_HAS_MEMORY_ALLOCATION)
  19. template<typename T> class allocator;
  20. /** @brief Allocator specialization for @c void value types.
  21. *
  22. * The @c void specialization of @c allocator is useful only for
  23. * rebinding to another, different value type.
  24. */
  25. template<>
  26. class BOOST_MPI_DECL allocator<void>
  27. {
  28. public:
  29. typedef void* pointer;
  30. typedef const void* const_pointer;
  31. typedef void value_type;
  32. template <class U>
  33. struct rebind
  34. {
  35. typedef allocator<U> other;
  36. };
  37. };
  38. /** @brief Standard Library-compliant allocator for the MPI-2 memory
  39. * allocation routines.
  40. *
  41. * This allocator provides a standard C++ interface to the @c
  42. * MPI_Alloc_mem and @c MPI_Free_mem routines of MPI-2. It is
  43. * intended to be used with the containers in the Standard Library
  44. * (@c vector, in particular) in cases where the contents of the
  45. * container will be directly transmitted via MPI. This allocator is
  46. * also used internally by the library for character buffers that
  47. * will be used in the transmission of data.
  48. *
  49. * The @c allocator class template only provides MPI memory
  50. * allocation when the underlying MPI implementation is either MPI-2
  51. * compliant or is known to provide @c MPI_Alloc_mem and @c
  52. * MPI_Free_mem as extensions. When the MPI memory allocation
  53. * routines are not available, @c allocator is brought in directly
  54. * from namespace @c std, so that standard allocators are used
  55. * throughout. The macro @c BOOST_MPI_HAS_MEMORY_ALLOCATION will be
  56. * defined when the MPI-2 memory allocation facilities are available.
  57. */
  58. template<typename T>
  59. class BOOST_MPI_DECL allocator
  60. {
  61. public:
  62. /// Holds the size of objects
  63. typedef std::size_t size_type;
  64. /// Holds the number of elements between two pointers
  65. typedef std::ptrdiff_t difference_type;
  66. /// A pointer to an object of type @c T
  67. typedef T* pointer;
  68. /// A pointer to a constant object of type @c T
  69. typedef const T* const_pointer;
  70. /// A reference to an object of type @c T
  71. typedef T& reference;
  72. /// A reference to a constant object of type @c T
  73. typedef const T& const_reference;
  74. /// The type of memory allocated by this allocator
  75. typedef T value_type;
  76. /** @brief Retrieve the type of an allocator similar to this
  77. * allocator but for a different value type.
  78. */
  79. template <typename U>
  80. struct rebind
  81. {
  82. typedef allocator<U> other;
  83. };
  84. /** Default-construct an allocator. */
  85. allocator() throw() { }
  86. /** Copy-construct an allocator. */
  87. allocator(const allocator&) throw() { }
  88. /**
  89. * Copy-construct an allocator from another allocator for a
  90. * different value type.
  91. */
  92. template <typename U>
  93. allocator(const allocator<U>&) throw() { }
  94. /** Destroy an allocator. */
  95. ~allocator() throw() { }
  96. /** Returns the address of object @p x. */
  97. pointer address(reference x) const
  98. {
  99. return &x;
  100. }
  101. /** Returns the address of object @p x. */
  102. const_pointer address(const_reference x) const
  103. {
  104. return &x;
  105. }
  106. /**
  107. * Allocate enough memory for @p n elements of type @c T.
  108. *
  109. * @param n The number of elements for which memory should be
  110. * allocated.
  111. *
  112. * @return a pointer to the newly-allocated memory
  113. */
  114. pointer allocate(size_type n, allocator<void>::const_pointer /*hint*/ = 0)
  115. {
  116. pointer result;
  117. BOOST_MPI_CHECK_RESULT(MPI_Alloc_mem,
  118. (static_cast<MPI_Aint>(n * sizeof(T)),
  119. MPI_INFO_NULL,
  120. &result));
  121. return result;
  122. }
  123. /**
  124. * Deallocate memory referred to by the pointer @c p.
  125. *
  126. * @param p The pointer whose memory should be deallocated. This
  127. * pointer shall have been returned from the @c allocate() function
  128. * and not have already been freed.
  129. */
  130. void deallocate(pointer p, size_type /*n*/)
  131. {
  132. BOOST_MPI_CHECK_RESULT(MPI_Free_mem, (p));
  133. }
  134. /**
  135. * Returns the maximum number of elements that can be allocated
  136. * with @c allocate().
  137. */
  138. size_type max_size() const throw()
  139. {
  140. return (std::numeric_limits<std::size_t>::max)() / sizeof(T);
  141. }
  142. /** Construct a copy of @p val at the location referenced by @c p. */
  143. void construct(pointer p, const T& val)
  144. {
  145. new ((void *)p) T(val);
  146. }
  147. /** Destroy the object referenced by @c p. */
  148. void destroy(pointer p)
  149. {
  150. ((T*)p)->~T();
  151. }
  152. };
  153. /** @brief Compare two allocators for equality.
  154. *
  155. * Since MPI allocators have no state, all MPI allocators are equal.
  156. *
  157. * @returns @c true
  158. */
  159. template<typename T1, typename T2>
  160. inline bool operator==(const allocator<T1>&, const allocator<T2>&) throw()
  161. {
  162. return true;
  163. }
  164. /** @brief Compare two allocators for inequality.
  165. *
  166. * Since MPI allocators have no state, all MPI allocators are equal.
  167. *
  168. * @returns @c false
  169. */
  170. template<typename T1, typename T2>
  171. inline bool operator!=(const allocator<T1>&, const allocator<T2>&) throw()
  172. {
  173. return false;
  174. }
  175. #else
  176. // Bring in the default allocator from namespace std.
  177. using std::allocator;
  178. #endif
  179. } } /// end namespace boost::mpi
  180. #endif // BOOST_MPI_ALLOCATOR_HPP