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