// bdld_datumintmapbuilder.h -*-C++-*- #ifndef INCLUDED_BDLD_DATUMINTMAPBUILDER #define INCLUDED_BDLD_DATUMINTMAPBUILDER #include <bsls_ident.h> BSLS_IDENT("$Id$ $CSID$") //@PURPOSE: Provide a utility to build a 'Datum' object holding an int-map. // //@CLASSES: // bdld::DatumIntMapBuilder: utility to build 'Datum' objects holding int-maps // //@SEE_ALSO: bdld_datum // //@DESCRIPTION: This component defines a mechanism, 'bdld::DatumIntMapBuilder', // used to populate a 'Datum' int-map value in an exception-safe manner. In // addition to providing exception safety, a 'DatumIntMapBuilder' is // particularly useful when the size of the int-map to be constructed is not // known in advance. The user can append elements to the datum int-map as // needed, and when there are no more elements to append the user calls // 'commit' or 'sortAndCommit' and ownership of the populated 'Datum' object is // transferred to the caller. After calling 'commit' or 'sortAndCommit', no // additional elements can be appended to the 'Datum' int-map value. Note that // 'sortAndCommit' method will sort the populated int-map (by keys) and tag the // resulting 'Datum' int-map value as sorted. Also note that the user can // insert elements in a (ascending) sorted order and tag the int-map as sorted. // The behavior is undefined if unsorted int-map is tagged sorted. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Basic Syntax ///- - - - - - - - - - - - // Suppose we need a data map for some UX data. The keys of the map are 32-bit // integers; and the values in that map can be different types. The following // code illustrates how to use 'bdld::DatumIntMapBuilder' to create such map // easily. // // First, we need data to fill our int-map: //.. // bslma::TestAllocator ta("test", veryVeryVerbose); // // DatumIntMapEntry formData[] = { // DatumIntMapEntry(1, Datum::createStringRef("Bart", &ta)), // DatumIntMapEntry(2, Datum::createStringRef("Simpson", &ta)), // DatumIntMapEntry(3, Datum::createStringRef("male", &ta)), // DatumIntMapEntry(4, Datum::createInteger(10)) // }; // // const size_t DATA_SIZE = sizeof(formData) / sizeof(DatumIntMapEntry); //.. // Next, we create an object of 'DatumIntMapBuilder' class with initial // capacity sufficient for storing all our data: //.. // DatumIntMapBuilder builder(DATA_SIZE, &ta); //.. // Then, we load our builder with these data: //.. // for (size_t i = 0; i < DATA_SIZE; ++i) { // builder.pushBack(formData[i].key(), formData[i].value()); // } //.. // Next, we adopt the int-map, held by our builder, by newly created 'Datum' // object: //.. // Datum form = builder.commit(); //.. // Now, we can check that all data have been correctly added to the int-map at // the required order: //.. // assert(true == form.isIntMap()); // assert(DATA_SIZE == form.theIntMap().size()); // // assert(1 == form.theIntMap()[0].key()); // assert(true == form.theIntMap()[0].value().isString()); // assert("Bart" == form.theIntMap()[0].value().theString()); // // assert(2 == form.theIntMap()[1].key()); // assert(true == form.theIntMap()[1].value().isString()); // assert("Simpson" == form.theIntMap()[1].value().theString()); // // assert(3 == form.theIntMap()[2].key()); // assert(true == form.theIntMap()[2].value().isString()); // assert("male" == form.theIntMap()[2].value().theString()); // // assert(4 == form.theIntMap()[3].key()); // assert(true == form.theIntMap()[3].value().isInteger()); // assert(10 == form.theIntMap()[3].value().theInteger()); //.. // Finally, we destroy the 'Datum' object to release all allocated memory // correctly: //.. // Datum::destroy(form, &ta); // assert(0 == ta.numBytesInUse()); //.. #include <bdlscm_version.h> #include <bdld_datum.h> #include <bslma_stdallocator.h> #include <bslma_usesbslmaallocator.h> #include <bslmf_nestedtraitdeclaration.h> #include <bsls_types.h> namespace BloombergLP { namespace bdld { // ======================== // class DatumIntMapBuilder // ======================== class DatumIntMapBuilder { // This 'class' provides a mechanism to build a 'Datum' object having an // int-map value in an exception-safe manner. See 'bdld_datum' for more // information about integer maps. public: // TYPES typedef bsls::Types::size_type SizeType; // 'SizeType' is an alias for a unsigned integral value, representing // the capacity or size of a datum int-map. typedef bsl::allocator<char> allocator_type; private: // DATA DatumMutableIntMapRef d_mapping; // mutable access to the datum int-map SizeType d_capacity; // capacity of the datum int-map bool d_sorted; // underlying int-map is sorted allocator_type d_allocator; // allocator for memory private: // NOT IMPLEMENTED DatumIntMapBuilder(const DatumIntMapBuilder&); DatumIntMapBuilder& operator=(const DatumIntMapBuilder&); public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(DatumIntMapBuilder, bslma::UsesBslmaAllocator); // 'DatumIntMapBuilder' is allocator-aware. // CREATORS DatumIntMapBuilder(); explicit DatumIntMapBuilder(const allocator_type& allocator); explicit DatumIntMapBuilder( SizeType initialCapacity, const allocator_type& allocator = allocator_type()); // Create a 'DatumIntMapBuilder' object that will administer the // process of building a 'Datum' int-map. Optionally specify an // 'initialCapacity' for the int-map. If 'initialCapacity' is not // supplied, the initial capacity of the int-map is 0. Optionally // specify an 'allocator' (e.g., the address of a 'bslma::Allocator' // object) to supply memory; otherwise, the default allocator is used. ~DatumIntMapBuilder(); // Destroy this object. If this object is holding a datum int-map that // has not been adopted, then the datum int-map is disposed after // destroying each of its elements. // MANIPULATORS void append(const DatumIntMapEntry *entries, SizeType size); // Append the specified array 'entries' having the specified 'size' to // the 'Datum' int-map being build by this object. The behavior is // undefined unless '0 != entries && 0 != size' and each element in // 'entries' that needs dynamic memory is allocated with the same // allocator that was used to construct this object. The behavior is // undefined if 'commit' or 'sortAndCommit' has already been called on // this object. Datum commit(); // Return a 'Datum' int-map value holding the elements supplied to // 'pushBack' or 'append'. The caller is responsible for releasing the // resources of the returned 'Datum' object. Calling this method // indicates that the caller is finished building the 'Datum' int-map // and no further values shall be appended. The behavior is undefined // if any method of this object, other than its destructor, is called // after 'commit' invocation. void pushBack(int key, const Datum& value); // Append the entry with the specified 'key' and the specified 'value' // to the 'Datum' int-map being build by this object. The behavior is // undefined if 'value' needs dynamic memory and was allocated using a // different allocator than the one used to construct this object. The // behavior is also undefined if 'commit' or 'sortAndCommit' has // already been called on this object. void setSorted(bool value); // Mark the Datum int-map being built by this object as sorted if the // specified 'value' is 'true' and mark it unsorted otherwise. This // function does not sort the int-map entries, or mark them to be // sorted later; the function should be used to indicate if the entries // are being appended in sorted order. The behavior is undefined if // 'commit' or 'sortAndCommit' has already been called on this object. // The behavior is also undefined if the int-map being constructed is // marked sorted, but the entries are not appended in sorted order. // Note also that the int-map being constructed is marked unsorted by // default. Datum sortAndCommit(); // Return a 'Datum' int-map value holding the elements supplied to // 'pushBack' or 'append' sorted by their keys. The caller is // responsible for releasing the resources of the returned 'Datum' // object. Calling this method indicates that the caller is finished // building the 'Datum' int-map and no further values shall be // appended. The behavior is undefined if any method of this object, // other than its destructor, is called after 'sortAndCommit' // invocation. // ACCESSORS SizeType capacity() const; // Return the capacity of the held 'Datum' int-map. The behavior is // undefined if 'commit' or 'sortAndCommit' has already been called on // this object. Note that similar to the capacity of a 'vector', the // returned capacity has no bearing on the value of the 'Datum' being // constructed, but does indicate at which point additional memory will // be required to grow the 'Datum' int-map being built. allocator_type get_allocator() const; // Return the allocator used by this object to supply memory. Note // that if no allocator was supplied at construction the default // allocator in effect at construction is used. SizeType size() const; // Return the size of the held 'Datum' int-map. The behavior is // undefined if 'commit' or 'sortAndCommit' has already been called on // this object. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ------------------------ // class DatumIntMapBuilder // ------------------------ // ACCESSORS inline DatumIntMapBuilder::SizeType DatumIntMapBuilder::capacity() const { return d_capacity; } inline DatumIntMapBuilder::allocator_type DatumIntMapBuilder::get_allocator() const { return d_allocator; } inline DatumIntMapBuilder::SizeType DatumIntMapBuilder::size() const { if (d_capacity) { return *d_mapping.size(); // RETURN } return 0; } } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2017 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------