BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_allocator.h
Go to the documentation of this file.
1
/// @file bslstl_allocator.h
2
///
3
/// The content of this file has been pre-processed for Doxygen.
4
///
5
6
7
// bslstl_allocator.h -*-C++-*-
8
#ifndef INCLUDED_BSLSTL_ALLOCATOR
9
#define INCLUDED_BSLSTL_ALLOCATOR
10
11
#include <
bsls_ident.h
>
12
BSLS_IDENT
(
"$Id: $"
)
13
14
/// @defgroup bslstl_allocator bslstl_allocator
15
/// @brief Provide an STL-compatible proxy for `bslma::Allocator` objects.
16
/// @addtogroup bsl
17
/// @{
18
/// @addtogroup bslstl
19
/// @{
20
/// @addtogroup bslstl_allocator
21
/// @{
22
///
23
/// <h1> Outline </h1>
24
/// * <a href="#bslstl_allocator-purpose"> Purpose</a>
25
/// * <a href="#bslstl_allocator-classes"> Classes </a>
26
/// * <a href="#bslstl_allocator-description"> Description </a>
27
/// * <a href="#bslstl_allocator-restrictions-on-allocator-usage"> Restrictions on Allocator Usage </a>
28
/// * <a href="#bslstl_allocator-usage"> Usage </a>
29
///
30
/// # Purpose {#bslstl_allocator-purpose}
31
/// Provide an STL-compatible proxy for `bslma::Allocator` objects.
32
///
33
/// @deprecated Use @ref bslma_bslallocator instead.
34
///
35
/// # Classes {#bslstl_allocator-classes}
36
///
37
/// - bsl::allocator: STL-compatible allocator template
38
/// - bsl::allocator_traits<bsl::allocator>: specialization for `bsl::allocator`
39
///
40
/// **Canonical header:** bsl_memory.h
41
///
42
/// @see bslma_bslallocator
43
///
44
/// # Description {#bslstl_allocator-description}
45
/// This component is for internal use only. Please include
46
/// `<bsl_memory.h>` instead and use `bsl::allocator` directly. This component
47
/// provides an STL-compatible proxy for any allocator class derived from
48
/// `bslma::Allocator`. The proxy class, `bsl::allocator` is a template that
49
/// adheres to the allocator requirements defined in section 20.1.5
50
/// [lib.allocator.requirements] of the C++ standard. `bsl::allocator` may be
51
/// used to instantiate any class template that is parameterized by a standard
52
/// allocator. The container is expected to allocate memory for its own use
53
/// through the allocator. Different types of allocator use different
54
/// allocation mechanisms, so this mechanism gives the programmer control over
55
/// how the container obtains memory.
56
///
57
/// The `bsl::allocator` template is intended to solve a problem created by the
58
/// C++ standard allocator protocol. Since, in STL, the allocator type is
59
/// specified as a container template parameter, the allocation mechanism
60
/// becomes an explicit part of the resulting container type. Two containers
61
/// cannot be of the same type unless they are instantiated with the same
62
/// allocator type, and therefore the same allocation mechanism.
63
/// `bsl::allocator` breaks the connection between allocator type and allocation
64
/// mechanism. The allocation mechanism is chosen at *run-time* by
65
/// *initializing* (contrast with *instantiating*) the `bsl::allocator` with a
66
/// pointer to a *mechanism* *object* derived from `bslma::Allocator`. Each
67
/// class derived from `bslma::Allocator` implements a specific allocation
68
/// mechanism and is thus called a *mechanism* *class* within this component.
69
/// The `bsl::allocator` object forwards calls made through the standard
70
/// allocator interface to the mechanism object with which it was initialized.
71
/// In this way, two containers instantiated with `bsl::allocator` can utilize
72
/// different allocation mechanisms even though they have the same compile-time
73
/// type. The default mechanism object, if none is supplied to the
74
/// `bsl::allocator` constructor, is `bslma::Default::defaultAllocator()`.
75
///
76
/// Instantiations of `bsl::allocator` have full value semantics (well-behaved
77
/// copy construction, assignment, and tests for equality). Note, however, that
78
/// a `bsl::allocator` object does not "own" the `bslma::Allocator` with which
79
/// it is initialized. In practice , this means that copying a `bsl::allocator`
80
/// object does not copy its mechanism object and destroying a `bsl::allocator`
81
/// does not destroy its mechanism object. Two `bsl::allocator` objects compare
82
/// equal if and only if they share the same mechanism object.
83
///
84
/// ## Restrictions on Allocator Usage {#bslstl_allocator-restrictions-on-allocator-usage}
85
///
86
///
87
/// The allocator requirements section of the C++ standard (section 20.1.5
88
/// [lib.allocator.requirements]) permits containers to assume that two
89
/// allocators of the same type always compare equal. This assumption is
90
/// incorrect for instantiations of `bsl::allocator`. Therefore, any container
91
/// (or other facility) that can use `bsl::allocator` must operate correctly in
92
/// the presence of non-equal `bsl::allocator` objects. In practice, this means
93
/// that a container cannot transfer ownership of allocated memory to another
94
/// container unless the two containers use equal allocators. Two
95
/// `bsl::allocator` objects will compare equal if and only if they were
96
/// initialized with the same mechanism object.
97
///
98
/// ## Usage {#bslstl_allocator-usage}
99
///
100
///
101
/// We first show how to define a container type parameterized with an STL-style
102
/// allocator template parameter. For simplicity, we choose a fixed-size array
103
/// to avoid issues concerning reallocation, dynamic growth, etc. Furthermore,
104
/// we do not assume the `bslma` allocation protocol, which would dictate that
105
/// we pass-through the allocator to the parameterized `T` contained type (see
106
/// the @ref bslma_allocator component and `bslalg` package). The interface would
107
/// be as follows:
108
/// @code
109
/// // my_fixedsizearray.h
110
/// // ...
111
///
112
/// // =======================
113
/// // class my_FixedSizeArray
114
/// // =======================
115
///
116
/// /// This class provides an array of the parameterized `T` type passed of
117
/// /// fixed length at construction, using an object of the parameterized
118
/// /// `ALLOC` type to supply memory.
119
/// template <class T, class ALLOC>
120
/// class my_FixedSizeArray {
121
///
122
/// // DATA
123
/// ALLOC d_allocator;
124
/// int d_length;
125
/// T *d_array;
126
///
127
/// public:
128
/// // TYPES
129
/// typedef ALLOC allocator_type;
130
/// typedef T value_type;
131
///
132
/// // CREATORS
133
///
134
/// /// Create a fixed-size array of the specified `length`, using the
135
/// /// optionally specified `allocator` to supply memory. If
136
/// /// `allocator` is not specified, a default-constructed object of
137
/// /// the parameterized `ALLOC` type is used. Note that all the
138
/// /// elements in that array are default-constructed.
139
/// my_FixedSizeArray(int length, const ALLOC& allocator = ALLOC());
140
///
141
/// /// Create a copy of the specified `original` fixed-size array,
142
/// /// using the optionally specified `allocator` to supply memory. If
143
/// /// `allocator` is not specified, a default-constructed object of
144
/// /// the parameterized `ALLOC` type is used.
145
/// my_FixedSizeArray(const my_FixedSizeArray& original,
146
/// const ALLOC& allocator = ALLOC());
147
///
148
/// /// Destroy this fixed size array.
149
/// ~my_FixedSizeArray();
150
///
151
/// // MANIPULATORS
152
///
153
/// /// Return a reference to the modifiable element at the specified
154
/// /// `index` position in this fixed size array.
155
/// T& operator[](int index);
156
///
157
/// // ACCESSORS
158
///
159
/// /// Return a reference to the modifiable element at the specified
160
/// /// `index` position in this fixed size array.
161
/// const T& operator[](int index) const;
162
///
163
/// /// Return the length specified at construction of this fixed size
164
/// // array.
165
/// int length() const;
166
///
167
/// /// Return a reference to the non-modifiable allocator used by this
168
/// /// fixed size array to supply memory. This is here for
169
/// /// illustrative purposes. We should not generally have an accessor
170
/// /// to return the allocator.
171
/// const ALLOC& allocator() const;
172
/// };
173
///
174
/// // FREE OPERATORS
175
///
176
/// /// Return `true` if the specified `lhs` fixed-size array has the same
177
/// /// value as the specified `rhs` fixed-size array, and `false`
178
/// /// otherwise. Two fixed-size arrays have the same value if they have
179
/// /// the same length and if the element at any index in `lhs` has the
180
/// /// same value as the corresponding element at the same index in `rhs`.
181
/// template<class T, class ALLOC>
182
/// bool operator==(const my_FixedSizeArray<T,ALLOC>& lhs,
183
/// const my_FixedSizeArray<T,ALLOC>& rhs)
184
/// @endcode
185
/// The implementation is straightforward
186
/// @code
187
/// // my_fixedsizearray.cpp
188
/// // ...
189
/// // -----------------------
190
/// // class my_FixedSizeArray
191
/// // -----------------------
192
///
193
/// // CREATORS
194
/// template<class T, class ALLOC>
195
/// my_FixedSizeArray<T,ALLOC>::my_FixedSizeArray(int length,
196
/// const ALLOC& allocator)
197
/// : d_allocator(allocator), d_length(length)
198
/// {
199
/// d_array = d_allocator.allocate(d_length); // sizeof(T)*d_length bytes
200
///
201
/// // Default construct each element of the array:
202
/// for (int i = 0; i < d_length; ++i) {
203
/// d_allocator.construct(&d_array[i], T());
204
/// }
205
/// }
206
///
207
/// template<class T, class ALLOC>
208
/// my_FixedSizeArray<T,ALLOC>::my_FixedSizeArray(
209
/// const my_FixedSizeArray& original,
210
/// const ALLOC& allocator)
211
/// : d_allocator(allocator), d_length(original.d_length)
212
/// {
213
/// d_array = d_allocator.allocate(d_length); // sizeof(T)*d_length bytes
214
///
215
/// // copy construct each element of the array:
216
/// for (int i = 0; i < d_length; ++i) {
217
/// d_allocator.construct(&d_array[i], original.d_array[i]);
218
/// }
219
/// }
220
///
221
/// template<class T, class ALLOC>
222
/// my_FixedSizeArray<T,ALLOC>::~my_FixedSizeArray()
223
/// {
224
/// // Call destructor for each element
225
/// for (int i = 0; i < d_length; ++i) {
226
/// d_allocator.destroy(&d_array[i]);
227
/// }
228
///
229
/// // Return memory to allocator.
230
/// d_allocator.deallocate(d_array, d_length);
231
/// }
232
///
233
/// // MANIPULATORS
234
/// template<class T, class ALLOC>
235
/// inline T& my_FixedSizeArray<T,ALLOC>::operator[](int i)
236
/// {
237
/// return d_array[i];
238
/// }
239
///
240
/// // ACCESSORS
241
/// template<class T, class ALLOC>
242
/// inline
243
/// const T& my_FixedSizeArray<T,ALLOC>::operator[](int i) const
244
/// {
245
/// return d_array[i];
246
/// }
247
///
248
/// template<class T, class ALLOC>
249
/// inline int my_FixedSizeArray<T,ALLOC>::length() const
250
/// {
251
/// return d_length;
252
/// }
253
///
254
/// template<class T, class ALLOC>
255
/// inline
256
/// const ALLOC& my_FixedSizeArray<T,ALLOC>::allocator() const
257
/// {
258
/// return d_allocator;
259
/// }
260
///
261
/// // FREE OPERATORS
262
/// template<class T, class ALLOC>
263
/// bool operator==(const my_FixedSizeArray<T,ALLOC>& lhs,
264
/// const my_FixedSizeArray<T,ALLOC>& rhs)
265
/// {
266
/// if (lhs.length() != rhs.length()) {
267
/// return false;
268
/// }
269
/// for (int i = 0; i < lhs.length(); ++i) {
270
/// if (lhs[i] != rhs[i]) {
271
/// return false;
272
/// }
273
/// }
274
/// return true;
275
/// }
276
/// @endcode
277
/// Now we declare an allocator mechanism. Our mechanism will be to simply call
278
/// global `operator new` and `operator delete` functions, and count the number
279
/// of blocks outstanding (allocated but not deallocated). Note that a more
280
/// reusable implementation would take an underlying mechanism at construction.
281
/// We keep things simple only for the sake of this example.
282
/// @code
283
/// // my_countingallocator.h
284
///
285
/// // ==========================
286
/// // class my_CountingAllocator
287
/// // ==========================
288
///
289
/// /// This concrete implementation of the `bslma::Allocator` protocol
290
/// /// maintains some statistics of the number of blocks outstanding (i.e.,
291
/// /// allocated but not yet deallocated).
292
/// class my_CountingAllocator : public bslma::Allocator {
293
///
294
/// // DATA
295
/// int d_blocksOutstanding;
296
///
297
/// public:
298
/// // CREATORS
299
///
300
/// /// Create a counting allocator that uses the operators `new` and
301
/// /// `delete` to supply and free memory.
302
/// my_CountingAllocator();
303
///
304
/// // MANIPULATORS
305
///
306
/// /// Return a pointer to an uninitialized memory of the specified
307
/// /// `size` (in bytes).
308
/// virtual void *allocate(size_type size);
309
///
310
/// /// Return the memory at the specified `address` to this allocator.
311
/// virtual void deallocate(void *address);
312
///
313
/// // ACCESSORS
314
///
315
/// /// Return the number of blocks outstanding (i.e., allocated but not
316
/// /// yet deallocated by this counting allocator).
317
/// int blocksOutstanding() const;
318
/// };
319
/// @endcode
320
/// The implementation is really straightforward:
321
/// @code
322
/// // my_countingallocator.cpp
323
///
324
/// // --------------------------
325
/// // class my_CountingAllocator
326
/// // --------------------------
327
///
328
/// // CREATORS
329
/// my_CountingAllocator::my_CountingAllocator()
330
/// : d_blocksOutstanding(0)
331
/// {
332
/// }
333
///
334
/// // MANIPULATORS
335
/// void *my_CountingAllocator::allocate(size_type size)
336
/// {
337
/// ++d_blocksOutstanding;
338
/// return operator new(size);
339
/// }
340
///
341
/// void my_CountingAllocator::deallocate(void *address)
342
/// {
343
/// --d_blocksOutstanding;
344
/// operator delete(address);
345
/// }
346
///
347
/// // ACCESSORS
348
/// int my_CountingAllocator::blocksOutstanding() const
349
/// {
350
/// return d_blocksOutstanding;
351
/// }
352
/// @endcode
353
/// Now we can create array objects with different allocator mechanisms. First
354
/// we create an array, `a1`, using the default allocator and fill it with the
355
/// values `[1 .. 5]`:
356
/// @code
357
/// int main() {
358
///
359
/// my_FixedSizeArray<int, bsl::allocator<int> > a1(5);
360
/// assert(5 == a1.length());
361
/// assert(bslma::Default::defaultAllocator() == a1.allocator());
362
///
363
/// for (int i = 0; i < a1.length(); ++i) {
364
/// a1[i] = i + 1;
365
/// }
366
/// @endcode
367
/// Then we create a copy of `a1` using the counting allocator. The values of
368
/// `a1` and `a2` are equal, even though they have different allocation
369
/// mechanisms.
370
/// @code
371
/// my_CountingAllocator countingAlloc;
372
/// my_FixedSizeArray<int, bsl::allocator<int> > a2(a1,&countingAlloc);
373
/// assert(a1 == a2);
374
/// assert(a1.allocator() != a2.allocator());
375
/// assert(&countingAlloc == a2.allocator());
376
/// assert(1 == countingAlloc.blocksOutstanding())
377
/// }
378
/// @endcode
379
/// @}
380
/** @} */
381
/** @} */
382
383
/** @addtogroup bsl
384
* @{
385
*/
386
/** @addtogroup bslstl
387
* @{
388
*/
389
/** @addtogroup bslstl_allocator
390
* @{
391
*/
392
393
#include <bslscm_version.h>
394
395
#include <
bslma_bslallocator.h
>
396
397
398
399
400
401
#endif
402
403
// ----------------------------------------------------------------------------
404
// Copyright 2013 Bloomberg Finance L.P.
405
//
406
// Licensed under the Apache License, Version 2.0 (the "License");
407
// you may not use this file except in compliance with the License.
408
// You may obtain a copy of the License at
409
//
410
// http://www.apache.org/licenses/LICENSE-2.0
411
//
412
// Unless required by applicable law or agreed to in writing, software
413
// distributed under the License is distributed on an "AS IS" BASIS,
414
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
415
// See the License for the specific language governing permissions and
416
// limitations under the License.
417
// ----------------------------- END-OF-FILE ----------------------------------
418
419
/** @} */
420
/** @} */
421
/** @} */
bslma_bslallocator.h
bsls_ident.h
BSLS_IDENT
#define BSLS_IDENT(str)
Definition
bsls_ident.h:195
doxygen_input
bde
groups
bsl
bslstl
bslstl_allocator.h
Generated by
1.9.8