Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bslalg_functoradapter
[Package bslalg]

Provide an utility that adapts callable objects to functors. More...

Namespaces

namespace  bslalg

Detailed Description

Outline
Purpose:
Provide an utility that adapts callable objects to functors.
Classes:
bslalg::FunctorAdapter utility for using callable objects as functors
See also:
Component bslstl_setcomparator, Component 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:
  template <class BINARY_PREDICATE>
  class Bind2ndInteger : private FunctorAdapter<BINARY_PREDICATE>::Type {
      // 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.

      // DATA
      int d_bondValue;  // the bound value

      // NOT IMPLEMENTED
      Bind2ndInteger(const Bind2ndInteger&);
      Bind2ndInteger& operator=(const Bind2ndInteger&);

    public:
      // CREATORS
      Bind2ndInteger(int value, const BINARY_PREDICATE& predicate);
          // Create a 'Bind2ndInteger' object that will bind the second
          // parameter of the specified 'predicate' with the specified
          // integer 'value'.

      // ~Bind2ndInteger() = default;
          // Destroy this object.

      // ACCESSORS
      bool operator() (const int value) const;
          // 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.
  };
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));