Provide a binary functor conforming to the C++11 equal_to
spec.
More...
Detailed Description
- Outline
-
-
- Purpose:
- Provide a binary functor conforming to the C++11
equal_to
spec.
-
- Classes:
equal_to | C++11-compliant binary functor applying operator== |
- Canonical Header:
- bsl_functional.h
- See also:
- Component bslstl_unorderedmap, Component bslstl_unorderedset
-
- Description:
- This component provides the C+11 standard binary comparison functor,
bsl::equal_to
, that evaluates equality of two VALUE_TYPE
objects through the operator==
. The application of the functor to two different objects o1
and o2
returns true if o1 == o2
. Note that this the for use as keys in the standard unordered associative containers such as bsl::unordered_map
and bsl::unordered_set
. Also note that this class is an empty POD type.
-
- Usage:
- This section illustrates intended usage of this component.
-
- Example 1: Creating and Using a List Set:
- Suppose we want to keep a set of a small number of elements, and the only comparison operation we have on the type of the elements is an equality operator. We can keep a singly-linked list of the elements, and exhaustively use the comparison operator to see if a given value exists in the list, forming a primitive set.
- First, we define our
ListSet
template class: template <typename TYPE, typename EQUALS = bsl::equal_to<TYPE> >
class ListSet {
struct Node {
TYPE d_value;
Node *d_next;
};
EQUALS d_comparator;
Node *d_nodeList;
bslma::Allocator *d_allocator_p;
private:
ListSet(const ListSet&);
ListSet& operator=(const ListSet&);
public:
explicit
ListSet(bslma::Allocator *allocator = 0)
: d_comparator()
, d_nodeList(0)
, d_allocator_p(bslma::Default::allocator(allocator))
{}
~ListSet()
{
for (Node *node = d_nodeList; node; ) {
Node *toDelete = node;
node = node->d_next;
d_allocator_p->deleteObject(toDelete);
}
}
bool insert(const TYPE& value)
{
if (count(value)) {
return false;
}
Node *node = (Node *) d_allocator_p->allocate(sizeof(Node));
bslma::ConstructionUtil::construct(&node->d_value,
d_allocator_p,
value);
node->d_next = d_nodeList;
d_nodeList = node;
return true;
}
int count(const TYPE& value) const
{
for (Node *node = d_nodeList; node; node = node->d_next) {
if (d_comparator(node->d_value, value)) {
return 1;
}
}
return 0;
}
};
Then, in main
, we declare an instance of ListSet
storing int
s. The default definition of bsl::equal_to
will work nicely: Now, we insert several values into our ListSet
. Note that successful insertions return true
while redundant ones return false
with no effect: assert(true == lsi.insert( 5));
assert(false == lsi.insert( 5));
assert(false == lsi.insert( 5));
assert(true == lsi.insert(11));
assert(true == lsi.insert(17));
assert(true == lsi.insert(81));
assert(true == lsi.insert(32));
assert(false == lsi.insert(17));
Finally, we observe that our count
method successfully distinguishes between values that have been stored in our ListSet
and those that haven't: assert(0 == lsi.count( 7));
assert(1 == lsi.count( 5));
assert(0 == lsi.count(13));
assert(1 == lsi.count(11));
assert(0 == lsi.count(33));
assert(1 == lsi.count(32));
-
- Example 2: Using Our List Set For a Custom Type:
- Suppose we want to have a list set containing objects of a custom type. We can declare an
operator==
for our custom type, and equal_to
will use that. We will re-use the ListSet
template class from example 1, and create a new custom type.
- First, we define a type
StringThing
, which will contain a const char *
pointer, it will be a very simple type, that is implicitly castable to or from a const char *
. class StringThing {
const char *d_string;
public:
StringThing(const char *string)
: d_string(string)
{}
operator const char *() const
{
return d_string;
}
};
Then, we create an operator==
for StringThings bool operator==(const StringThing& lhs, const StringThing& rhs)
{
return !strcmp(lhs, rhs);
}
Next, in main
, we declare a ListSet
containing StringThing
s: ListSet<StringThing> lsst;
Then, we insert a number of values, and observe that redundant inserts return false
with no effect: assert(true == lsst.insert("woof"));
assert(true == lsst.insert("meow"));
assert(true == lsst.insert("arf"));
assert(false == lsst.insert("woof"));
assert(true == lsst.insert("bark"));
assert(false == lsst.insert("meow"));
assert(false == lsst.insert("woof"));
Now, we observe that our count
method successfully distinguishes between values that have been stored in lsst
and those that haven't: assert(1 == lsst.count("meow"));
assert(0 == lsst.count("woo"));
assert(1 == lsst.count("woof"));
assert(1 == lsst.count("arf"));
assert(0 == lsst.count("chomp"));
Finally, we copy values into a buffer and observe that this makes no difference to count
s results: char buffer[10];
strcpy(buffer, "meow");
assert(1 == lsst.count(buffer));
strcpy(buffer, "bite");
assert(0 == lsst.count(buffer));
Typedef Documentation
template<class VALUE_TYPE = void>
typedef VALUE_TYPE bsl::equal_to< VALUE_TYPE >::second_argument_type [inherited] |
template<class VALUE_TYPE = void>
typedef bool bsl::equal_to< VALUE_TYPE >::result_type [inherited] |
Function Documentation
template<class VALUE_TYPE = void>
template<class VALUE_TYPE = void>
Create a equal_to
object. Note that as equal_to
is an empty (stateless) type, this operation will have no observable effect.
template<class VALUE_TYPE = void>
template<class VALUE_TYPE = void>
Assign to this object the value of the specified rhs
object, and a return a reference providing modifiable access to this object. Note that as equal_to
is an empty (stateless) type, this operation will have no observable effect.
template<class VALUE_TYPE = void>
BSLA_NODISCARD BSLS_KEYWORD_CONSTEXPR bool bsl::equal_to< VALUE_TYPE >::operator() |
( |
const VALUE_TYPE & |
lhs, |
|
|
const VALUE_TYPE & |
rhs | |
|
) |
| | const [inherited] |
Return true
if the specified lhs
compares equal to the specified rhs
using the equality-comparison operator, lhs == rhs
.
Create a equal_to
object. Note that as equal_to<void>
is an empty (stateless) type, this operation will have no observable effect.
Assign to this object the value of the specified rhs
object, and a return a reference providing modifiable access to this object. Note that as equal_to
is an empty (stateless) type, this operation will have no observable effect.
template<class TYPE1 , class TYPE2 >
bool bsl::equal_to< void >::operator() |
( |
const TYPE1 & |
lhs, |
|
|
const TYPE2 & |
rhs | |
|
) |
| | const [inline, inherited] |
< Return true
if the specified lhs
compares equal to the specified rhs
using the equality-comparison operator, lhs == rhs
. Implemented inline because of compiler errors (AIX, SUN).