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

Classes

class  bdef_Function< PROTOTYPE >
 

Functions

 bslstl::Function_Variadic< RET(ARGS...)>::Function_Variadic (const allocator_type &allocator)
 
RET bslstl::Function_Variadic< RET(ARGS...)>::operator() (ARGS... args) const
 
 bsl::function< PROTOTYPE >::function () BSLS_KEYWORD_NOEXCEPT
 
 bsl::function< PROTOTYPE >::function (nullptr_t) BSLS_KEYWORD_NOEXCEPT
 
 bsl::function< PROTOTYPE >::function (allocator_arg_t, const allocator_type &allocator) BSLS_KEYWORD_NOEXCEPT
 
 bsl::function< PROTOTYPE >::function (allocator_arg_t, const allocator_type &allocator, nullptr_t) BSLS_KEYWORD_NOEXCEPT
 
 bsl::function< PROTOTYPE >::function (const function &original)
 
 bsl::function< PROTOTYPE >::function (allocator_arg_t, const allocator_type &allocator, const function &original)
 
 bsl::function< PROTOTYPE >::function (BloombergLP::bslmf::MovableRef< function > original) BSLS_KEYWORD_NOEXCEPT
 
 bsl::function< PROTOTYPE >::function (allocator_arg_t, const allocator_type &allocator, BloombergLP::bslmf::MovableRef< function > original)
 
functionbsl::function< PROTOTYPE >::operator= (const function &rhs)
 
functionbsl::function< PROTOTYPE >::operator= (BloombergLP::bslmf::MovableRef< function > rhs)
 
functionbsl::function< PROTOTYPE >::operator= (nullptr_t) BSLS_KEYWORD_NOEXCEPT
 Set this object to empty and return *this.
 
void bsl::function< PROTOTYPE >::swap (function &other) BSLS_KEYWORD_NOEXCEPT
 
template<class TP >
TP * bsl::function< PROTOTYPE >::target () BSLS_KEYWORD_NOEXCEPT
 
allocator_type bsl::function< PROTOTYPE >::get_allocator () const BSLS_KEYWORD_NOEXCEPT
 
template<class TP >
const TP * bsl::function< PROTOTYPE >::target () const BSLS_KEYWORD_NOEXCEPT
 
const std::type_info & bsl::function< PROTOTYPE >::target_type () const BSLS_KEYWORD_NOEXCEPT
 
 bsl::function< PROTOTYPE >::operator BloombergLP::bdef_Function< PROTOTYPE * > & () BSLS_KEYWORD_NOEXCEPT
 
 bsl::function< PROTOTYPE >::operator const BloombergLP::bdef_Function< PROTOTYPE * > & () const BSLS_KEYWORD_NOEXCEPT
 
BloombergLP::bslma::Allocator * bsl::function< PROTOTYPE >::allocator () const BSLS_KEYWORD_NOEXCEPT
 
bool bsl::function< PROTOTYPE >::isInplace () const BSLS_KEYWORD_NOEXCEPT
 

Detailed Description

Outline

Purpose

Provide a polymorphic function object with a specific prototype.

Classes

Canonical header: bsl_functional.h

Description

