// ball_managedattributeset.h -*-C++-*- #ifndef INCLUDED_BALL_MANAGEDATTRIBUTESET #define INCLUDED_BALL_MANAGEDATTRIBUTESET #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a container for managed attributes. // //@CLASSES: // ball::ManagedAttributeSet: a container for managed attributes // //@SEE_ALSO: ball_managedattribute, ball_rule // //@DESCRIPTION: This component implements a value-semantic container class, // 'ball::ManagedAttributeSet', that manages a set of 'ball::ManagedAttribute' // objects. // // This component participates in the implementation of "Rule-Based Logging". // For more information on how to use that feature, please see the // package-level documentation and usage examples for "Rule-Based Logging". // ///Usage ///----- // In this section we show intended usage of this component. // ///Example 1: Basic Properties of 'ball::ManagedAttributeSet' /// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // This example shows basic operations on a managed attribute set. // // First, we create an empty attribute set: //.. // ball::ManagedAttributeSet attributeSet; //.. // Then, we add two attributes to the attribute set: //.. // ball::ManagedAttribute p1("uuid", 4044457); // assert(attributeSet.addAttribute(p1)); // assert(attributeSet.addAttribute(ball::ManagedAttribute("uuid", 3133246))); //.. // Next, we look up (by value) via the 'isMember' method: //.. // assert(attributeSet.isMember(p1)); // assert(attributeSet.isMember(ball::ManagedAttribute("uuid", 3133246))); //.. // Then, we add duplicated value and observe the status of the operation: //.. // assert(!attributeSet.addAttribute(ball::ManagedAttribute("uuid", // 3133246))); //.. // Finally, we remove an attribute and check that it is not a member of the // attribute set: //.. // assert(attributeSet.removeAttribute(p1)); // assert(!attributeSet.isMember(p1)); //.. #include <balscm_version.h> #include <ball_attribute.h> #include <ball_managedattribute.h> #include <bslma_allocator.h> #include <bslma_usesbslmaallocator.h> #include <bslmf_nestedtraitdeclaration.h> #include <bsl_functional.h> #include <bsl_unordered_set.h> namespace BloombergLP { namespace ball { class AttributeContainerList; // ========================= // class ManagedAttributeSet // ========================= class ManagedAttributeSet { // This class implements a value-semantic collection of unique attributes. // (Note that an attribute is a compound entity that, as a whole, must be // unique although individual parts need not be.) Additionally, the // 'evaluate' accessor can be used to determine if every attribute in the // set is present in the specified attribute container list. // PRIVATE TYPES struct AttributeHash { // A hash functor for 'ManagedAttribute'. private: // CLASS DATA static int s_hashtableSize; // default hashtable size for which the // hash value is calculated public: // ACCESSORS int operator()(const ManagedAttribute& attribute) const // Return the hash value of the specified 'attribute'. { return ManagedAttribute::hash(attribute, s_hashtableSize); } }; typedef bsl::unordered_set<ManagedAttribute, AttributeHash> SetType; // This 'typedef' is an alias for the container of managed attributes // used by this object. // CLASS DATA static int s_initialSize; // the initial size of the set // DATA SetType d_attributeSet; // the set of attributes // FRIENDS friend bool operator==(const ManagedAttributeSet&, const ManagedAttributeSet&); friend bool operator!=(const ManagedAttributeSet&, const ManagedAttributeSet&); friend bsl::ostream& operator<<(bsl::ostream&, const ManagedAttributeSet&); public: // TYPES typedef bsl::allocator<char> allocator_type; typedef SetType::const_iterator const_iterator; // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(ManagedAttributeSet, bslma::UsesBslmaAllocator); // CLASS METHODS static int hash(const ManagedAttributeSet& set, int size); // Return a hash value calculated from the specified 'set' using the // specified 'size' as the number of slots. The hash value is // guaranteed to be in the range '[0 .. size - 1]'. The behavior is // undefined unless '0 < size'. // CREATORS ManagedAttributeSet(); explicit ManagedAttributeSet(const allocator_type& allocator); // Create an empty 'ManagedAttributeSet' object. Optionally specify an // 'allocator' (e.g., the address of a 'bslma::Allocator' object) to // supply memory; otherwise, the default allocator is used. ManagedAttributeSet( const ManagedAttributeSet& original, const allocator_type& allocator = allocator_type()); // Create a 'ManagedAttributeSet' object having the same value as the // specified 'original' object. Optionally specify an 'allocator' // (e.g., the address of a 'bslma::Allocator' object) to supply memory; // otherwise, the default allocator is used. //! ~ManagedAttributeSet() = default; // Destroy this attribute set. // MANIPULATORS ManagedAttributeSet& operator=(const ManagedAttributeSet& rhs); // Assign the value of the specified 'rhs' to this object, and return a // reference providing modifiable access to this object. bool addAttribute(const ManagedAttribute& value); // Add an attribute having the specified 'value' to this object. // Return 'true' on success and 'false' if an attribute having the // same 'value' already exists in this object. int addPredicate(const ManagedAttribute& value); // Add an attribute having the specified 'value' to this object. // Return 1 on success and 0 if an attribute having the same value // already exists in this object. // !DEPRECATED!: Use 'addAttribute' instead. void removeAll(); // Remove all attributes from this attribute set. void removeAllPredicates(); // !DEPRECATED!: Use 'removeAll' instead. bool removeAttribute(const ManagedAttribute& value); // Remove the attribute having the specified 'value' from this object. // Return 'true' on success and 'false' if an attribute having the // 'value' does not exist in this object. int removePredicate(const ManagedAttribute& value); // Remove the attribute having the specified 'value' from this object. // Return the number of attributes removed (i.e., 1 on success and 0 if // an attribute having 'value' does not exist in this object). // !DEPRECATED!: Use 'removeAttribute' instead. // ACCESSORS bool evaluate(const AttributeContainerList& containerList) const; // Return 'true' if for every attribute maintained by this object, an // attribute with the same name and value exists in the specified // 'containerList', or if this object has no attributes; otherwise // return 'false'. 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. bool isMember(const ManagedAttribute& value) const; // Return 'true' if an attribute having specified 'value' exists in // this object, and 'false' otherwise. int numAttributes() const; // Return the number of attributes managed by this object. int numPredicates() const; // !DEPRECATED!: Use 'numAttributes' instead. const_iterator begin() const; // Return an iterator referring to the first member of this attribute // set. const_iterator end() const; // Return an iterator referring to one past the last member of this // attribute set. bsl::ostream& print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const; // Format this object to the specified output 'stream' at the (absolute // value of) the optionally specified indentation 'level' and return a // reference to 'stream'. If 'level' is specified, optionally specify // 'spacesPerLevel', the number of spaces per indentation level for // this and all of its nested objects. If 'level' is negative, // suppress indentation of the first line. If 'spacesPerLevel' is // negative, format the entire output on one line, suppressing all but // the initial indentation (as governed by 'level'). If 'stream' is // not valid on entry, this operation has no effect. }; // FREE OPERATORS bool operator==(const ManagedAttributeSet& lhs, const ManagedAttributeSet& rhs); // Return 'true' if the specified 'lhs' and 'rhs' objects have the same // value, and 'false' otherwise. Two 'ManagedAttributeSet' objects have // the same value if they have the same number of attributes and every // attribute value that appears in one object also appears in the other. bool operator!=(const ManagedAttributeSet& lhs, const ManagedAttributeSet& rhs); // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the // same value, and 'false' otherwise. Two 'ManagedAttributeSet' objects do // not have the same value if they do not have the same number of // attributes or there is at least one attribute value that appears in one // object, but not in the other. bsl::ostream& operator<<(bsl::ostream& output, const ManagedAttributeSet& attributeSet); // Write the value of the specified 'attributeSet' to the specified // 'output' stream. Return the specified 'output' stream. // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ------------------------- // class ManagedAttributeSet // ------------------------- // CREATORS inline ManagedAttributeSet::ManagedAttributeSet() : d_attributeSet(s_initialSize, // initial size AttributeHash(), // hash functor bsl::equal_to<ManagedAttribute>()) // equal functor { } inline ManagedAttributeSet::ManagedAttributeSet(const allocator_type& allocator) : d_attributeSet(s_initialSize, // initial size AttributeHash(), // hash functor bsl::equal_to<ManagedAttribute>(), // equal functor allocator.mechanism()) { } inline ManagedAttributeSet::ManagedAttributeSet(const ManagedAttributeSet& original, const allocator_type& allocator) : d_attributeSet(original.d_attributeSet, allocator) { } // MANIPULATORS inline bool ManagedAttributeSet::addAttribute(const ManagedAttribute& value) { return d_attributeSet.insert(value).second; } inline int ManagedAttributeSet::addPredicate(const ManagedAttribute& value) { return addAttribute(value); } inline bool ManagedAttributeSet::removeAttribute(const ManagedAttribute& value) { return !!d_attributeSet.erase(value); } inline int ManagedAttributeSet::removePredicate(const ManagedAttribute& value) { return static_cast<int>(d_attributeSet.erase(value)); } inline void ManagedAttributeSet::removeAll() { d_attributeSet.clear(); } inline void ManagedAttributeSet::removeAllPredicates() { removeAll(); } // ACCESSORS inline ManagedAttributeSet::allocator_type ManagedAttributeSet::get_allocator() const { return d_attributeSet.get_allocator(); } inline bool ManagedAttributeSet::isMember(const ManagedAttribute& value) const { return d_attributeSet.find(value) != d_attributeSet.end(); } inline int ManagedAttributeSet::numAttributes() const { return static_cast<int>(d_attributeSet.size()); } inline int ManagedAttributeSet::numPredicates() const { return numAttributes(); } inline ManagedAttributeSet::const_iterator ManagedAttributeSet::begin() const { return d_attributeSet.begin(); } inline ManagedAttributeSet::const_iterator ManagedAttributeSet::end() const { return d_attributeSet.end(); } } // close package namespace // FREE OPERATORS inline bsl::ostream& ball::operator<<(bsl::ostream& output, const ManagedAttributeSet& attributeSet) { attributeSet.print(output, 0, -1); return output; } } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 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 ----------------------------------