BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdld_datumarraybuilder.h
Go to the documentation of this file.
1/// @file bdld_datumarraybuilder.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdld_datumarraybuilder.h -*-C++-*-
8#ifndef INCLUDED_BDLD_DATUMARRAYBUILDER
9#define INCLUDED_BDLD_DATUMARRAYBUILDER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$ $CSID$")
13
14/// @defgroup bdld_datumarraybuilder bdld_datumarraybuilder
15/// @brief Provide a utility to build a `Datum` object holding an array.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdld
19/// @{
20/// @addtogroup bdld_datumarraybuilder
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdld_datumarraybuilder-purpose"> Purpose</a>
25/// * <a href="#bdld_datumarraybuilder-classes"> Classes </a>
26/// * <a href="#bdld_datumarraybuilder-description"> Description </a>
27/// * <a href="#bdld_datumarraybuilder-usage"> Usage </a>
28/// * <a href="#bdld_datumarraybuilder-example-1-using-a-datumarraybuilder-to-create-a-datum-array"> Example 1: Using a DatumArrayBuilder to Create a Datum array. </a>
29///
30/// # Purpose {#bdld_datumarraybuilder-purpose}
31/// Provide a utility to build a `Datum` object holding an array.
32///
33/// # Classes {#bdld_datumarraybuilder-classes}
34///
35/// - bdld::DatumArrayBuilder: utility to build a `Datum` object holding an array
36///
37/// @see bdld_datum
38///
39/// # Description {#bdld_datumarraybuilder-description}
40/// This component defines a mechanism, `bdld::DatumArrayBuilder`,
41/// used to populate a `Datum` array value in an exception-safe manner. In
42/// addition to providing exception safety, a `DatumArrayBuilder` is
43/// particularly useful when the length of the array to be constructed is not
44/// known in advance. The user can append elements to the datum array as
45/// needed, and when there are no more elements to append the user calls
46/// `commit` and ownership of the populated `Datum` object is transferred to the
47/// caller. After the call to `commit`, no additional elements can be appended
48/// to the `Datum` array value.
49///
50/// ## Usage {#bdld_datumarraybuilder-usage}
51///
52///
53/// This section illustrates intended use of this component.
54///
55/// ### Example 1: Using a DatumArrayBuilder to Create a Datum array. {#bdld_datumarraybuilder-example-1-using-a-datumarraybuilder-to-create-a-datum-array}
56///
57///
58/// Suppose we receive a string that is constructed by streaming a bunch of
59/// values together in the format shown below:
60/// @code
61/// "2.34,4,hi there,true"
62/// @endcode
63/// Notice that the values are separated by a `,`. Also note that a `,` is not
64/// allowed to be part of a string value to simplify the implementation of the
65/// utility that parses this string. The following code snippets illustrate how
66/// to create a `Datum` object that holds an array of `Datum` objects
67/// constructed using the streamed values.
68///
69/// First we define a function `nextValue` that we will use to tokenize the
70/// input string:
71/// @code
72/// /// Extract the next value from a list of comma separated values in the
73/// /// specified `input` string and load it in the specified `value`.
74/// /// Return the index of the next value within `input`.
75/// bsl::size_t nextValue(bsl::string *value, const bsl::string& input)
76/// {
77/// if (input.empty()) {
78/// return bsl::string::npos;
79/// }
80/// int start = 0;
81/// bsl::size_t nextIndex = input.find(',', start);
82/// if (bsl::string::npos != nextIndex) {
83/// *value = input.substr(start, nextIndex - start);
84/// }
85/// else {
86/// *value = input.substr(start);
87/// }
88/// return nextIndex;
89/// }
90/// @endcode
91/// Next, we define a function `convertToDatum` that will convert a string
92/// token into a `Datum` scalar value:
93/// @code
94/// // Convert the specified `token` into the appropriate type of scalar
95/// // value and then create and return a `Datum` object using that value.
96/// // Use the specified `basicAllocator` to supply memory.
97/// bdld::Datum convertToDatum(const bsl::string& token,
98/// bslma::Allocator *basicAllocator)
99/// {
100/// bool isInteger = true;
101/// bool isDouble = false;
102/// bool isBoolean = false;
103/// for (bsl::size_t i = 0; i < token.size(); ++i) {
104/// if (!isdigit(token[i])) {
105/// if ('.' == token[i] && !isDouble) {
106/// isDouble = true;
107/// isInteger = false;
108/// continue;
109/// }
110/// isInteger = false;
111/// isDouble = false;
112/// break;
113/// }
114/// }
115///
116/// if (!isInteger && !isDouble) {
117/// if ("true" == token || "false" == token) {
118/// isBoolean = true;
119/// }
120/// }
121///
122/// if (isInteger) { // integer token
123/// return bdld::Datum::createInteger(atoi(token.c_str()));
124/// }
125/// else if (isDouble) { // double token
126/// return bdld::Datum::createDouble(atof(token.c_str()));
127/// }
128/// else if (isBoolean) { // boolean token
129/// return bdld::Datum::createBoolean("true" == token ? true : false);
130/// }
131/// else { // string value
132/// return bdld::Datum::copyString(token, basicAllocator);
133/// }
134/// }
135/// @endcode
136/// Now, in our example main, we tokenize an input string "2.34,4,hi there,true"
137/// to populate a `Datum` array containing the values '[2.34, 4, "hi there",
138/// true]':
139/// @code
140/// void exampleMain() {
141/// bslma::TestAllocator allocator;
142/// const bsl::string input("2.34,4,hi there,true", &allocator);
143/// @endcode
144/// Here, we create a `DatumArrayBuilder`, and iterate over the parsed tokens
145/// from `input`, using `pushBack` on the array builder to add the tokens to a
146/// `Datum` array value:
147/// @code
148/// bdld::DatumArrayBuilder builder(0, &allocator);
149///
150/// bsl::string str(input, &allocator);
151///
152/// bsl::string value;
153/// bsl::size_t nextIndex;
154/// do {
155/// nextIndex = nextValue(&value, str);
156/// builder.pushBack(convertToDatum(value, &allocator));
157/// if (bsl::string::npos == nextIndex) {
158/// break;
159/// }
160/// str = str.substr(nextIndex + 1);
161/// } while (bsl::string::npos != nextIndex);
162///
163/// bdld::Datum result = builder.commit();
164/// @endcode
165/// Notice that calling `commit` on the `DatumArrayBuilder` adopts ownership
166/// for the returned `Datum` object, and that the behavior is undefined if
167/// `pushBack` is called after `commit`.
168///
169/// Finally, we verify that `result` has the expected array value, and destroy
170/// the created `Datum` value:
171/// @code
172/// assert(true == result.isArray());
173/// assert(4 == result.theArray().length());
174/// assert(true == result.theArray()[0].isDouble());
175/// assert(2.34 == result.theArray()[0].theDouble());
176/// assert(true == result.theArray()[1].isInteger());
177/// assert(4 == result.theArray()[1].theInteger());
178/// assert(true == result.theArray()[2].isString());
179/// assert("hi there" == result.theArray()[2].theString());
180/// assert(true == result.theArray()[3].isBoolean());
181/// assert(true == result.theArray()[3].theBoolean());
182///
183/// // Destroy the 'Datum' object.
184/// bdld::Datum::destroy(result, &allocator);
185/// }
186/// @endcode
187/// @}
188/** @} */
189/** @} */
190
191/** @addtogroup bdl
192 * @{
193 */
194/** @addtogroup bdld
195 * @{
196 */
197/** @addtogroup bdld_datumarraybuilder
198 * @{
199 */
200
201#include <bdlscm_version.h>
202
203#include <bdld_datum.h>
204
205#include <bslma_bslallocator.h>
207
209
210#include <bsls_types.h>
211
212
213namespace bdld {
214
215 // =======================
216 // class DatumArrayBuilder
217 // =======================
218
219/// This `class` provides a mechanism to build a `Datum` object having an
220/// array value in an exception-safe manner.
221///
222/// See @ref bdld_datumarraybuilder
224
225 public:
226 // TYPES
227
228 /// `SizeType` is an alias for an unsigned integral value, representing
229 /// the capacity or length of a datum array.
231
233
234 private:
235 // DATA
236 DatumMutableArrayRef d_array; // mutable access to the datum array
237 SizeType d_capacity; // capacity of the datum array
238 allocator_type d_allocator; // allocator for memory
239
240 private:
241 // NOT IMPLEMENTED
243 DatumArrayBuilder& operator=(const DatumArrayBuilder&);
244
245 public:
246 // TRAITS
249
250 // CREATORS
251
253 explicit DatumArrayBuilder(const allocator_type& allocator);
254 /// Create a `DatumArrayBuilder` object that will administer the process
255 /// of building a `Datum` array. Optionally specify an
256 /// `initialCapacity` for the array. If `initialCapacity` is not
257 /// supplied, the initial capacity of the array is 0. Optionally
258 /// specify an `allocator` (e.g., the address of a `bslma::Allocator`
259 /// object) to supply memory; otherwise, the default allocator is used.
261 SizeType initialCapacity,
262 const allocator_type& allocator = allocator_type());
263
264 /// Destroy this object. If this object is holding a `Datum` array that
265 /// has not been adopted, then the `Datum` array is disposed after
266 /// destroying each of its elements.
268
269 // MANIPULATORS
270
271 /// Append the specified array `values` having the specified `length` to
272 /// the `Datum` array being built by this object. The behavior is
273 /// undefined unless `0 != length && 0 != values` and each element in
274 /// `values` that needs dynamic memory, is allocated with the same
275 /// allocator that was used to construct this object. The behavior is
276 /// also undefined if `commit` has already been called on this object.
277 void append(const Datum *values, SizeType length);
278
279 /// Return a `Datum` array value holding the elements supplied to
280 /// `pushBack` or `append`. The caller is responsible for releasing the
281 /// resources of the returned `Datum` object. Calling this method
282 /// indicates that the caller is finished building the datum array and
283 /// no further values shall be appended. It is undefined behavior to
284 /// call any method of this object, other than the destructor, after
285 /// `commit` has been called.
287
288 /// Append the specified `value` to the `Datum` array being built by
289 /// this object. The behavior is undefined if `value` needs dynamic
290 /// memory and was allocated using a different allocator than the one
291 /// used to construct this object. The behavior is also undefined if
292 /// `commit` has already been called on this object.
293 void pushBack(const Datum& value);
294
295 // ACCESSORS
296
297 /// Return the capacity of the held `Datum` array. The behavior is
298 /// undefined if `commit` has already been called on this object. Note
299 /// that similar to the capacity of a `vector`, the returned capacity
300 /// has no bearing on the value of the `Datum` array being constructed,
301 /// but does indicate at which point additional memory will be required
302 /// to grow the `Datum` array being built.
303 SizeType capacity() const;
304
305 /// Return the allocator used by this object to supply memory. Note
306 /// that if no allocator was supplied at construction the default
307 /// allocator in effect at construction is used.
309
310 /// Return the size of the held `Datum` array. The behavior is
311 /// undefined if `commit` has already been called on this object.
312 SizeType size() const;
313};
314
315// ============================================================================
316// INLINE DEFINITIONS
317// ============================================================================
318
319 // -----------------------
320 // class DatumArrayBuilder
321 // -----------------------
322
323// ACCESSORS
324inline
326{
327 return d_capacity;
328}
329
330inline
335
336inline
338{
339 if (d_capacity) {
340 return *d_array.length(); // RETURN
341 }
342 return 0;
343}
344
345} // close package namespace
346
347
348#endif
349
350// ----------------------------------------------------------------------------
351// Copyright 2020 Bloomberg Finance L.P.
352//
353// Licensed under the Apache License, Version 2.0 (the "License");
354// you may not use this file except in compliance with the License.
355// You may obtain a copy of the License at
356//
357// http://www.apache.org/licenses/LICENSE-2.0
358//
359// Unless required by applicable law or agreed to in writing, software
360// distributed under the License is distributed on an "AS IS" BASIS,
361// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
362// See the License for the specific language governing permissions and
363// limitations under the License.
364// ----------------------------- END-OF-FILE ----------------------------------
365
366/** @} */
367/** @} */
368/** @} */
Definition bdld_datumarraybuilder.h:223
void append(const Datum *values, SizeType length)
DatumArrayBuilder(SizeType initialCapacity, const allocator_type &allocator=allocator_type())
DatumArrayBuilder(const allocator_type &allocator)
allocator_type get_allocator() const
Definition bdld_datumarraybuilder.h:331
bsl::allocator< char > allocator_type
Definition bdld_datumarraybuilder.h:232
SizeType size() const
Definition bdld_datumarraybuilder.h:337
bsls::Types::size_type SizeType
Definition bdld_datumarraybuilder.h:230
BSLMF_NESTED_TRAIT_DECLARATION(DatumArrayBuilder, bslma::UsesBslmaAllocator)
void pushBack(const Datum &value)
SizeType capacity() const
Definition bdld_datumarraybuilder.h:325
Definition bdld_datum.h:2137
SizeType * length() const
Return pointer to the length of the array.
Definition bdld_datum.h:5354
Definition bdld_datum.h:787
Definition bslma_bslallocator.h:580
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdld_datum.h:730
Definition bslma_usesbslmaallocator.h:343
std::size_t size_type
Definition bsls_types.h:124