BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslma_allocatoradaptor.h
Go to the documentation of this file.
1/// @file bslma_allocatoradaptor.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslma_allocatoradaptor.h -*-C++-*-
8#ifndef INCLUDED_BSLMA_ALLOCATORADAPTOR
9#define INCLUDED_BSLMA_ALLOCATORADAPTOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslma_allocatoradaptor bslma_allocatoradaptor
15/// @brief Provide a polymorphic adaptor for STL-style allocators
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslma
19/// @{
20/// @addtogroup bslma_allocatoradaptor
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslma_allocatoradaptor-purpose"> Purpose</a>
25/// * <a href="#bslma_allocatoradaptor-classes"> Classes </a>
26/// * <a href="#bslma_allocatoradaptor-description"> Description </a>
27/// * <a href="#bslma_allocatoradaptor-usage"> Usage </a>
28/// * <a href="#bslma_allocatoradaptor-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#bslma_allocatoradaptor-purpose}
31/// Provide a polymorphic adaptor for STL-style allocators
32///
33/// # Classes {#bslma_allocatoradaptor-classes}
34///
35/// - bslma::AllocatorAdaptor<ALLOC>: polymorphic adaptor for STL allocators
36///
37/// # Description {#bslma_allocatoradaptor-description}
38/// Within the BDE libraries, the prefered way to handle memory
39/// allocation is through a pointer to the polymorphic base class,
40/// `bslma::Allocator`. The use of a run-time polymorphism for the allocator
41/// has numerous advantages over the compile-time polymorphism used by the STL
42/// components. However, there are times when client code may have an
43/// STL-style allocator available and needs to use it with a BDE component.
44///
45/// This component provides a class template, `AllocatorAdaptor` that wraps the
46/// STL-style allocator in an object of class derived from `bslma::Allocator`.
47/// A pointer to the object can thus be used with any component that uses
48/// BDE-style memory allocation.
49///
50/// ## Usage {#bslma_allocatoradaptor-usage}
51///
52///
53/// This section illustrates intended use of this component.
54///
55/// ### Example 1: Basic Usage {#bslma_allocatoradaptor-example-1-basic-usage}
56///
57///
58/// Let's start with a simple class, `my::FilePath`, which allocates storage
59/// using a `bslma::Allocator`:
60/// @code
61/// #include <bslma_allocator.h>
62/// #include <bslma_default.h>
63/// #include <bsls_nullptr.h>
64///
65/// #include <cstring>
66/// #include <cstdlib>
67///
68/// namespace my {
69///
70/// /// Store the path of a file or directory.
71/// class FilePath {
72/// bslma::Allocator *d_allocator;
73/// char *d_data;
74///
75/// public:
76/// FilePath(bslma::Allocator* basicAllocator = 0 /* nullptr */)
77/// : d_allocator(bslma::Default::allocator(basicAllocator))
78/// , d_data(0 /* nullptr */) { }
79///
80/// FilePath(const char* s, bslma::Allocator* basicAllocator = 0)
81/// : d_allocator(bslma::Default::allocator(basicAllocator))
82/// {
83/// d_data =
84/// static_cast<char*>(d_allocator->allocate(std::strlen(s) + 1));
85/// std::strcpy(d_data, s);
86/// }
87///
88/// bslma::Allocator *getAllocator() const { return d_allocator; }
89///
90/// //...
91/// };
92///
93/// } // close namespace my
94/// @endcode
95/// Next, assume that an STL-allocator exists that uses memory exactly the way
96/// you need:
97/// @code
98/// template <class TYPE>
99/// class MagicAllocator {
100/// bool d_useMalloc;
101/// public:
102/// typedef TYPE value_type;
103/// typedef TYPE *pointer;
104/// typedef const TYPE *const_pointer;
105/// typedef unsigned size_type;
106/// typedef int difference_type;
107///
108/// template <class U>
109/// struct rebind {
110/// typedef MagicAllocator<U> other;
111/// };
112///
113/// explicit MagicAllocator(bool useMalloc = false)
114/// : d_useMalloc(useMalloc) { }
115///
116/// template <class U>
117/// MagicAllocator(const MagicAllocator<U>& other)
118/// : d_useMalloc(other.getUseMalloc()) { }
119///
120/// value_type *allocate(std::size_t n, void* = 0 /* nullptr */) {
121/// if (d_useMalloc)
122/// return (value_type*) std::malloc(n * sizeof(value_type));
123/// else
124/// return (value_type*) ::operator new(n * sizeof(value_type));
125/// }
126///
127/// void deallocate(value_type *p, std::size_t) {
128/// if (d_useMalloc)
129/// std::free(p);
130/// else
131/// ::operator delete(p);
132/// }
133///
134/// static size_type max_size() { return UINT_MAX / sizeof(TYPE); }
135///
136/// void construct(pointer p, const TYPE& value)
137/// { new((void *)p) TYPE(value); }
138///
139/// void destroy(pointer p) { p->~TYPE(); }
140///
141/// int getUseMalloc() const { return d_useMalloc; }
142/// };
143///
144/// template <class T, class U>
145/// inline
146/// bool operator==(const MagicAllocator<T>& a, const MagicAllocator<U>& b)
147/// {
148/// return a.getUseMalloc() == b.getUseMalloc();
149/// }
150///
151/// template <class T, class U>
152/// inline
153/// bool operator!=(const MagicAllocator<T>& a, const MagicAllocator<U>& b)
154/// {
155/// return a.getUseMalloc() != b.getUseMalloc();
156/// }
157/// @endcode
158/// Now, if we want to create a `FilePath` using a `MagicAllocator`, we
159/// need to adapt the `MagicAllocator` to the `bslma::Allocator` protocol.
160/// This is where `bslma::AllocatorAdaptor` comes in:
161/// @code
162/// int main()
163/// {
164/// MagicAllocator<char> ma(true);
165/// bslma::AllocatorAdaptor<MagicAllocator<char> >::Type maa(ma);
166///
167/// my::FilePath usrbin("/usr/local/bin", &maa);
168///
169/// assert(&maa == usrbin.getAllocator());
170/// assert(ma == maa.adaptedAllocator());
171///
172/// return 0;
173/// }
174/// @endcode
175/// @}
176/** @} */
177/** @} */
178
179/** @addtogroup bsl
180 * @{
181 */
182/** @addtogroup bslma
183 * @{
184 */
185/** @addtogroup bslma_allocatoradaptor
186 * @{
187 */
188
189#include <bslscm_version.h>
190
191#include <bslma_allocator.h>
192
193#include <bslmf_assert.h>
194#include <bslmf_issame.h>
195
196#include <bsls_alignmentutil.h>
198#include <bsls_keyword.h>
199
200
201
202namespace bslma {
203
204 // ===================================
205 // class template AllocatorAdaptor_Imp
206 // ===================================
207
208/// Component-private class. Do not use. This class provides the actual
209/// interface and implementaiton for `AllocatorAdaptor`, which inherits
210/// from it. The indirection is necessary so that
211/// `AllocatorAdaptor<Alloc<T>>` and `AllocatorAdaptor<Alloc<U>>` produce
212/// only one instantiation of this template:
213/// `AllocatorAdaptor_imp<Alloc<char>>`.
214///
215/// See @ref bslma_allocatoradaptor
216template <class STL_ALLOC>
218
220
221 // PRIVATE TYPES
222 typedef bsls::AlignmentUtil::MaxAlignedType MaxAlignedType;
223
224 // PRIVATE DATA
225 typename STL_ALLOC::template rebind<MaxAlignedType>::other d_stlAllocator;
226
227 // NOT ASSIGNABLE
228 AllocatorAdaptor_Imp& operator=(const AllocatorAdaptor_Imp&); // = delete
229
230 public:
231 // TYPES
233 typedef STL_ALLOC StlAllocatorType;
234
235 // CREATORS
236
237 /// Construct a polymorphic wrapper around a default-constructed
238 /// STL-style allocator.
239 AllocatorAdaptor_Imp(); // = default
240
241 /// Construct a polymorphic wrapper around a copy of the specified
242 /// `stla` STL-style allocator.
244
245#if defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS)
246 /// Create an `AllocatorAdaptor_Imp` object that can allocate and
247 /// deallocate memory as if it were the specified `original` object.
248 AllocatorAdaptor_Imp(const AllocatorAdaptor_Imp& original) = default;
249#endif
250
251
252 /// Destroy this object and the STL-style allocator that it wraps.
254
255 // MANIPULATORS
256
257 /// Return a maximally-aligned block of memory no smaller than `size` bytes
258 /// allocated from the STL-style allocator that was supplied to this
259 /// object's constructor. Any exceptions thrown by the underlying
260 /// STL-style allocator are propagated out from this member.
262
263 /// Return the memory block at the specified `address` back to the
264 /// STL-allocator. If `address` is null, this funciton has no effect.
265 ///
266 /// \pre The behavior is undefined unless `address` was allocated using this
267 /// allocator object and has not already been deallocated.
269
270 // ACCESSORS
271
272 /// Return a copy of the STL allocator stored within this object.
273 STL_ALLOC adaptedAllocator() const;
274};
275
276 // ===============================
277 // class template AllocatorAdaptor
278 // ===============================
279
280#ifdef BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
281/// Polymorphic wrapper around an STL-style allocator.
282///
283/// \note Note that `AllocatorAdaptor<A>::Type` is the same type regardless of whether or not
284/// the compiler supports alias templates. It should be used, therefore,
285/// whenever the exact type of the adaptor is important.
286template <class STL_ALLOC>
287using AllocatorAdaptor =
289#else
290/// Polymorphic wrapper around an object of the specified `STL_ALLOC` STL-style
291/// allocator template parameter. A pointer to an object of this class can
292/// thus be used with any component that uses BDE-style memory allocation.
293///
294/// \note Note that `AllocatorAdaptor<A>::Type` is the same type regardless of
295/// whether or not the compiler supports alias templates. It should be used,
296/// therefore, whenever the exact type of the adaptor is important.
297template <class STL_ALLOC>
298class AllocatorAdaptor : public
299 AllocatorAdaptor_Imp<typename STL_ALLOC::template rebind<char>::other>
300{
301 typedef typename STL_ALLOC::template rebind<char>::other ReboundSTLAlloc;
302
303 // Not assignable
304 AllocatorAdaptor& operator=(const AllocatorAdaptor&); // = delete
305
306public:
307 // CREATORS
308
309 /// Constructs a polymorphic wrapper around a default-constructed
310 /// STL-style allocator.
311 AllocatorAdaptor(); // = default
312
313 /// Constructs a polymorphic wrapper around a copy of the specified 'stla'
314 /// STL-style allocator.
315 AllocatorAdaptor(const STL_ALLOC& stla);
316
318 ~AllocatorAdaptor() = default;
319};
320#endif // BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
321
322} // close package namespace
323
324// ===========================================================================
325// TEMPLATE IMPLEMENTATION
326// ===========================================================================
327
328 // -----------------------------------
329 // class template AllocatorAdaptor_Imp
330 // -----------------------------------
331
332// CREATORS
333template <class STL_ALLOC>
334inline
339
340template <class STL_ALLOC>
341inline
343 const StlAllocatorType& stla)
344 : d_stlAllocator(stla)
345{
346}
347
348template <class STL_ALLOC>
349inline
353
354// MANIPULATORS
355template <class STL_ALLOC>
357{
358 BSLMF_ASSERT(sizeof(size_type) <= sizeof(MaxAlignedType));
359
360 // Compute number of 'MaxAlignedType' objects needed to make up 'size'
361 // bytes plus an extra one to hold the size.
362 size_type n = 1 + (size+sizeof(MaxAlignedType)-1) / sizeof(MaxAlignedType);
363 MaxAlignedType* p = d_stlAllocator.allocate(n);
364 *reinterpret_cast<size_type*>(p) = n;
365 return ++p;
366}
367
368template <class STL_ALLOC>
370{
371 MaxAlignedType *p = static_cast<MaxAlignedType*>(address);
372
373 // Extract size from slot before 'p'
374 size_type n = *reinterpret_cast<size_type*>(--p);
375 d_stlAllocator.deallocate(p, n);
376}
377
378// ACCESSORS
379template <class STL_ALLOC>
381{
382 return d_stlAllocator;
383}
384
385#ifndef BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
386
387 // -------------------------------
388 // class template AllocatorAdaptor
389 // -------------------------------
390
391// CREATORS
392template <class STL_ALLOC>
393inline
397
398template <class STL_ALLOC>
399inline
401 : bslma::AllocatorAdaptor_Imp<ReboundSTLAlloc>(stla)
402{
403}
404#endif // ! BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
405
406
407
408
409#endif // ! defined(INCLUDED_BSLMA_ALLOCATORADAPTOR)
410
411// ----------------------------------------------------------------------------
412// Copyright 2013 Bloomberg Finance L.P.
413//
414// Licensed under the Apache License, Version 2.0 (the "License");
415// you may not use this file except in compliance with the License.
416// You may obtain a copy of the License at
417//
418// http://www.apache.org/licenses/LICENSE-2.0
419//
420// Unless required by applicable law or agreed to in writing, software
421// distributed under the License is distributed on an "AS IS" BASIS,
422// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
423// See the License for the specific language governing permissions and
424// limitations under the License.
425// ----------------------------- END-OF-FILE ----------------------------------
426
427/** @} */
428/** @} */
429/** @} */
Definition bslma_allocatoradaptor.h:217
STL_ALLOC StlAllocatorType
Definition bslma_allocatoradaptor.h:233
AllocatorAdaptor_Imp Type
Definition bslma_allocatoradaptor.h:232
Definition bslma_allocatoradaptor.h:300
AllocatorAdaptor(const AllocatorAdaptor &)=default
Definition bslma_allocator.h:545
std::size_t size_type
Definition bslma_allocator.h:593
STL_ALLOC adaptedAllocator() const
Return a copy of the STL allocator stored within this object.
Definition bslma_allocatoradaptor.h:380
AllocatorAdaptor_Imp()
Definition bslma_allocatoradaptor.h:335
AllocatorAdaptor_Imp(const StlAllocatorType &stla)
Definition bslma_allocatoradaptor.h:342
AllocatorAdaptor()
Definition bslma_allocatoradaptor.h:394
~AllocatorAdaptor_Imp() BSLS_KEYWORD_OVERRIDE
Destroy this object and the STL-style allocator that it wraps.
Definition bslma_allocatoradaptor.h:350
void deallocate(void *address) BSLS_KEYWORD_OVERRIDE
Definition bslma_allocatoradaptor.h:369
void * allocate(size_type size) BSLS_KEYWORD_OVERRIDE
Definition bslma_allocatoradaptor.h:356
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition baljsn_encoder_testtypes.h:76
Definition bslmf_issame.h:146
AlignmentToType< BSLS_MAX_ALIGNMENT >::Type MaxAlignedType
Definition bsls_alignmentutil.h:307