Outline
Purpose
Provide a protocol for containers holding logging attributes.
Classes
- See also
- ball_attribute, ball_defaultattributecontainer
Description
This component defines a protocol class, ball::AttributeContainer
, for containers of ball::Attribute
values. The ball::AttributeContainer
protocol primarily provides a hasValue()
method, allowing clients to determine if a given attribute value is held by the container.
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 the following examples we examine two derived implementations of the ball::AttributeContainer
protocol. The first implementation is potentially more efficient, holding a specific group of attributes relevant to a particular application. The second implementation is more general, and can hold any valid ball::Attribute
value. In the final example we demonstrate how to call the methods of the ball::AttributeContainer
protocol.
Example 1: An Implementation of ball::AttributeContainer
In the following example we develop a ball::AttributeContainer
implementation specifically intended for a service offline that will perform rule-based logging, governed by the service client's Bloomberg "uuid", "luw", and "firm number". We define a class ServiceAttributes
that contains three integer ball::Attribute
values having the names "uuid", "luw", and "firmNumber".
Note that this implementation requires no memory allocation, so it will be more efficient than a more general set-based implementation if the container is frequently created, destroyed, or modified. We will develop a ball::AttributeContainer
implementation that can hold any ball::Attribute
value in example 2 (and one is provided by the ball
package in the ball_defaultattributecontainer component).
Definition ball_attributecontainer.h:426
Note that we use the type ball::Attribute
for our data members for simplicity. It would be a little more efficient to use int
data members, but the implementation of hasValue()
would be less readable.
public:
static const char * const UUID_ATTRIBUTE_NAME;
static const char * const LUW_ATTRIBUTE_NAME;
static const char * const FIRMNUMBER_ATTRIBUTE_NAME;
ServiceAttributes(int uuid, int luw, int firmNumber);
virtual ~ServiceAttributes();
virtual bsl::ostream& print(bsl::ostream& stream,
int level = 0,
int spacesPerLevel = 4) const;
virtual void visitAttributes(
};
inline
ServiceAttributes::ServiceAttributes(int uuid, int luw, int firmNumber)
: d_uuid(UUID_ATTRIBUTE_NAME, uuid)
, d_luw(LUW_ATTRIBUTE_NAME, luw)
, d_firmNumber(FIRMNUMBER_ATTRIBUTE_NAME, firmNumber)
{
}
const char * const ServiceAttributes::UUID_ATTRIBUTE_NAME = "uuid";
const char * const ServiceAttributes::LUW_ATTRIBUTE_NAME = "luw";
const char * const ServiceAttributes::FIRMNUMBER_ATTRIBUTE_NAME =
"firmNumber";
ServiceAttributes::~ServiceAttributes()
{
}
{
return d_uuid == value || d_luw == value || d_firmNumber == value;
}
bsl::ostream& ServiceAttributes::print(bsl::ostream& stream,
int level,
int spacesPerLevel) const
{
printer.start();
printer.printAttribute("uuid", d_uuid);
printer.printAttribute("luw", d_luw);
printer.printAttribute("firmNumber", d_firmNumber);
printer.end();
return stream;
}
void ServiceAttributes::visitAttributes(
{
visitor(d_uuid);
visitor(d_luw);
visitor(d_firmNumber);
}
Definition ball_attribute.h:198
Forward declaration.
Definition bslstl_function.h:934
Definition bslim_printer.h:601
Example 2: A Generic Implementation of ball::AttributeContainer
In this second example we define a ball::AttributeContainer
that can contain any valid ball::Attribute
value (a "generic" ball::AttributeContainer
). In practice, an implementation that can contain any attribute values may be less efficient than one specifically created for a particular group of attributes needed by an application (as shown in {Example 1}).
Note that the ball
package provides a similar ball::AttributeContainer
implementation in the ball_defaultattributecontainer component.
To define an STL set (or hash set) for ball::Attribute
values, we must define a comparison (or hash) operation for attribute values. Here we define a comparison functor that compares attributes by name, then by value-type, and finally by value.
struct AttributeComparator {
{
int cmp = bsl::strcmp(lhs.
name(), rhs.
name());
if (0 != cmp) {
return cmp < 0;
}
}
case 0:
return true;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
return lhs.
value().
the<
unsigned long long>()
< rhs.
value().
the<
unsigned long long>();
case 7:
case 8:
return lhs.
value().
the<
const void *>() <
case 9:
}
return false;
}
};
public:
virtual ~AttributeSet();
virtual bsl::ostream&
print(bsl::ostream& stream,
int level = 0,
int spacesPerLevel = 4) const;
virtual void visitAttributes(
};
const char * name() const
Return the name of this object.
Definition ball_attribute.h:643
const Value & value() const
Definition ball_attribute.h:649
Definition bdlb_guid.h:201
int typeIndex() const
Definition bdlb_variant.h:7646
TYPE & the()
Definition bdlb_variant.h:7517
Definition bslstl_string.h:1281
Definition bslstl_set.h:657
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
bsl::ostream & print(bsl::ostream &stream, const TYPE &object, int level=0, int spacesPerLevel=4)
Definition bdlb_printmethods.h:719
The AttributeSet
methods are simple wrappers around bsl::set
methods:
inline
: d_set(AttributeComparator(), basicAllocator)
{
}
inline
{
}
inline
{
return d_set.
erase(value) > 0;
}
AttributeSet::~AttributeSet()
{
}
{
return d_set.
find(value) != d_set.
end();
}
bsl::ostream& AttributeSet::print(bsl::ostream& stream,
int level,
int spacesPerLevel) const
{
printer.start();
for (; it != d_set.
end(); ++it) {
printer.printValue(*it);
}
return stream;
}
void AttributeSet::visitAttributes(
{
for (; it != d_set.
end(); ++it) {
visitor(*it);
}
}
pair< iterator, bool > insert(const value_type &value)
Definition bslstl_set.h:2326
set &operator=(BloombergLP::bslmf::MovableRef< set > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_set.h:2294
iterator find(const key_type &key)
Definition bslstl_set.h:1191
BloombergLP::bslstl::TreeIterator< const value_type, Node, difference_type > const_iterator
Definition bslstl_set.h:762
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_set.h:2302
iterator erase(const_iterator position)
Definition bslstl_set.h:2544
Example 3. Using a ball::AttributeContainer
In this final example, we demonstrate how to call the methods of the ball::AttributeContainer
protocol.
First we create an object of a concrete type that implements the ball::AttributeContainer
protocol (e.g., ServiceAttributes
defined in {Example 1}). Then we obtain a reference to this object.
ServiceAttributes serviceAttributes(3938908, 1, 9001);
We use hasValue()
to examine the values in the container:
virtual bool hasValue(const Attribute &value) const =0
Finally we can print the attribute values in the container:
bsl::cout << attributes << bsl::endl;
The resulting output should look like:
[ [ uuid = 3938908 ] [ luw = 1 ] [ firmNumber = 9001 ] ]