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