Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:46:54

0001 // Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.com>
0002 
0003 // Use, modification and distribution is subject to the Boost Software
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 /** @file allocator.hpp
0008  *
0009  *  This header provides an STL-compliant allocator that uses the
0010  *  MPI-2 memory allocation facilities.
0011  */
0012 #ifndef BOOST_MPI_ALLOCATOR_HPP
0013 #define BOOST_MPI_ALLOCATOR_HPP
0014 
0015 #include <boost/mpi/config.hpp>
0016 #include <boost/mpi/exception.hpp>
0017 #include <cstddef>
0018 #include <memory>
0019 #include <boost/limits.hpp>
0020 
0021 namespace boost { namespace mpi {
0022 
0023 #if defined(BOOST_MPI_HAS_MEMORY_ALLOCATION)
0024 template<typename T> class allocator;
0025 
0026 /** @brief Allocator specialization for @c void value types.
0027  *
0028  *  The @c void specialization of @c allocator is useful only for
0029  *  rebinding to another, different value type.
0030  */
0031 template<> 
0032 class BOOST_MPI_DECL allocator<void> 
0033 { 
0034 public: 
0035   typedef void* pointer; 
0036   typedef const void* const_pointer; 
0037   typedef void value_type; 
0038 
0039   template <class U> 
0040   struct rebind 
0041   { 
0042     typedef allocator<U> other; 
0043   }; 
0044 };
0045 
0046 /** @brief Standard Library-compliant allocator for the MPI-2 memory
0047  *  allocation routines.
0048  *
0049  *  This allocator provides a standard C++ interface to the @c
0050  *  MPI_Alloc_mem and @c MPI_Free_mem routines of MPI-2. It is
0051  *  intended to be used with the containers in the Standard Library
0052  *  (@c vector, in particular) in cases where the contents of the
0053  *  container will be directly transmitted via MPI. This allocator is
0054  *  also used internally by the library for character buffers that
0055  *  will be used in the transmission of data.
0056  *
0057  *  The @c allocator class template only provides MPI memory
0058  *  allocation when the underlying MPI implementation is either MPI-2
0059  *  compliant or is known to provide @c MPI_Alloc_mem and @c
0060  *  MPI_Free_mem as extensions. When the MPI memory allocation
0061  *  routines are not available, @c allocator is brought in directly
0062  *  from namespace @c std, so that standard allocators are used
0063  *  throughout. The macro @c BOOST_MPI_HAS_MEMORY_ALLOCATION will be
0064  *  defined when the MPI-2 memory allocation facilities are available.
0065  */
0066 template<typename T> 
0067 class BOOST_MPI_DECL allocator 
0068 {
0069 public:
0070   /// Holds the size of objects
0071   typedef std::size_t     size_type;
0072 
0073   /// Holds the number of elements between two pointers
0074   typedef std::ptrdiff_t  difference_type;
0075 
0076   /// A pointer to an object of type @c T
0077   typedef T*              pointer;
0078 
0079   /// A pointer to a constant object of type @c T
0080   typedef const T*        const_pointer;
0081 
0082   /// A reference to an object of type @c T
0083   typedef T&              reference;
0084 
0085   /// A reference to a constant object of type @c T
0086   typedef const T&        const_reference;
0087 
0088   /// The type of memory allocated by this allocator
0089   typedef T               value_type;
0090 
0091   /** @brief Retrieve the type of an allocator similar to this
0092    * allocator but for a different value type.
0093    */
0094   template <typename U> 
0095   struct rebind 
0096   { 
0097     typedef allocator<U> other; 
0098   };
0099 
0100   /** Default-construct an allocator. */
0101   allocator() throw() { }
0102 
0103   /** Copy-construct an allocator. */
0104   allocator(const allocator&) throw() { }
0105 
0106   /** 
0107    * Copy-construct an allocator from another allocator for a
0108    * different value type.
0109    */
0110   template <typename U> 
0111   allocator(const allocator<U>&) throw() { }
0112 
0113   /** Destroy an allocator. */
0114   ~allocator() throw() { }
0115 
0116   /** Returns the address of object @p x. */
0117   pointer address(reference x) const
0118   {
0119     return &x;
0120   }
0121 
0122   /** Returns the address of object @p x. */
0123   const_pointer address(const_reference x) const
0124   {
0125     return &x;
0126   }
0127 
0128   /** 
0129    *  Allocate enough memory for @p n elements of type @c T.
0130    *
0131    *  @param n The number of elements for which memory should be
0132    *  allocated.
0133    *
0134    *  @return a pointer to the newly-allocated memory
0135    */
0136   pointer allocate(size_type n, allocator<void>::const_pointer /*hint*/ = 0)
0137   {
0138     pointer result;
0139     BOOST_MPI_CHECK_RESULT(MPI_Alloc_mem,
0140                            (static_cast<MPI_Aint>(n * sizeof(T)), 
0141                             MPI_INFO_NULL, 
0142                             &result));
0143     return result;
0144   }
0145 
0146   /**
0147    *  Deallocate memory referred to by the pointer @c p.
0148    *
0149    *  @param p The pointer whose memory should be deallocated. This
0150    *  pointer shall have been returned from the @c allocate() function
0151    *  and not have already been freed.
0152    */
0153   void deallocate(pointer p, size_type /*n*/)
0154   {
0155     BOOST_MPI_CHECK_RESULT(MPI_Free_mem, (p));
0156   }
0157 
0158   /** 
0159    * Returns the maximum number of elements that can be allocated
0160    * with @c allocate().
0161    */
0162   size_type max_size() const throw()
0163   {
0164     return (std::numeric_limits<std::size_t>::max)() / sizeof(T);
0165   }
0166 
0167   /** Construct a copy of @p val at the location referenced by @c p. */
0168   void construct(pointer p, const T& val)
0169   {
0170     new ((void *)p) T(val);
0171   }
0172 
0173   /** Destroy the object referenced by @c p. */
0174   void destroy(pointer p)
0175   {
0176     ((T*)p)->~T();
0177   }
0178 };
0179 
0180 /** @brief Compare two allocators for equality.
0181  *
0182  *  Since MPI allocators have no state, all MPI allocators are equal.
0183  *
0184  *  @returns @c true
0185  */
0186 template<typename T1, typename T2>
0187 inline bool operator==(const allocator<T1>&, const allocator<T2>&) throw()
0188 {
0189   return true;
0190 }
0191 
0192 /** @brief Compare two allocators for inequality.
0193  *
0194  *  Since MPI allocators have no state, all MPI allocators are equal.
0195  *
0196  *  @returns @c false
0197  */
0198 template<typename T1, typename T2>
0199 inline bool operator!=(const allocator<T1>&, const allocator<T2>&) throw()
0200 {
0201   return false;
0202 }
0203 #else
0204 // Bring in the default allocator from namespace std.
0205 using std::allocator;
0206 #endif
0207 
0208 } } /// end namespace boost::mpi
0209 
0210 #endif // BOOST_MPI_ALLOCATOR_HPP