Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdlb_functionoutputiterator
[Package bdlb]

Provides an output iterator for a client-supplied functor. More...

Namespaces

namespace  bdlb

Detailed Description

Outline
Purpose:
Provides an output iterator for a client-supplied functor.
Classes:
bdlb::FunctionOutputIterator function output iterator template
See also:
Component bdlb_nulloutputiterator
Description:
This component provides an iterator template mechanism, bdlb::FunctionOutputIterator, that adapts a client supplied functor (or function pointer) to a C++ compliant output iterator. This component allows clients to create custom output iterators easily.
A bdlb::FunctionOutputIterator instance's template parameter type FUNCTION must be a functor (or function) that can be called as if it has the following signature:
  void operator()(const TYPE&)'
where TYPE is the type of the object that will be assigned (by clients) to the dereferenced iterator. For example:
  void myFunction(const int& value) {};
  typedef void (*MyFunctionPtr)(const int&);
  typedef bdlb::FunctionOutputIterator<MyFunctionPtr> MyFunctionIterator;

  MyFunctionIterator it(&foo);
  *it = 5;                       // Calls 'myFunction(5)'!
Notice that assigning 5 to the dereferenced output iterator invokes the function with the value 5.
The provided output iterator has the following attributes:
  • Meets the requirements for an output iterator according to the C++ Standard (C++11, Section 24.2.4 [output.iterators]).
  • Dereferencing an iterator and assigning to the result leads to a call of the functional object owned by the iterator. The value assigned to the dereferenced iterator is passed to a call of the function or functor held by the iterator as a constant reference. In other words, the assignment *it = value is equivalent to function(value).
  • Incrementing an iterator is a no-op.
Usage:
This section illustrates intended use of this component.
Example 1: Adapting a Free-Function to an Output Iterator:
Suppose we want use a provided function foo, that prints integers in some predefined format, to print each unique element of an array. Instead of manually writing a loop and checking for duplicate elements, we would like to use a standard algorithm such as unique_copy. However, unique_copy takes in an output iterator instead of a free function. We can use bdlb::FunctionOutputIterator to adapt foo into an output iterator that is acceptable by unique_copy.
First, we define the type Function and a function of that type foo:
  typedef void (*Function)(const int&);

  void foo(const int& value)
  {
      bsl::cout << value << " ";
  }
Then, we define a data sequence to process:
  enum { NUM_VALUES_1 = 7 };
  const int array1[NUM_VALUES_1] = { 2, 3, 3, 5, 7, 11, 11 };
Next, we use bdlb::FunctionOutputIterator to wrap foo for use in the algorithm bsl::unqiue_copy:
  unique_copy(
      array1,
      array1 + NUM_VALUES,
      bdlb::FunctionOutputIterator<Function>(&foo));
Notice, that each time bsl::unique_copy copies an element from the supplied range and assigns it to the output iterator, the function foo is called for the element.
Finally, the resulting console output:
  2 3 5 7 11
Example 2: Adapting A Functor to An Output Iterator:
The following example demonstrates using a bdlb::FunctionOutputIterator with a user defined functor object. Consider the Accumulator class for accumulating integer values into a total. We want to adapt Accumulator for use with the algorithm bsl::unique_copy.
First, we define an Accumulator class that will total the values supplied to the increment method:
  class Accumulator {
      // This class provides a value accumulating functionality.

      // DATA
      int d_sum;
    public:
      // CREATORS
      Accumulator() : d_sum(0) {};

      // MANIPULATORS
      void increment(int value) { d_sum += value; };

      // ACCESSORS
      int total() const { return d_sum; }
  };
Next, we define a functor, AccumulatorFunctor, that adapts Accumulator to a function object:
  class AccumulatorFunctor {
      // This class implements a function object that invokes 'increment' in
      // response of calling operator()(int).

      // DATA
      Accumulator *d_accumulator_p;  // accumulator (held, not owned)

    public:
      // CREATORS
      explicit AccumulatorFunctor(Accumulator *accumulator)
     : d_accumulator_p(accumulator)
      {}

      // MANIPULATORS
      void operator()(int value) { d_accumulator_p->increment(value); };
  };
Then, we define data sequence to process:
  enum { NUM_VALUES_2 = 7 };
  const int   array2[NUM_VALUES_2] = { 2, 3, 3, 5, 7, 11, 11 };
Next, we create a bdlb::FunctionOutputIterator for AccumulatorFunctor and supply it to the bsl::unique_copy algorithm to accumulate a sequence of values:
  Accumulator accumulator;
  unique_copy(
      array2,
      array2 + NUM_VALUES_2,
      bdlb::FunctionOutputIterator<AccumulatorFunctor>(
          AccumulatorFunctor(&accumulator)));
Finally, we observe that accumulator holds the accumulated total of unique values in array:
  assert(28 == accumulator.total());