This component provides a single class template, bsl::function, implementing the standard template std::function, a runtime-polymorphic wrapper that encapsulates an arbitrary callable object (the target) and allows the wrapped object to be invoked. bsl::function extends std::function by adding allocator support in a manner consistent with standards proposal P0987 (http://wg21.link/P0987).

Objects of type bsl::function generalize the notion of function pointers and are generally used to pass callbacks to a non-template function or class. For example, bsl::function<RET (ARG1, ARG2, ...)> can be used similarly to RET (*)(ARG1, ARG2, ...) but, unlike the function pointer, the bsl::function can hold a non-function callable type such as pointer to member function, pointer to member data, lambda expression, or functor (class type having an operator()). A bsl::function can also be "empty", i.e., having no target object. In a bool context, a bsl::function object will evaluate to false if it is empty, and true otherwise. The target type is determined at runtime using type erasure in the constructors and can be changed by means of assignment, but the function prototype (argument types and return type) is specified as a template parameter at compile time.

An instantiation of bsl::function is an in-core value-semantic type whose salient attributes are the type and value of its target, if any. The bsl::function owns the target object and manages its lifetime; copying or moving the bsl::function object copies or moves the target and destroying the bsl::function destroys the target. Somewhat counter-intuitively, the target is always mutable within the bsl::function; when wrapping a class type, calling a bsl::function can modify its target object, even if the bsl::function itself is const-qualified.

Although, as a value-semantic type, bsl::function does have an abstract notion of "value", there is no general equality operator comparing between two bsl::function objects. This limitation is a consequence of the target type not being required to provide equality comparison operators. The operator== overloads that are provided compare a bsl::function against the null pointer and do not satisfy the requirements we typically expect for value-semantic equality operators.

Invocation

Calling an empty bsl::function object will cause it to throw a bsl::bad_function_call exception. Given a non-empty object of type bsl::function<RET(ARG0, ARG1, ...)> invoked with arguments arg0, arg1, ..., invocation of the target follows the definition of INVOKE in section [func.require] of the C++ standard. These rules are summarized in the following table:

+----------------------------+-----------------------+
| Type of target object, 'f' | Invocation expression |
+============================+=======================+
| Functor, function, or | f(arg0, arg1, ...) |
| pointer to function | |
+----------------------------+-----------------------+
| Pointer to member function | (arg0X.*f)(arg1, ...) |
+----------------------------+-----------------------+
| Pointer to member data | arg0X.*f |
+----------------------------+-----------------------+

The arguments to f must be implicitly convertible from the corresponding argument types ARG0, ARG1, ... and the return value of the call expression must be implicitly convertible to RET, unless RET is void.

In the case of a pointer to member function, R (T::*f)(...), or pointer to data member R T::*f, arg0X is one of the following:

Note that, consistent with the C++ Standard definition of INVOKE, we consider pointer-to-member-function and pointer-to-member-data types to be "callable" even though, strictly speaking, they cannot be called directly due to the lack of an operator().

Allocator Usage

The C++11 standard specified a type erasure scheme for allocator support in std::function. This specification was never implemented by any vendor or popular open-source standard library and allocator support was removed from the 2017 standard version of std::function. A new design for allocator support using std::pmr::polymorphic_allocator instead of type erasure is currently part of version 3 of the Library Fundamentals Technical Specification (LFTS 3), after acceptance of paper P0987 (http://wg21.link/P0987). This component follows the P0987 specification, substituting bsl::allocator for std::pmr::polymorphic_allocator.

bsl::function meets the requirements for an allocator-aware type. Specifically:

There are two uses for the allocator in bsl::function:

  1. To allocate storage for holding the target object.
  2. To pass to the constructor of the wrapped object if the wrapped object is allocator aware.

Small-object Optimization

A bsl::function class has a buffer capable of holding a small callable object without allocating dynamic memory. The buffer is guaranteed to be large enough to hold a pointer to function, pointer to member function, pointer to member data, a bsl::reference_wrapper, or a stateless functor. In practice, it is large enough to hold many stateful functors up to six times the size of a void *. Note that, even if the target object is stored in the small object buffer, memory might still be allocated by the target object itself.

There are only two circumstances under which bsl::function will store the target object in allocated memory:

  1. If the object is too large to fit into the small object buffer
  2. If the object has a move constructor that might throw an exception

The second restriction allows the move constructor and swap operation on bsl::function to be noexcept, as required by the C++ Standard.

Usage

In this section we show intended use of this component.

Example 1: Polymorphic Invocation

In this example, we create a single bsl::function object, then assign it to callable objects of different types at run time.

First, we define a simple function that returns the XOR of its two integer arguments:

int intXor(int a, int b) { return a ^ b; }

Next, we create a bsl::function that takes two integers and returns an integer. Because we have not initialized the object with a target, it starts out as empty and evaluates to false in a Boolean context:

void main()
{
bsl::function<int(int, int)> funcObject;
assert(! funcObject);
Forward declaration.
Definition bslstl_function.h:934

Next, we use assignment to give it the value of (a pointer to) intXor and test that we can invoke it to get the expected result:

funcObject = intXor;
assert(funcObject);
assert(5 == funcObject(6, 3));

Next, we assign an instance of std::plus<int> functor to funcObject, which then holds a copy of it, and again test that we get the expected result when we invoke funcObject.

funcObject = std::plus<int>();
assert(funcObject);
assert(9 == funcObject(6, 3));

Then, if we are using C++11 or later, we assign it to a lambda expression that multiplies its arguments:

#if BSLS_COMPILERFEATURES_CPLUSPLUS >= 201103L
funcObject = [](int a, int b) { return a * b; };
assert(funcObject);
assert(18 == funcObject(6, 3));
#endif

Finally, we assign funcObject to nullptr, which makes it empty again:

funcObject = bsl::nullptr_t();
assert(! funcObject);
}
BloombergLP::bsls::Nullptr_Impl::Type nullptr_t
Definition bsls_nullptr.h:281

Example 2: Use in a Generic Algorithm

Suppose we want to define an algorithm that performs a mutating operation on every element of an array of integers. The inputs are pointers to the first and last element to transform, a pointer to the first element into which the to write the output, and an operation that takes an integer in and produces an integer return value. Although the pointer arguments have known type (int *), the type of the transformation operation can be anything that can be called with an integral argument and produces an integral return value. We do not want to accept this operation as a template argument, however (perhaps because our algorithm is sufficiently complex and/or proprietary that we want to keep it out of header files). We solve these disparate requirements by passing the operation as a bsl::function object, whose type is known at compile time but which can be set to an arbitrary operation at run time:

/// Apply my special algorithm to the elements in the contiguous address
/// range from the specified `begin` pointer up to but not including the
/// specified `end` pointer, writing the result to the contiguous range
/// starting at the specified `output` pointer. The specified `op`
/// function is applied to each element before it is fed into the
/// algorithm.
void myAlgorithm(const int *begin,
const int *end,
int *output,
const bsl::function<int(int)>& op);

For the purpose of illustration, myAlgorithm is a simple loop that invokes the specified op on each element in the input range and writes it directly to the output:

void myAlgorithm(const int *begin,
const int *end,
int *output,
const bsl::function<int(int)>& op)
{
for (; begin != end; ++begin) {
*output++ = op(*begin);
}
}

Next, we define input and output arrays to be used throughout the rest of this example:

static const std::size_t DATA_SIZE = 5;
static const int testInput[DATA_SIZE] = { 4, 3, -2, 9, -7 };
static int testOutput[DATA_SIZE];

Next, we define a function that simply negates its argument:

long negate(long v) { return -v; }
// Return the arithmetic negation of the specified 'v' integer.

Then, we test our algorithm using our negation function:

/// Test the use of the `negation` function with `myAlgorithm`.
bool testNegation()
{
myAlgorithm(testInput, testInput + DATA_SIZE, testOutput, negate);
for (std::size_t i = 0; i < DATA_SIZE; ++i) {
if (-testInput[i] != testOutput[i]) {
return false; // RETURN
}
}
return true;
}

Note that the prototype for negate is not identical to the prototype used to instantiate the op argument in myAlgorithm. All that is required is that each argument to op be convertible to the corresponding argument in the function and that the return type of the function be convertible to the return type of op.

Next, we get a bit more sophisticated and define an operation that produces a running sum over its inputs. A running sum requires holding on to state, so we define a functor class for this purpose:

/// Keep a running total of all of the inputs provided to `operator()`.
class RunningSum {
// DATA
int d_sum;
public:
// CREATORS
// Create a `RunningSum` with initial value set to the specified
// `initial` argument.
explicit RunningSum(int initial = 0) : d_sum(initial) { }
// MANIPULATORS
// Add the specified `v` to the running sum and return the running
// sum.
int operator()(int v)
{ return d_sum += v; }
};

Then, we test myAlgorithm with RunningSum:

/// Test the user of `RunningSum` with `myAlgorithm`.
bool testRunningSum()
{
myAlgorithm(testInput, testInput+DATA_SIZE, testOutput, RunningSum());
int sum = 0;
for (std::size_t i = 0; i < DATA_SIZE; ++i) {
sum += testInput[i];
if (sum != testOutput[i]) {
return false; // RETURN
}
}
return true;
}

Note that RunningSum::operator() is a mutating operation and that, within myAlgorithm, op is const. Even though bsl::function owns a copy of its target, logical constness does not apply, as per the standard.

Finally, we run our tests and validate the results:

void main()
{
assert(testNegation());
assert(testRunningSum());
}

Example 3: A Parallel Work queue

In this example, we'll simulate a simple library whereby worker threads take work items from a queue and execute them asynchronously. This simulation is single-threaded, but keeps metrics on how much work each worker accomplished so that we can get a rough idea of how much parallelism was expressed by the program.

We start by defining a work item type to be stored in our work queue. This type is simply a bsl::function taking a WorkQueue pointer argument and returning void.

class WorkQueue; // Forward declaration
typedef bsl::function<void(WorkQueue *)> WorkItem;

Next, we define a work queue class. For simplicity, we'll implement our queue as a fixed-sized circular buffer and (because this is a single-threaded simulation), ignore synchronization concerns.

/// A FIFO queue of tasks to be executed.
class WorkQueue {
// PRIVATE CONSTANTS
static const int k_MAX_ITEMS = 16;
// DATA
int d_numItems;
int d_head;
WorkItem d_items[k_MAX_ITEMS];
public:
// CREATORS
/// Create an empty work queue.
WorkQueue()
: d_numItems(0), d_head(0) { }
// MANIPULATORS
/// Move the work item at the head of the queue into the specified
/// `result` and remove it from the queue. The behavior is
/// undefined if this queue is empty.
void dequeue(WorkItem *result)
{
assert(d_numItems > 0);
*result = bslmf::MovableRefUtil::move(d_items[d_head]);
d_head = (d_head + 1) % k_MAX_ITEMS; // circular
--d_numItems;
}
/// Enqueue the specified `item` work item onto the tail of the
/// queue. The work is moved from `item`.
void enqueue(bslmf::MovableRef<WorkItem> item)
{
int tail = (d_head + d_numItems++) % k_MAX_ITEMS; // circular
assert(d_numItems <= k_MAX_ITEMS);
d_items[tail] = bslmf::MovableRefUtil::move(item);
}
// ACCESSORS
/// Return true if there are no items in the queue; otherwise return
/// false.
bool isEmpty() const { return 0 == d_numItems; }
/// Return the number of items currently in the queue.
int size() const { return d_numItems; }
};
Definition bslmf_movableref.h:751
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1060

Next, we'll create a worker class that represents the state of a worker thread:

/// A simulated worker thread.
class Worker {
// DATA
bool d_isIdle; // True if the worker is idle
public:
// CREATORS
/// Create an idle worker.
Worker()
: d_isIdle(true) { }
// MANIPULATORS
/// Dequeue a task from the specified `queue` and execute it
/// (asynchronously, in theory). The behavior is undefined unless
/// this worker is idle before the call to `run`.
void run(WorkQueue *queue);
// ACCESSORS
/// Return whether this worker is idle. An idle worker is one that
/// can except work.
bool isIdle() const { return d_isIdle; }
};

Next, we implement the run function, which removes a bsl::function object from the work queue and then executes it, passing the work queue as the sole argument:

void Worker::run(WorkQueue *queue)
{
if (queue->isEmpty()) {
// No work to do
return; // RETURN
}
WorkItem task;
queue->dequeue(&task);
d_isIdle = false; // We're about to do work.
task(queue); // Do the work.
d_isIdle = true; // We're idle again.
}

Now, we implement a simple scheduler containing a work queue and an array of four workers, which are run in a round-robin fashion:

/// Parallel work scheduler.
class Scheduler {
// PRIVATE CONSTANTS
static const int k_NUM_WORKERS = 4;
// DATA
WorkQueue d_workQueue;
Worker d_workers[k_NUM_WORKERS];
public:
// CREATORS
/// Create a scheduler and enqueue the specified `initialTask`.
explicit Scheduler(bslmf::MovableRef<WorkItem> initialTask)
{
d_workQueue.enqueue(bslmf::MovableRefUtil::move(initialTask));
}
// MANIPULATORS
/// Execute the tasks in the work queue (theoretically in parallel)
/// until the queue is empty.
void run();
};

Next, we implement the scheduler's run method: which does a round-robin scheduling of the workers, allowing each to pull work off of the queue and run it. As tasks are run, they may enqueue more work. The scheduler returns when there are no more tasks in the queue.

void Scheduler::run()
{
while (! d_workQueue.isEmpty()) {
for (int i = 0; i < k_NUM_WORKERS; ++i) {
if (d_workers[i].isIdle()) {
d_workers[i].run(&d_workQueue);
}
}
}
}

Next, we create a job for the parallel system to execute. A popular illustration of parallel execution is the quicksort algorithm, which is a recursive algorithm whereby the input array is partitioned into a low and high half and quicksort is recursively applied, in parallel, to the two halves. We define a class that encapsulates an invocation of quicksort on an input range:

/// A functor class to execute parallel quicksort on a contiguous range
/// of elements of specified `TYPE` supplied at construction.
template <class TYPE>
class QuickSortTask {
// DATA
TYPE *d_begin_p;
TYPE *d_end_p;
// PRIVATE CLASS METHODS
/// Partition the contiguous range specified by `[begin, end)` and
/// return an iterator, `mid`, such that every element in the range
/// `[begin, mid)` is less than `*mid` and every element in the
/// range `[mid + 1, end)` is not less than `*mid`. The behavior is
/// undefined unless `begin < end`.
static TYPE* partition(TYPE *begin, TYPE *end);
public:
// CREATORS
/// Create a task to sort the contiguous range from the item at the
/// specified `begin` location up to but not included the item at
/// the specified `end` location.
QuickSortTask(TYPE *begin, TYPE *end)
: d_begin_p(begin), d_end_p(end) { }
// MANIPULATORS
/// Preform the sort in parallel using the specified `queue` to
/// enqueue parallel work.
void operator()(WorkQueue *queue);
};

Next we implement the partition method, using a variation of the Lomuto partition scheme:

template <class TYPE>
TYPE* QuickSortTask<TYPE>::partition(TYPE *begin, TYPE *end)
{
using std::swap;
swap(begin[(end - begin) / 2], end[-1]); // Put pivot at end
TYPE& pivot = *--end;
TYPE *divider = begin;
for (; begin != end; ++begin) {
if (*begin < pivot) {
swap(*divider, *begin);
++divider;
}
}
swap(*divider, pivot); // Put pivot in the middle
return divider;
}
void swap(OptionValue &a, OptionValue &b)
void swap(TYPE &a, TYPE &b)

Then we define the call operator for our task type, which performs the quicksort:

template <class TYPE>
void QuickSortTask<TYPE>::operator()(WorkQueue *queue)
{
if (d_end_p - d_begin_p < 2) {
// Zero or one element. End recursion.
return; // RETURN
}
// Partition returns end iterator for low partition == begin iterator
// for high partition.
TYPE *mid = partition(d_begin_p, d_end_p);
// Asynchronously sort the two partitions
WorkItem sortLoPart(QuickSortTask(d_begin_p, mid));
WorkItem sortHiPart(QuickSortTask(mid + 1, d_end_p));
queue->enqueue(bslmf::MovableRefUtil::move(sortLoPart));
queue->enqueue(bslmf::MovableRefUtil::move(sortHiPart));
}

Finally, we use our scheduler and our QuickSortTask to sort an array initially containing the integers between 1 and 31 in random order:

void main()
{
short data[] = {
23, 12, 2, 28, 1, 10, 5, 13, 15, 8, 19, 14, 31, 29, 9, 11, 24, 3,
30, 7, 17, 27, 20, 21, 18, 4, 22, 25, 16, 6, 26
};
static const int DATA_SIZE = sizeof(data) / sizeof(data[0]);
WorkItem initialTask(QuickSortTask<short>(data, data + DATA_SIZE));
Scheduler sched(bslmf::MovableRefUtil::move(initialTask));
sched.run();
// Validate results
for (int i = 0; i < DATA_SIZE; ++i) {
assert(i + 1 == data[i]);
}
}

Function Documentation

◆ allocator()

template<class PROTOTYPE >
BloombergLP::bslma::Allocator * bsl::function< PROTOTYPE >::allocator ( ) const
inline
Deprecated:
Use get_allocator() instead.

Return get_allocator().mechanism(). Note that this function exists for BDE compatibility and is not part of the C++ Standard Library.

◆ function() [1/8]

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::function ( )
inline

◆ function() [2/8]

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::function ( allocator_arg_t  ,
const allocator_type allocator 
)
inline

◆ function() [3/8]

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::function ( allocator_arg_t  ,
const allocator_type allocator,
BloombergLP::bslmf::MovableRef< function< PROTOTYPE > >  original 
)
inline

Create a function having the same value as (i.e., wrapping a copy of the target held by) the specified original object. Use the specified allocator (e.g., the address of a bslma::Allocator object) to supply memory. If allocator == original.allocator(), this object is created as if by move construction; otherwise it is created as if by extended copy construction using allocator.

◆ function() [4/8]

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::function ( allocator_arg_t  ,
const allocator_type allocator,
const function< PROTOTYPE > &  original 
)
inline

Create a function having the same value as (i.e., wrapping a copy of the target held by) the specified original object. Optionally specify an allocator (e.g., the address of a bslma::Allocator object) to supply memory; otherwise, the default allocator is used.

◆ function() [5/8]

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::function ( allocator_arg_t  ,
const allocator_type allocator,
nullptr_t   
)
inline

Create an empty function object. Optionally specify an allocator (e.g., the address of a bslma::Allocator object) to supply memory; otherwise, the default allocator is used.

◆ function() [6/8]

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::function ( BloombergLP::bslmf::MovableRef< function< PROTOTYPE > >  original)
inline

Create a function having the same target as the specified original object. Use original.get_allocator() as the allocator to supply memory. The original object is set to empty after the new object is created. If the target qualifies for the small-object optimization (see class-level documentation), then it is move-constructed into the new object; otherwise ownership of the target is transferred without using the target's move constructor.

◆ function() [7/8]

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::function ( const function< PROTOTYPE > &  original)
inline

◆ function() [8/8]

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::function ( nullptr_t  )
inline

◆ Function_Variadic()

template<class RET , class... ARGS>
bslstl::Function_Variadic< RET(ARGS...)>::Function_Variadic ( const allocator_type allocator)
inline

Create an empty object. Use the specified allocator (e.g., the address of a bslma::Allocator) to supply memory.

◆ get_allocator()

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::allocator_type bsl::function< PROTOTYPE >::get_allocator ( ) const
inline

Return (a copy of) the allocator used to supply memory for this function.

◆ isInplace()

template<class PROTOTYPE >
bool bsl::function< PROTOTYPE >::isInplace ( ) const
inline
Deprecated:
Runtime checking of this optimization is discouraged.

Return true if this function is empty or if it is non-empty and its target qualifies for the small-object optimization (and is thus allocated within this object's footprint); otherwise, return false.

◆ operator BloombergLP::bdef_Function< PROTOTYPE * > &()

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::operator BloombergLP::bdef_Function< PROTOTYPE * > & ( )
inline
Deprecated:
Use bsl::function` instead of `bdef_Function.

Return *this, converted to a mutable bdef_Function reference by downcasting. The behavior is undefined unless bdef_Function<F*> is derived from bsl::function<F> and adds no new data members.

◆ operator const BloombergLP::bdef_Function< PROTOTYPE * > &()

template<class PROTOTYPE >
bsl::function< PROTOTYPE >::operator const BloombergLP::bdef_Function< PROTOTYPE * > & ( ) const
inline
Deprecated:
Use bsl::function` instead of `bdef_Function.

Return *this converted to a const bdef_Function reference by downcasting. The behavior is undefined unless bdef_Function<F*> is derived from bsl::function<F> and adds no new data members.

◆ operator()()

template<class RET , class... ARGS>
RET bslstl::Function_Variadic< RET(ARGS...)>::operator() ( ARGS...  args) const
inline

If this object is empty, throw bsl::bad_function_call; otherwise invoke the target object with the specified args... and return the result (after conversion to RET). Note that, even though it is declared const, this call operator can mutate the target object and is thus considered a manipulator rather than an accessor.

◆ operator=() [1/3]

template<class PROTOTYPE >
bsl::function< PROTOTYPE > & bsl::function< PROTOTYPE >::operator= ( BloombergLP::bslmf::MovableRef< function< PROTOTYPE > >  rhs)
inline

Set the target of this object to the target (if any) held by the specified rhs object, destroy the target (if any) previously held by *this, and return *this. The result is equivalent to having constructed *this from rhs using the extended move constructor with allocator this->get_allocator(). If an exception is thrown, rhs will have a valid but unspecified value and *this will not be modified. Note that an exception will never be thrown if get_allocator() == rhs.get_allocator().

◆ operator=() [2/3]

template<class PROTOTYPE >
bsl::function< PROTOTYPE > & bsl::function< PROTOTYPE >::operator= ( const function< PROTOTYPE > &  rhs)
inline

Set the target of this object to a copy of the target (if any) held by the specified rhs object, destroy the target (if any) previously held by *this, and return *this. The result is equivalent to having constructed *this from rhs using the extended copy constructor with allocator this->get_allocator(). If an exception is thrown, *this is not modified (i.e., copy assignment provides the strong exception guarantee).

◆ operator=() [3/3]

template<class PROTOTYPE >
bsl::function< PROTOTYPE > & bsl::function< PROTOTYPE >::operator= ( nullptr_t  )
inline

◆ swap()

template<class PROTOTYPE >
void bsl::function< PROTOTYPE >::swap ( function< PROTOTYPE > &  other)
inline

Exchange the targets held by this function and the specified other function. The behavior is undefined unless get_allocator() == other.get_allocator().

◆ target() [1/2]

template<class PROTOTYPE >
template<class TP >
TP * bsl::function< PROTOTYPE >::target ( )
inline

If TP is the same type as the target object, returns a pointer granting modifiable access to the target; otherwise return a null pointer.

◆ target() [2/2]

template<class PROTOTYPE >
template<class TP >
const TP * bsl::function< PROTOTYPE >::target ( ) const
inline

If TP is the same type as the target object, returns a pointer granting read-only access to the target; otherwise return a null pointer.

◆ target_type()

template<class PROTOTYPE >
const std::type_info & bsl::function< PROTOTYPE >::target_type ( ) const

Return typeid(void) if this object is empty; otherwise typeid(FUNC) where FUNC is the type of the target object.