BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslalg_functoradapter

Detailed Description

Outline

Purpose

Provide an utility that adapts callable objects to functors.

Classes

See also
bslstl_setcomparator, bslstl_mapcomparator

Description

This component provides a single utility template, FunctorAdapter, that adapts a parameterized adaptee type, which can be any callable object type, to a target functor type. This adaptation enables a client to inherit from the target functor type even if the adaptee callable object type is a function pointer type. This is particularly useful if the client of the callable object type wants to take advantage of the empty-base optimization to avoid paying storage cost when the callable object type is a functor type with no data members.

FunctorAdapter defines an alias to the target functor type. If the adaptee type is a functor type, the target type is an alias to the adaptee type. If the adaptee type is a function pointer type, the target type is a functor type that delegates to a function referred to by a function pointer of the adaptee type.

Usage

This section illustrates the intended use of this component.

Example 1: Using function pointer base for an empty-base optimized class

Suppose that we wanted to define a binder that binds a binary predicate of a parameterized type to a value passed on construction. Also suppose that we wanted to use the empty-base optimization to avoid paying storage cost when the predicate type is a functor type with no data members. Unfortunately, the binary predicate type may be a function pointer type, which cannot serve as a base class. The solution is to have the binder inherit from FunctorAdapter::Type, which adapts a function pointer type to a functor type that is a suitable base class.

First, we define the class Bind2ndInteger, which inherits from FunctorAdapter::Type to take advantage of the empty-base optimization:

/// This class provides a functor that delegate its function-call
/// operator to the parameterized `BINARY_PREDICATE`, passing the user
/// supplied parameter as the first argument and the integer value
/// passed on construction as the second argument.
template <class BINARY_PREDICATE>
class Bind2ndInteger : private FunctorAdapter<BINARY_PREDICATE>::Type {
// DATA
int d_bondValue; // the bound value
// NOT IMPLEMENTED
Bind2ndInteger(const Bind2ndInteger&);
Bind2ndInteger& operator=(const Bind2ndInteger&);
public:
// CREATORS
/// Create a `Bind2ndInteger` object that will bind the second
/// parameter of the specified `predicate` with the specified
/// integer `value`.
Bind2ndInteger(int value, const BINARY_PREDICATE& predicate);
/// Destroy this object.
//! ~Bind2ndInteger() = default;
// ACCESSORS
/// Return the result of calling the parameterized
/// `BINARY_PREDICATE` passing the specified `value` as the first
/// argument and the integer value passed on construction as the
/// second argument.
bool operator() (const int value) const;
};

Then, we implement the methods of the Bind2ndInteger class:

template <class BINARY_PREDICATE>
Bind2ndInteger<BINARY_PREDICATE>::Bind2ndInteger(int value,
const BINARY_PREDICATE& predicate)
: FunctorAdapter<BINARY_PREDICATE>::Type(predicate), d_bondValue(value)
{
}

Here, we implement the operator() member function that simply delegates to BINARY_PREDICATE

template <class BINARY_PREDICATE>
bool Bind2ndInteger<BINARY_PREDICATE>::operator() (const int value) const
{
const BINARY_PREDICATE& predicate = *this;
return predicate(value, d_bondValue);
}

Next, we define a function, intCompareFunction, that compares two integers:

bool intCompareFunction(const int lhs, const int rhs)
{
return lhs < rhs;
}

Now, we define a Bind2ndInteger object functorLessThan10 using the std::less<int> functor as the parameterized BINARY_PREDICATE and invoke the function call operator:

Bind2ndInteger<std::less<int> > functorLessThan10(10, std::less<int>());
assert(functorLessThan10(1));
assert(!functorLessThan10(12));

Finally, we define a Bind2ndInteger object functionLessThan10 passing the address of intCompareFunction on construction and invoke the function call operator:

Bind2ndInteger<bool (*)(const int, const int)>
functionLessThan10(10, &intCompareFunction);
assert(functionLessThan10(1));
assert(!functionLessThan10(12));