BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_stdtestallocator.h
Go to the documentation of this file.
1/// @file bslma_stdtestallocator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_stdtestallocator.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_STDTESTALLOCATOR
9#define INCLUDED_BSLMA_STDTESTALLOCATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_stdtestallocator bslma_stdtestallocator
15/// @brief Provide stl-compatible, `bslma`-style allocator to track usage.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_stdtestallocator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_stdtestallocator-purpose"> Purpose</a>
25/// * <a href="#bslma_stdtestallocator-classes"> Classes </a>
26/// * <a href="#bslma_stdtestallocator-macros"> Macros </a>
27/// * <a href="#bslma_stdtestallocator-description"> Description </a>
28///
29/// # Purpose {#bslma_stdtestallocator-purpose}
30/// Provide stl-compatible, `bslma`-style allocator to track usage.
31///
32/// # Classes {#bslma_stdtestallocator-classes}
33///
34/// - bslma::StdTestAllocator: instrumented `bslma-style` stl allocator template
35///
36/// # Macros {#bslma_stdtestallocator-macros}
37///
38///
39/// @see TBD
40///
41/// # Description {#bslma_stdtestallocator-description}
42/// TBD
43/// @}
44/** @} */
45/** @} */
46
47/** @addtogroup bsl
48 * @{
49 */
50/** @addtogroup bslma
51 * @{
52 */
53/** @addtogroup bslma_stdtestallocator
54 * @{
55 */
56
57#include <bslscm_version.h>
58
62#include <bslma_testallocator.h>
63#include <bslma_default.h>
64
68#include <bslmf_issame.h>
70
71
72namespace bslma {
73
74 // ======================
75 // class StdTestAllocator
76 // ======================
77
78/// An STL-compatible test allocator that forwards allocation calls to an
79/// underlying mechanism object of a type derived from
80/// `bslma::TestAllocator`. This class template adheres to the allocator
81/// requirements defined in section 20.1.5 [lib.allocator.requirements] of
82/// the C++ standard and may be used to instantiate any [container] class
83/// template that follows the STL allocator protocol. The allocation
84/// mechanism is chosen at run-time, giving the programmer run-time control
85/// over how a container allocates and frees memory.
86///
87/// See @ref bslma_stdtestallocator
88template <class TYPE>
90
91 // DATA
92 TestAllocator *d_mechanism;
93
94 public:
95 // TRAITS
103 // Declare nested type traits for this class.
104
105 // PUBLIC TYPES
106 typedef std::size_t size_type;
107 typedef std::ptrdiff_t difference_type;
108 typedef TYPE *pointer;
109 typedef const TYPE *const_pointer;
111 void,
112 TYPE&>::type reference;
114 void,
115 const TYPE&>::type const_reference;
116 // typedef TYPE& reference;
117 // typedef const TYPE& const_reference;
118 typedef TYPE value_type;
119
120 /// This nested `struct` template, parameterized by `ANY_TYPE`, provides
121 /// a namespace for an `other` type alias, which is a `StdTestAllocator`
122 /// type following the same template as this one but that allocates
123 /// elements of `ANY_TYPE`. Note that this `StdTestAllocator` type is
124 /// convertible to and from `other` for any type, including `void`.
125 template <class ANY_TYPE>
126 struct rebind {
127
129 };
130
131 // CREATORS
132
133 /// TBD: fix comment to mention that the default allocator has to be
134 /// a test allocator.
135 /// Create a proxy object which will forward allocation calls to the
136 /// object pointed to by `bslma::Default::defaultAllocator()`.
137 /// Postcondition:
138 /// @code
139 /// this->mechanism() == bslma::Default::defaultAllocator();
140 /// @endcode
142
143 /// TBD: fix comment to mention that `mechanism` has to be a test
144 /// allocator.
145 /// Convert a `bslma::Allocator` pointer to an test allocator object
146 /// which forwards allocation calls to the object pointed to by the
147 /// specified `mechanism`. If `mechanism` is 0, then the currently
148 /// installed default allocator is used instead. Postcondition:
149 /// `0 == mechanism || this->mechanism() == mechanism`.
151
152 /// Create a proxy object using the same mechanism as the specified
153 /// `original`. Postcondition: `this->mechanism() == rhs.mechanism()`.
154 StdTestAllocator(const StdTestAllocator& original);
155
156 /// Create a proxy object sharing the same mechanism object as the
157 /// specified `rhs`. The newly constructed test allocator will compare
158 /// equal to `rhs`, even though they are instantiated on different
159 /// types. Postcondition: `this->mechanism() == rhs.mechanism()`.
160 template <class ANY_TYPE>
162
164 // Destroy this object. Note that this does not delete the object
165 // pointed to by 'mechanism()'. Also note that this method's
166 // definition is compiler generated.
167
169 // Assign to this object the value of the specified 'rhs'.
170 // Postcondition: 'this->mechanism() == rhs->mechanism()'. Note that
171 // this does not delete the object pointed to by the previous value of
172 // 'mechanism()'. Also note that this method's definition is compiler
173 // generated.
174
175 // MANIPULATORS
176
177 /// Allocate enough (properly aligned) space for the specified `n`
178 /// objects of (template parameter) `TYPE` by calling `allocate` on the
179 /// mechanism object. The optionally specified `hint` argument is
180 /// ignored by this test allocator type. The behavior is undefined
181 /// unless `n <= max_size()`.
182 pointer allocate(size_type n, const void *hint = 0);
183
184 /// Return memory previously allocated with `allocate` to the underlying
185 /// mechanism object by calling `deallocate` on the mechanism object
186 /// with the specified `p`. The optionally specified `n` argument is
187 /// ignored by this test allocator type.
188 void deallocate(pointer p, size_type n = 1);
189
190 /// Copy-construct an object of (template parameter) `TYPE` from the
191 /// specified `val` at the memory address specified by `p`. Do not
192 /// directly allocate memory. The behavior is undefined unless `p` is
193 /// not properly aligned for objects of the given `TYPE`.
194 template <class ELEMENT_TYPE>
195 void construct(ELEMENT_TYPE *address, const TYPE& val);
196
197 /// Call the `TYPE` destructor for the object pointed to by the
198 /// specified `p`. Do not directly deallocate any memory.
199 template <class ELEMENT_TYPE>
200 void destroy(ELEMENT_TYPE *address);
201
202 // ACCESSORS
203
204 /// Return the address of the object referred to by the specified `x`,
205 /// even if the (template parameter) `TYPE` overloads the unary
206 /// `operator&`.
207 pointer address(reference x) const;
208
209 /// Return the address of the object referred to by the specified `x`,
210 /// even if the (template parameter) `TYPE` overloads the unary
211 /// `operator&`.
213
214 /// Return the maximum number of elements of (template parameter) `TYPE`
215 /// that can be allocated using this test allocator. Note that there is
216 /// no guarantee that attempts at allocating fewer elements than the
217 /// value returned by @ref max_size will not throw.
218 size_type max_size() const;
219
220 /// Return a pointer to the mechanism object to which this proxy
221 /// forwards allocation and deallocation calls.
222 TestAllocator *mechanism() const;
223};
224
225// FREE OPERATORS
226
227/// Return `true` if the specified `lhs` and `rhs` are proxies for the same
228/// `bslma::TestAllocator` object. This is a practical implementation of
229/// the STL requirement that two allocators compare equal if and only if
230/// memory allocated from one can be deallocated from the other. Note that
231/// the two allocators need not be instantiated on the same type in order to
232/// compare equal.
233template <class T1, class T2>
234inline
235bool operator==(const StdTestAllocator<T1>& lhs,
236 const StdTestAllocator<T2>& rhs);
237
238/// Return `true` unless the specified `lhs` and `rhs` are proxies for the
239/// same `bslma::TestAllocator` object, in which case return `false`. This
240/// is a practical implementation of the STL requirement that two allocators
241/// compare equal if and only if memory allocated from one can be
242/// deallocated from the other. Note that the two allocators need not be
243/// instantiated on the same type in order to compare equal.
244template <class T1, class T2>
245inline
246bool operator!=(const StdTestAllocator<T1>& lhs,
247 const StdTestAllocator<T2>& rhs);
248
249/// Return `true` if the specified `lhs` is a proxy for the specified `rhs`,
250/// and `false` otherwise.
251template <class TYPE>
252inline
253bool operator==(const StdTestAllocator<TYPE>& lhs,
254 const TestAllocator *rhs);
255
256/// Return `true` unless the specified `lhs` is a proxy for the specified
257/// `rhs`, in which case return `false`.
258template <class TYPE>
259inline
260bool operator!=(const StdTestAllocator<TYPE>& lhs,
261 const TestAllocator *rhs);
262
263/// Return `true` if the specified `rhs` is a proxy for the specified `lhs`,
264/// and `false` otherwise.
265template <class TYPE>
266inline
267bool operator==(const TestAllocator *lhs,
268 const StdTestAllocator<TYPE>& rhs);
269
270/// Return `true` unless the specified `rhs` is a proxy for the specified
271/// `lhs`, in which case return `false`.
272template <class TYPE>
273inline
274bool operator!=(const TestAllocator *lhs,
275 const StdTestAllocator<TYPE>& rhs);
276
277
278// ============================================================================
279// INLINE FUNCTION DEFINITIONS
280// ============================================================================
281
282 // ----------------------
283 // class StdTestAllocator
284 // ----------------------
285
286// LOW-LEVEL ACCESSORS
287template <class TYPE>
288inline
290{
291 return d_mechanism;
292}
293
294// CREATORS
295template <class TYPE>
296inline
298: d_mechanism(dynamic_cast<TestAllocator *>(Default::defaultAllocator()))
299{
300 BSLS_ASSERT_SAFE(d_mechanism);
301}
302
303template <class TYPE>
304inline
306: d_mechanism(dynamic_cast<TestAllocator *>(Default::allocator(mechanism)))
307{
308 BSLS_ASSERT_SAFE(d_mechanism);
309}
310
311template <class TYPE>
312inline
314: d_mechanism(original.mechanism())
315{
316 BSLS_ASSERT_SAFE(d_mechanism);
317}
318
319template <class TYPE>
320template <class ANY_TYPE>
321inline
323: d_mechanism(rhs.mechanism())
324{
325 BSLS_ASSERT_SAFE(d_mechanism);
326}
327
328// MANIPULATORS
329template <class TYPE>
330inline
333 const void *hint)
334{
335 BSLS_ASSERT_SAFE(n <= this->max_size());
336
337 (void) hint; // suppress unused parameter warning
338 return static_cast<pointer>(d_mechanism->allocate(n * sizeof(TYPE)));
339}
340
341template <class TYPE>
342inline
345{
346 (void) n; // suppress unused parameter warning
347 d_mechanism->deallocate(p);
348}
349
350template <class TYPE>
351template <class ELEMENT_TYPE>
352inline
353void StdTestAllocator<TYPE>::construct(ELEMENT_TYPE *address, const TYPE& val)
354{
355 new (static_cast<void*>(address)) ELEMENT_TYPE(val);
356}
357
358template <class TYPE>
359template <class ELEMENT_TYPE>
360inline
361void StdTestAllocator<TYPE>::destroy(ELEMENT_TYPE *address)
362{
363 DestructionUtil::destroy(address);
364}
365
366// ACCESSORS
367template <class TYPE>
368inline
374
375template <class TYPE>
376inline
378StdTestAllocator<TYPE>::address(reference x) const
379{
380 return BSLS_UTIL_ADDRESSOF(x);
381}
382
383template <class TYPE>
384inline
387{
388 // Return the largest value, 'v', such that 'v * sizeof(T)' fits in a
389 // 'size_type'.
390
391 // We will calculate MAX_NUM_BYTES based on our knowledge that
392 // 'bslma::Allocator::size_type' is just an alias for 'std::size_t'. First
393 // demonstrate that is true:
394
396
397 static const std::size_t MAX_NUM_BYTES = ~std::size_t(0);
398 static const std::size_t MAX_NUM_ELEMENTS = MAX_NUM_BYTES / sizeof(TYPE);
399
400 return MAX_NUM_ELEMENTS;
401}
402
403// FREE OPERATORS
404template <class T1, class T2>
405inline
406bool operator==(const StdTestAllocator<T1>& lhs,
407 const StdTestAllocator<T2>& rhs)
408{
409 return lhs.mechanism() == rhs.mechanism();
410}
411
412template <class T1, class T2>
413inline
414bool operator!=(const StdTestAllocator<T1>& lhs,
415 const StdTestAllocator<T2>& rhs)
416{
417 return ! (lhs == rhs);
418}
419
420template <class TYPE>
421inline
422bool operator==(const StdTestAllocator<TYPE>& lhs,
423 const TestAllocator *rhs)
424{
425 return lhs.mechanism() == rhs;
426}
427
428template <class TYPE>
429inline
430bool operator!=(const StdTestAllocator<TYPE>& lhs,
431 const TestAllocator *rhs)
432{
433 return ! (lhs == rhs);
434}
435
436template <class TYPE>
437inline
438bool operator==(const TestAllocator *lhs,
439 const StdTestAllocator<TYPE>& rhs)
440{
441 return lhs == rhs.mechanism();
442}
443
444template <class TYPE>
445inline
446bool operator!=(const TestAllocator *lhs,
447 const StdTestAllocator<TYPE>& rhs)
448{
449 return ! (lhs == rhs);
450}
451
452} // close package namespace
453
454
455#endif
456
457// ----------------------------------------------------------------------------
458// Copyright 2013 Bloomberg Finance L.P.
459//
460// Licensed under the Apache License, Version 2.0 (the "License");
461// you may not use this file except in compliance with the License.
462// You may obtain a copy of the License at
463//
464// http://www.apache.org/licenses/LICENSE-2.0
465//
466// Unless required by applicable law or agreed to in writing, software
467// distributed under the License is distributed on an "AS IS" BASIS,
468// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
469// See the License for the specific language governing permissions and
470// limitations under the License.
471// ----------------------------- END-OF-FILE ----------------------------------
472
473/** @} */
474/** @} */
475/** @} */
Definition bslma_allocator.h:457
Definition bslma_stdtestallocator.h:89
std::size_t size_type
Definition bslma_stdtestallocator.h:106
StdTestAllocator()
Definition bslma_stdtestallocator.h:297
BSLMF_NESTED_TRAIT_DECLARATION(StdTestAllocator, bslmf::IsBitwiseEqualityComparable)
void construct(ELEMENT_TYPE *address, const TYPE &val)
Definition bslma_stdtestallocator.h:353
pointer address(reference x) const
Definition bslma_stdtestallocator.h:370
bsl::conditional< bsl::is_void< TYPE >::value, void, TYPE & >::type reference
Definition bslma_stdtestallocator.h:112
BSLMF_NESTED_TRAIT_DECLARATION(StdTestAllocator, bslmf::IsBitwiseMoveable)
TestAllocator * mechanism() const
Definition bslma_stdtestallocator.h:289
bsl::conditional< bsl::is_void< TYPE >::value, void, constTYPE & >::type const_reference
Definition bslma_stdtestallocator.h:115
BSLMF_NESTED_TRAIT_DECLARATION(StdTestAllocator, bslmf::IsBitwiseCopyable)
pointer allocate(size_type n, const void *hint=0)
Definition bslma_stdtestallocator.h:332
void deallocate(pointer p, size_type n=1)
Definition bslma_stdtestallocator.h:343
const TYPE * const_pointer
Definition bslma_stdtestallocator.h:109
const_pointer address(const_reference x) const
void destroy(ELEMENT_TYPE *address)
Definition bslma_stdtestallocator.h:361
TYPE value_type
Definition bslma_stdtestallocator.h:118
StdTestAllocator & operator=(const StdTestAllocator &rhs)
std::ptrdiff_t difference_type
Definition bslma_stdtestallocator.h:107
size_type max_size() const
Definition bslma_stdtestallocator.h:386
TYPE * pointer
Definition bslma_stdtestallocator.h:108
BSLMF_NESTED_TRAIT_DECLARATION(StdTestAllocator, bslma::IsStdAllocator)
Definition bslma_testallocator.h:384
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
Definition balxml_encoderoptions.h:68
Definition bdldfp_decimal.h:5188
Definition bslmf_conditional.h:120
Definition bslmf_integralconstant.h:244
Definition bslmf_issame.h:146
Definition bslma_default.h:740
Definition bslma_isstdallocator.h:201
Definition bslma_stdtestallocator.h:126
StdTestAllocator< ANY_TYPE > other
Definition bslma_stdtestallocator.h:128
Definition bslmf_isbitwisecopyable.h:298
Definition bslmf_isbitwiseequalitycomparable.h:499
Definition bslmf_isbitwisemoveable.h:718