BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_function.h
Go to the documentation of this file.
1/// @file bslstl_function.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_function.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_FUNCTION
9#define INCLUDED_BSLSTL_FUNCTION
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_function bslstl_function
15/// @brief Provide a polymorphic function object with a specific prototype.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_function
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_function-purpose"> Purpose</a>
25/// * <a href="#bslstl_function-classes"> Classes </a>
26/// * <a href="#bslstl_function-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_function-description"> Description </a>
28/// * <a href="#bslstl_function-invocation"> Invocation </a>
29/// * <a href="#bslstl_function-allocator-usage"> Allocator Usage </a>
30/// * <a href="#bslstl_function-small-object-optimization"> Small-object Optimization </a>
31/// * <a href="#bslstl_function-usage"> Usage </a>
32/// * <a href="#bslstl_function-example-1-polymorphic-invocation"> Example 1: Polymorphic Invocation </a>
33/// * <a href="#bslstl_function-example-2-use-in-a-generic-algorithm"> Example 2: Use in a Generic Algorithm </a>
34/// * <a href="#bslstl_function-example-3-a-parallel-work-queue"> Example 3: A Parallel Work queue </a>
35///
36/// # Purpose {#bslstl_function-purpose}
37/// Provide a polymorphic function object with a specific prototype.
38///
39/// # Classes {#bslstl_function-classes}
40///
41/// - bsl::function: polymorphic function object with a specific prototype.
42///
43/// # Canonical Header {#bslstl_function-canonical-header}
44/// bsl_functional.h
45///
46/// # Description {#bslstl_function-description}
47/// This component provides a single class template,
48/// `bsl::function`, implementing the standard template `std::function`, a
49/// runtime-polymorphic wrapper that encapsulates an arbitrary callable object
50/// (the *target*) and allows the wrapped object to be invoked. `bsl::function`
51/// extends `std::function` by adding allocator support in a manner consistent
52/// with standards proposal P0987 (http://wg21.link/P0987).
53///
54/// Objects of type `bsl::function` generalize the notion of function pointers
55/// and are generally used to pass callbacks to a non-template function or
56/// class. For example, `bsl::function<RET (ARG1, ARG2, ...)>` can be used
57/// similarly to `RET (*)(ARG1, ARG2, ...)` but, unlike the function pointer,
58/// the `bsl::function` can hold a non-function callable type such as pointer to
59/// member function, pointer to member data, lambda expression, or functor
60/// (class type having an `operator()`). A `bsl::function` can also be "empty",
61/// i.e., having no target object. In a `bool` context, a `bsl::function`
62/// object will evaluate to false if it is empty, and true otherwise. The
63/// target type is determined at runtime using *type* *erasure* in the
64/// constructors and can be changed by means of assignment, but the function
65/// prototype (argument types and return type) is specified as a template
66/// parameter at compile time.
67///
68/// An instantiation of `bsl::function` is an in-core value-semantic type whose
69/// salient attributes are the type and value of its target, if any. The
70/// `bsl::function` owns the target object and manages its lifetime; copying or
71/// moving the `bsl::function` object copies or moves the target and destroying
72/// the `bsl::function` destroys the target. Somewhat counter-intuitively, the
73/// target is always mutable within the `bsl::function`; when wrapping a class
74/// type, calling a `bsl::function` can modify its target object, even if the
75/// `bsl::function` itself is const-qualified.
76///
77/// Although, as a value-semantic type, `bsl::function` does have an abstract
78/// notion of "value", there is no general equality operator comparing between
79/// two `bsl::function` objects. This limitation is a consequence of the target
80/// type not being required to provide equality comparison operators. The
81/// `operator==` overloads that *are* provided compare a `bsl::function` against
82/// the null pointer and do not satisfy the requirements we typically expect for
83/// value-semantic equality operators.
84///
85/// ## Invocation {#bslstl_function-invocation}
86///
87///
88/// Calling an empty `bsl::function` object will cause it to throw a
89/// `bsl::bad_function_call` exception. Given a non-empty object of type
90/// `bsl::function<RET(ARG0, ARG1, ...)>` invoked with arguments `arg0`, `arg1`,
91/// ..., invocation of the target follows the definition of *INVOKE* in section
92/// [func.require] of the C++ standard. These rules are summarized in the
93/// following table:
94/// @code
95/// +----------------------------+-----------------------+
96/// | Type of target object, 'f' | Invocation expression |
97/// +============================+=======================+
98/// | Functor, function, or | f(arg0, arg1, ...) |
99/// | pointer to function | |
100/// +----------------------------+-----------------------+
101/// | Pointer to member function | (arg0X.*f)(arg1, ...) |
102/// +----------------------------+-----------------------+
103/// | Pointer to member data | arg0X.*f |
104/// +----------------------------+-----------------------+
105/// @endcode
106/// The arguments to `f` must be implicitly convertible from the corresponding
107/// argument types `ARG0`, `ARG1`, ... and the return value of the call
108/// expression must be implicitly convertible to `RET`, unless `RET` is `void`.
109///
110/// In the case of a pointer to member function, `R (T::*f)(...)`, or pointer to
111/// data member `R T::*f`, `arg0X` is one of the following:
112///
113/// * `arg0` if `ARG0` is `T` or derived from `T`
114/// * `arg0.get()` if `ARG0` is a specialization of @ref reference_wrapper
115/// * `(*arg0)` if `ARG0` is a pointer type or pointer-like type (e.g., a smart
116/// pointer).
117///
118/// Note that, consistent with the C++ Standard definition of *INVOKE*, we
119/// consider pointer-to-member-function and pointer-to-member-data types to be
120/// "callable" even though, strictly speaking, they cannot be called directly
121/// due to the lack of an `operator()`.
122///
123/// ## Allocator Usage {#bslstl_function-allocator-usage}
124///
125///
126/// The C++11 standard specified a type erasure scheme for allocator support in
127/// `std::function`. This specification was never implemented by any vendor or
128/// popular open-source standard library and allocator support was removed from
129/// the 2017 standard version of `std::function`. A new design for
130/// allocator support using `std::pmr::polymorphic_allocator` instead of type
131/// erasure is currently part of version 3 of the Library Fundamentals Technical
132/// Specification (LFTS 3), after acceptance of paper P0987
133/// (http://wg21.link/P0987). This component follows the P0987 specification,
134/// substituting `bsl::allocator` for `std::pmr::polymorphic_allocator`.
135///
136/// `bsl::function` meets the requirements for an allocator-aware type.
137/// Specifically:
138///
139/// * The type `allocator_type` is an alias for `bsl::allocator<char>`,
140/// * Every constructor can be invoked with an allocator argument, using the
141/// `bsl::allocator_arg_t` leading-allocator argument convention.
142/// * `get_allocator()` returns the allocator specified at construction.
143///
144/// There are two uses for the allocator in `bsl::function`:
145///
146/// 1. To allocate storage for holding the target object.
147/// 2. To pass to the constructor of the wrapped object if the wrapped object is
148/// allocator aware.
149///
150/// ## Small-object Optimization {#bslstl_function-small-object-optimization}
151///
152///
153/// A `bsl::function` class has a buffer capable of holding a small callable
154/// object without allocating dynamic memory. The buffer is guaranteed to be
155/// large enough to hold a pointer to function, pointer to member function,
156/// pointer to member data, a `bsl::reference_wrapper`, or a stateless functor.
157/// In practice, it is large enough to hold many stateful functors up to six
158/// times the size of a `void *`. Note that, even if the target object is
159/// stored in the small object buffer, memory might still be allocated by the
160/// target object itself.
161///
162/// There are only two circumstances under which `bsl::function` will store the
163/// target object in allocated memory:
164///
165/// 1. If the object is too large to fit into the small object buffer
166/// 2. If the object has a move constructor that might throw an exception
167///
168/// The second restriction allows the move constructor and swap operation on
169/// `bsl::function` to be `noexcept`, as required by the C++ Standard.
170///
171/// ## Usage {#bslstl_function-usage}
172///
173///
174/// In this section we show intended use of this component.
175///
176/// ### Example 1: Polymorphic Invocation {#bslstl_function-example-1-polymorphic-invocation}
177///
178///
179/// In this example, we create a single `bsl::function` object, then assign it
180/// to callable objects of different types at run time.
181///
182/// First, we define a simple function that returns the XOR of its two integer
183/// arguments:
184/// @code
185/// int intXor(int a, int b) { return a ^ b; }
186/// @endcode
187/// Next, we create a `bsl::function` that takes two integers and returns an
188/// integer. Because we have not initialized the object with a target, it
189/// starts out as empty and evaluates to false in a Boolean context:
190/// @code
191/// void main()
192/// {
193/// bsl::function<int(int, int)> funcObject;
194/// assert(! funcObject);
195/// @endcode
196/// Next, we use assignment to give it the value of (a pointer to) `intXor` and
197/// test that we can invoke it to get the expected result:
198/// @code
199/// funcObject = intXor;
200/// assert(funcObject);
201/// assert(5 == funcObject(6, 3));
202/// @endcode
203/// Next, we assign an instance of `std::plus<int>` functor to `funcObject`,
204/// which then holds a copy of it, and again test that we get the expected
205/// result when we invoke `funcObject`.
206/// @code
207/// funcObject = std::plus<int>();
208/// assert(funcObject);
209/// assert(9 == funcObject(6, 3));
210/// @endcode
211/// Then, if we are using C++11 or later, we assign it to a lambda expression
212/// that multiplies its arguments:
213/// @code
214/// #if BSLS_COMPILERFEATURES_CPLUSPLUS >= 201103L
215/// funcObject = [](int a, int b) { return a * b; };
216/// assert(funcObject);
217/// assert(18 == funcObject(6, 3));
218/// #endif
219/// @endcode
220/// Finally, we assign `funcObject` to `nullptr`, which makes it empty again:
221/// @code
222/// funcObject = bsl::nullptr_t();
223/// assert(! funcObject);
224/// }
225/// @endcode
226///
227/// ### Example 2: Use in a Generic Algorithm {#bslstl_function-example-2-use-in-a-generic-algorithm}
228///
229///
230/// Suppose we want to define an algorithm that performs a mutating operation on
231/// every element of an array of integers. The inputs are pointers to the first
232/// and last element to transform, a pointer to the first element into which the
233/// to write the output, and an operation that takes an integer in and produces
234/// an integer return value. Although the pointer arguments have known type
235/// (`int *`), the type of the transformation operation can be anything that can
236/// be called with an integral argument and produces an integral return value.
237/// We do not want to accept this operation as a template argument, however
238/// (perhaps because our algorithm is sufficiently complex and/or proprietary
239/// that we want to keep it out of header files). We solve these disparate
240/// requirements by passing the operation as a `bsl::function` object, whose
241/// type is known at compile time but which can be set to an arbitrary
242/// operation at run time:
243/// @code
244/// /// Apply my special algorithm to the elements in the contiguous address
245/// /// range from the specified `begin` pointer up to but not including the
246/// /// specified `end` pointer, writing the result to the contiguous range
247/// /// starting at the specified `output` pointer. The specified `op`
248/// /// function is applied to each element before it is fed into the
249/// /// algorithm.
250/// void myAlgorithm(const int *begin,
251/// const int *end,
252/// int *output,
253/// const bsl::function<int(int)>& op);
254/// @endcode
255/// For the purpose of illustration, `myAlgorithm` is a simple loop that
256/// invokes the specified `op` on each element in the input range and writes it
257/// directly to the output:
258/// @code
259/// void myAlgorithm(const int *begin,
260/// const int *end,
261/// int *output,
262/// const bsl::function<int(int)>& op)
263/// {
264/// for (; begin != end; ++begin) {
265/// *output++ = op(*begin);
266/// }
267/// }
268/// @endcode
269/// Next, we define input and output arrays to be used throughout the rest of
270/// this example:
271/// @code
272/// static const std::size_t DATA_SIZE = 5;
273/// static const int testInput[DATA_SIZE] = { 4, 3, -2, 9, -7 };
274/// static int testOutput[DATA_SIZE];
275/// @endcode
276/// Next, we define a function that simply negates its argument:
277/// @code
278/// long negate(long v) { return -v; }
279/// // Return the arithmetic negation of the specified 'v' integer.
280/// @endcode
281/// Then, we test our algorithm using our negation function:
282/// @code
283/// /// Test the use of the `negation` function with `myAlgorithm`.
284/// bool testNegation()
285/// {
286/// myAlgorithm(testInput, testInput + DATA_SIZE, testOutput, negate);
287///
288/// for (std::size_t i = 0; i < DATA_SIZE; ++i) {
289/// if (-testInput[i] != testOutput[i]) {
290/// return false; // RETURN
291/// }
292/// }
293/// return true;
294/// }
295/// @endcode
296/// Note that the prototype for `negate` is not identical to the prototype used
297/// to instantiate the `op` argument in `myAlgorithm`. All that is required is
298/// that each argument to `op` be convertible to the corresponding argument in
299/// the function and that the return type of the function be convertible to the
300/// return type of `op`.
301///
302/// Next, we get a bit more sophisticated and define an operation that produces
303/// a running sum over its inputs. A running sum requires holding on to state,
304/// so we define a functor class for this purpose:
305/// @code
306/// /// Keep a running total of all of the inputs provided to `operator()`.
307/// class RunningSum {
308///
309/// // DATA
310/// int d_sum;
311///
312/// public:
313/// // CREATORS
314///
315/// // Create a `RunningSum` with initial value set to the specified
316/// // `initial` argument.
317/// explicit RunningSum(int initial = 0) : d_sum(initial) { }
318///
319/// // MANIPULATORS
320///
321/// // Add the specified `v` to the running sum and return the running
322/// // sum.
323/// int operator()(int v)
324/// { return d_sum += v; }
325/// };
326/// @endcode
327/// Then, we test `myAlgorithm` with `RunningSum`:
328/// @code
329/// /// Test the user of `RunningSum` with `myAlgorithm`.
330/// bool testRunningSum()
331/// {
332/// myAlgorithm(testInput, testInput+DATA_SIZE, testOutput, RunningSum());
333///
334/// int sum = 0;
335/// for (std::size_t i = 0; i < DATA_SIZE; ++i) {
336/// sum += testInput[i];
337/// if (sum != testOutput[i]) {
338/// return false; // RETURN
339/// }
340/// }
341/// return true;
342/// }
343/// @endcode
344/// Note that `RunningSum::operator()` is a mutating operation and that, within
345/// `myAlgorithm`, `op` is const. Even though `bsl::function` owns a copy of
346/// its target, logical constness does not apply, as per the standard.
347///
348/// Finally, we run our tests and validate the results:
349/// @code
350/// void main()
351/// {
352/// assert(testNegation());
353/// assert(testRunningSum());
354/// }
355/// @endcode
356///
357/// ### Example 3: A Parallel Work queue {#bslstl_function-example-3-a-parallel-work-queue}
358///
359///
360/// In this example, we'll simulate a simple library whereby worker threads take
361/// work items from a queue and execute them asynchronously. This simulation is
362/// single-threaded, but keeps metrics on how much work each worker accomplished
363/// so that we can get a rough idea of how much parallelism was expressed by the
364/// program.
365///
366/// We start by defining a work item type to be stored in our work queue. This
367/// type is simply a `bsl::function` taking a `WorkQueue` pointer argument and
368/// returning `void`.
369/// @code
370/// class WorkQueue; // Forward declaration
371///
372/// typedef bsl::function<void(WorkQueue *)> WorkItem;
373/// @endcode
374/// Next, we define a work queue class. For simplicity, we'll implement our
375/// queue as a fixed-sized circular buffer and (because this is a
376/// single-threaded simulation), ignore synchronization concerns.
377/// @code
378/// /// A FIFO queue of tasks to be executed.
379/// class WorkQueue {
380///
381/// // PRIVATE CONSTANTS
382/// static const int k_MAX_ITEMS = 16;
383///
384/// // DATA
385/// int d_numItems;
386/// int d_head;
387/// WorkItem d_items[k_MAX_ITEMS];
388///
389/// public:
390/// // CREATORS
391///
392/// /// Create an empty work queue.
393/// WorkQueue()
394/// : d_numItems(0), d_head(0) { }
395///
396/// // MANIPULATORS
397///
398/// /// Move the work item at the head of the queue into the specified
399/// /// `result` and remove it from the queue. The behavior is
400/// /// undefined if this queue is empty.
401/// void dequeue(WorkItem *result)
402/// {
403/// assert(d_numItems > 0);
404/// *result = bslmf::MovableRefUtil::move(d_items[d_head]);
405/// d_head = (d_head + 1) % k_MAX_ITEMS; // circular
406/// --d_numItems;
407/// }
408///
409/// /// Enqueue the specified `item` work item onto the tail of the
410/// /// queue. The work is moved from `item`.
411/// void enqueue(bslmf::MovableRef<WorkItem> item)
412/// {
413/// int tail = (d_head + d_numItems++) % k_MAX_ITEMS; // circular
414/// assert(d_numItems <= k_MAX_ITEMS);
415/// d_items[tail] = bslmf::MovableRefUtil::move(item);
416/// }
417///
418/// // ACCESSORS
419///
420/// /// Return true if there are no items in the queue; otherwise return
421/// /// false.
422/// bool isEmpty() const { return 0 == d_numItems; }
423///
424/// /// Return the number of items currently in the queue.
425/// int size() const { return d_numItems; }
426/// };
427/// @endcode
428/// Next, we'll create a worker class that represents the state of a worker
429/// thread:
430/// @code
431/// /// A simulated worker thread.
432/// class Worker {
433///
434/// // DATA
435/// bool d_isIdle; // True if the worker is idle
436///
437/// public:
438/// // CREATORS
439///
440/// /// Create an idle worker.
441/// Worker()
442/// : d_isIdle(true) { }
443///
444/// // MANIPULATORS
445///
446/// /// Dequeue a task from the specified `queue` and execute it
447/// /// (asynchronously, in theory). The behavior is undefined unless
448/// /// this worker is idle before the call to `run`.
449/// void run(WorkQueue *queue);
450///
451/// // ACCESSORS
452///
453/// /// Return whether this worker is idle. An idle worker is one that
454/// /// can except work.
455/// bool isIdle() const { return d_isIdle; }
456/// };
457/// @endcode
458/// Next, we implement the `run` function, which removes a `bsl::function`
459/// object from the work queue and then executes it, passing the work queue as
460/// the sole argument:
461/// @code
462/// void Worker::run(WorkQueue *queue)
463/// {
464/// if (queue->isEmpty()) {
465/// // No work to do
466/// return; // RETURN
467/// }
468///
469/// WorkItem task;
470/// queue->dequeue(&task);
471///
472/// d_isIdle = false; // We're about to do work.
473/// task(queue); // Do the work.
474/// d_isIdle = true; // We're idle again.
475/// }
476/// @endcode
477/// Now, we implement a simple scheduler containing a work queue and an array of
478/// four workers, which are run in a round-robin fashion:
479/// @code
480/// /// Parallel work scheduler.
481/// class Scheduler {
482///
483/// // PRIVATE CONSTANTS
484/// static const int k_NUM_WORKERS = 4;
485///
486/// // DATA
487/// WorkQueue d_workQueue;
488/// Worker d_workers[k_NUM_WORKERS];
489///
490/// public:
491/// // CREATORS
492///
493/// /// Create a scheduler and enqueue the specified `initialTask`.
494/// explicit Scheduler(bslmf::MovableRef<WorkItem> initialTask)
495/// {
496/// d_workQueue.enqueue(bslmf::MovableRefUtil::move(initialTask));
497/// }
498///
499/// // MANIPULATORS
500///
501/// /// Execute the tasks in the work queue (theoretically in parallel)
502/// /// until the queue is empty.
503/// void run();
504/// };
505/// @endcode
506/// Next, we implement the scheduler's `run` method: which does a round-robin
507/// scheduling of the workers, allowing each to pull work off of the queue and
508/// run it. As tasks are run, they may enqueue more work. The scheduler
509/// returns when there are no more tasks in the queue.
510/// @code
511/// void Scheduler::run()
512/// {
513/// while (! d_workQueue.isEmpty()) {
514/// for (int i = 0; i < k_NUM_WORKERS; ++i) {
515/// if (d_workers[i].isIdle()) {
516/// d_workers[i].run(&d_workQueue);
517/// }
518/// }
519/// }
520/// }
521/// @endcode
522/// Next, we create a job for the parallel system to execute. A popular
523/// illustration of parallel execution is the quicksort algorithm, which is a
524/// recursive algorithm whereby the input array is partitioned into a low and
525/// high half and quicksort is recursively applied, in parallel, to the two
526/// halves. We define a class that encapsulates an invocation of quicksort on
527/// an input range:
528/// @code
529/// /// A functor class to execute parallel quicksort on a contiguous range
530/// /// of elements of specified `TYPE` supplied at construction.
531/// template <class TYPE>
532/// class QuickSortTask {
533///
534/// // DATA
535/// TYPE *d_begin_p;
536/// TYPE *d_end_p;
537///
538/// // PRIVATE CLASS METHODS
539///
540/// /// Partition the contiguous range specified by `[begin, end)` and
541/// /// return an iterator, `mid`, such that every element in the range
542/// /// `[begin, mid)` is less than `*mid` and every element in the
543/// /// range `[mid + 1, end)` is not less than `*mid`. The behavior is
544/// /// undefined unless `begin < end`.
545/// static TYPE* partition(TYPE *begin, TYPE *end);
546///
547/// public:
548/// // CREATORS
549///
550/// /// Create a task to sort the contiguous range from the item at the
551/// /// specified `begin` location up to but not included the item at
552/// /// the specified `end` location.
553/// QuickSortTask(TYPE *begin, TYPE *end)
554/// : d_begin_p(begin), d_end_p(end) { }
555///
556/// // MANIPULATORS
557///
558/// /// Preform the sort in parallel using the specified `queue` to
559/// /// enqueue parallel work.
560/// void operator()(WorkQueue *queue);
561/// };
562/// @endcode
563/// Next we implement the `partition` method, using a variation of the Lomuto
564/// partition scheme:
565/// @code
566/// template <class TYPE>
567/// TYPE* QuickSortTask<TYPE>::partition(TYPE *begin, TYPE *end)
568/// {
569/// using std::swap;
570///
571/// swap(begin[(end - begin) / 2], end[-1]); // Put pivot at end
572/// TYPE& pivot = *--end;
573/// TYPE *divider = begin;
574/// for (; begin != end; ++begin) {
575/// if (*begin < pivot) {
576/// swap(*divider, *begin);
577/// ++divider;
578/// }
579/// }
580/// swap(*divider, pivot); // Put pivot in the middle
581/// return divider;
582/// }
583/// @endcode
584/// Then we define the call operator for our task type, which performs the
585/// quicksort:
586/// @code
587/// template <class TYPE>
588/// void QuickSortTask<TYPE>::operator()(WorkQueue *queue)
589/// {
590/// if (d_end_p - d_begin_p < 2) {
591/// // Zero or one element. End recursion.
592/// return; // RETURN
593/// }
594///
595/// // Partition returns end iterator for low partition == begin iterator
596/// // for high partition.
597/// TYPE *mid = partition(d_begin_p, d_end_p);
598///
599/// // Asynchronously sort the two partitions
600/// WorkItem sortLoPart(QuickSortTask(d_begin_p, mid));
601/// WorkItem sortHiPart(QuickSortTask(mid + 1, d_end_p));
602/// queue->enqueue(bslmf::MovableRefUtil::move(sortLoPart));
603/// queue->enqueue(bslmf::MovableRefUtil::move(sortHiPart));
604/// }
605/// @endcode
606/// Finally, we use our scheduler and our `QuickSortTask` to sort an array
607/// initially containing the integers between 1 and 31 in random order:
608/// @code
609/// void main()
610/// {
611/// short data[] = {
612/// 23, 12, 2, 28, 1, 10, 5, 13, 15, 8, 19, 14, 31, 29, 9, 11, 24, 3,
613/// 30, 7, 17, 27, 20, 21, 18, 4, 22, 25, 16, 6, 26
614/// };
615///
616/// static const int DATA_SIZE = sizeof(data) / sizeof(data[0]);
617///
618/// WorkItem initialTask(QuickSortTask<short>(data, data + DATA_SIZE));
619/// Scheduler sched(bslmf::MovableRefUtil::move(initialTask));
620/// sched.run();
621///
622/// // Validate results
623/// for (int i = 0; i < DATA_SIZE; ++i) {
624/// assert(i + 1 == data[i]);
625/// }
626/// }
627/// @endcode
628/// @}
629/** @} */
630/** @} */
631
632/** @addtogroup bsl
633 * @{
634 */
635/** @addtogroup bslstl
636 * @{
637 */
638/** @addtogroup bslstl_function
639 * @{
640 */
641
642#include <bslscm_version.h>
643
644#include <bslma_allocator.h>
645#include <bslma_bslallocator.h>
647
648#include <bslmf_allocatorargt.h>
649#include <bslmf_assert.h>
650#include <bslmf_forwardingtype.h>
651#include <bslmf_isintegral.h>
652#include <bslmf_movableref.h>
655#include <bslmf_util.h> // 'forward(V)'
656
657#include <bsls_assert.h>
658#include <bsls_buildtarget.h>
661#include <bsls_exceptionutil.h>
662#include <bsls_keyword.h>
663#include <bsls_nullptr.h>
664#include <bsls_platform.h>
665#include <bsls_unspecifiedbool.h>
666#include <bsls_util.h> // 'forward<T>(V)'
667
668#ifdef BDE_BUILD_TARGET_EXC
670#endif
671#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
672#include <bslstl_pair.h>
673#endif
675
676// Sub-components:
677#ifdef BSLSTL_FUNCTION_VARIADIC_LIMIT
678#define BSLSTL_FUNCTION_INVOKERUTIL_VARIADIC_LIMIT \
679 BSLSTL_FUNCTION_VARIADIC_LIMIT
680#endif
683#include <bslstl_function_rep.h>
685
686#include <cstddef>
687#include <cstdlib>
688#include <typeinfo>
689#include <utility>
690
691#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
692#include <stdlib.h> // Import global-scope 'abs(double)'
693#endif
694
695#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
696// clang-format off
697// Include version that can be compiled with C++03
698// Generated on Mon Jan 13 08:31:39 2025
699// Command line: sim_cpp11_features.pl bslstl_function.h
700
701# define COMPILING_BSLSTL_FUNCTION_H
702# include <bslstl_function_cpp03.h>
703# undef COMPILING_BSLSTL_FUNCTION_H
704
705// clang-format on
706#else
707
708// 'BSLS_ASSERT' filename fix -- See @ref bsls_assertimputil
709#ifdef BSLS_ASSERTIMPUTIL_AVOID_STRING_CONSTANTS
710
711extern const char s_bslstl_function_h[];
712#undef BSLS_ASSERTIMPUTIL_FILE
713#define BSLS_ASSERTIMPUTIL_FILE BloombergLP::s_bslstl_function_h
714
715#endif
716
717// FORWARD DECLARATIONS
718namespace bsl {
719
720/// Forward declaration.
721template <class PROTOTYPE>
722class function;
723
724} // close namespace bsl
725
726
727
728#ifndef BDE_OMIT_INTERNAL_DEPRECATED
729
730/// Forward declaration of legacy `bdef_Function` in order to implement
731/// by-reference conversion from `bsl::function<F>`. This declaration
732/// produces a by-name cyclic dependency between `bsl` and `bde` in order to
733/// allow legacy code to transition to `bsl::function` from (the deprecated)
734/// `bdef_Function`. The conversion, and therefore this forward reference,
735/// should not appear in the open-source version of this component.
736template <class PROTOTYPE>
738
739#endif // BDE_OMIT_INTERNAL_DEPRECATED
740
741namespace bslstl {
742
743 // =================================
744 // struct template Function_ArgTypes
745 // =================================
746
747/// This component-private struct template provides the following nested
748/// typedefs for `bsl::function` for a specified `PROTOTYPE` which must be a
749/// function type:
750/// @code
751/// argument_type -- Only if PROTOTYPE takes exactly one argument
752/// first_argument_type -- Only if PROTOTYPE takes exactly two arguments
753/// second_argument_type -- Only if PROTOTYPE takes exactly two arguments
754/// @endcode
755/// The C++ Standard requires that `function` define these typedefs for
756/// compatibility with one- and two-argument legacy (now deprecated) functor
757/// adaptors. `bsl::function` publicly inherits from an instantiation of
758/// this template in order to conditionally declare the above nested types.
759/// This primary (unspecialized) template provides no typedefs.
760///
761/// See @ref bslstl_function
762template <class PROTOTYPE>
764};
765
766/// This component-private specialization of `Function_ArgTypes` is for
767/// function prototypes that take exactly one argument and provides an
768/// `argument_type` nested typedef.
769template <class RET, class ARG>
770struct Function_ArgTypes<RET(ARG)> {
771
772 // PUBLIC TYPES
773
774 /// @deprecated This typedef is deprecated in C++17, for details see
775 /// https://isocpp.org/files/papers/p0005r4.html.
777 "deprecated_cpp17_standard_library_features",
778 "do not use")
779 typedef ARG argument_type;
780};
781
782/// This component-private specialization of `Function_ArgTypes` is for
783/// functions that take exactly two arguments and provides
784/// @ref first_argument_type and @ref second_argument_type nested typedefs.
785template <class RET, class ARG1, class ARG2>
786struct Function_ArgTypes<RET(ARG1, ARG2)> {
787
788 // PUBLIC TYPES
789
790 /// @deprecated This typedef is deprecated in C++17, for details see
791 /// https://isocpp.org/files/papers/p0005r4.html.
793 "deprecated_cpp17_standard_library_features",
794 "do not use")
795 typedef ARG1 first_argument_type;
796
798 "deprecated_cpp17_standard_library_features",
799 "do not use")
800 /// @deprecated This typedef is deprecated in C++17, for details see
801 /// https://isocpp.org/files/papers/p0005r4.html.
802 typedef ARG2 second_argument_type;
803};
804
805 // ================================
806 // class template Function_Variadic
807 // ================================
808
809#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=13
810
811template <class PROTOTYPE>
812class Function_Variadic; // Primary template is never instantiated
813
814/// This component-private class template contains the physical
815/// representation and provides the variadic interfaces for `bsl::function`
816/// (see class and component documentation for `bsl::function`).
817/// `bsl::function` publicly inherits from an instantiation of this
818/// template. This implementation class exists to 1) minimize the amount of
819/// variadic template expansion required in C++03 using the
820/// `sim_cpp11_features.pl` utility and 2) work around issues with the Sun
821/// CC compiler, which has trouble with argument type deduction when a
822/// template argument has a partial specialization (as `Function_Variadic`
823/// does). `bsl::function` does not have a partial specialization and
824/// delegates to the `Function_Variadic` base class only those parts of the
825/// interface and implementation that depend on decomposing the function
826/// prototype into a return type and variadic list of argument types.
827template <class RET, class... ARGS>
828class Function_Variadic<RET(ARGS...)> : public Function_ArgTypes<RET(ARGS...)>
829{
830
831 // PRIVATE TYPES
833
834 /// Type of invocation function. A generic function pointer is stored
835 /// in the representation and is cast to this type to invoke the
836 /// specific type of target stored in this wrapper.
837 typedef RET Invoker(const Function_Rep *,
839
840 // `protected` to workaround a Sun bug when instantiating `bsl::function`
841 // implicitly from an `extern "C"` function pointer, e.g. in a `bind`
842 // expression.
843 protected:
844 // DATA
845 Function_Rep d_rep; // Non-templated representation
846
847 private:
848 // NOT IMPLEMENTED
850
851 /// This component-private base class is not directly copyable.
854
855 // FRIENDS
856 friend class bsl::function<RET(ARGS...)>;
857
858 public:
859 // PUBLIC TYPES
860 typedef RET result_type;
862
863 // CREATORS
864
865 /// Create an empty object. Use the specified `allocator` (e.g., the
866 /// address of a `bslma::Allocator`) to supply memory.
867 Function_Variadic(const allocator_type& allocator);
868
869 /// Destroy this object and its target object.
871
872 // MANIPULATORS
873
874 /// If this object is empty, throw `bsl::bad_function_call`; otherwise
875 /// invoke the target object with the specified `args...` and return the result (after conversion to `RET`).
876 ///
877 /// \note Note that, even though it is
878 /// declared `const`, this call operator can mutate the target object
879 /// and is thus considered a manipulator rather than an accessor.
880 RET operator()(ARGS... args) const;
881};
882
883#endif
884
885 // =================================================
886 // struct template Function_IsInvocableWithPrototype
887 // =================================================
888
889/// Forward declaration of the component-private
890/// `Function_IsInvocableWithPrototype` `struct` template. The primary
891/// (unspecialized) template is not defined. This `struct` template
892/// implements a boolean metafunction that publicly inherits from
893/// `bsl::true_type` if an object of the specified `FUNC` type is invocable
894/// under the specified `PROTOTYPE`, and inherits from `bsl::false_type`
895/// otherwise. An object of `FUNC` type is invocable under the `PROTOTYPE`
896/// if it is Lvalue-Callable with the arguments of the `PROTOTYPE`, and
897/// returns an object of type convertible to the return type of the
898/// `PROTOTYPE`. If the return type of the `PROTOTYPE` is `void`, then any
899/// type is considered convertible to the return type of the `PROTOTYPE`.
900/// In C++03, `FUNC` is considered Lvalue-Callable with the argument and
901/// return types of the `PROTOTYPE` if it is not an integral type. This
902/// `struct` template requires `PROTOTYPE` to be an unqualified function
903/// type.
904template <class PROTOTYPE, class FUNC>
906
907} // close package namespace
908
909
910namespace bsl {
911
912 // =======================
913 // class template function
914 // =======================
915
916/// This class template implements the C++ Standard Library `std::function`
917/// template, enhanced for allocator support as per Standards Proposal
918/// P0987. An instantiation of this template generalizes the notion of a
919/// pointer to a function having the specified `PROTOTYPE` expressed as a
920/// function type (e.g., `int(const char *, float)`). An object of this
921/// class wraps a copy of the callable object specified at construction (if
922/// any), such as a function pointer, member-function pointer, member-data
923/// pointer, or functor object. The wrapped object (called the *target* or
924/// *target* *object*) is owned by the `bsl::function` object (unlike the
925/// function pointer that it mimics). Invoking the `bsl::function` object
926/// will invoke the target (or throw an exception, if there is no target).
927///
928/// \note Note that `function` will compile only if `PROTOTYPE` is a function
929/// type.
930///
931/// To optimize away many heap allocations, objects of this type have a
932/// buffer into which small callable objects can be stored. In order to
933/// qualify for this small-object optimization, a callable type must not
934/// only fit in the buffer but must also be nothrow move constructible. The
935/// latter constraint allows this type to be nothrow move constructible and
936/// nothrow swappable, as required by the C++ Standard. The small object
937/// buffer is guaranteed to be large enough to hold a pointer to function,
938/// pointer to member function, pointer to member data, a
939/// `bsl::reference_wrapper`, or an empty struct. Although the standard
940/// does not specify a minimum size beyond the aforementioned guarantee,
941/// many small structs will fit in the small object buffer, as defined in
942/// the @ref bslstl_function_smallobjectoptimization component.
943///
944/// See @ref bslstl_function
945template <class PROTOTYPE>
946class function : public BloombergLP::bslstl::Function_Variadic<PROTOTYPE> {
947
948 private:
949 // PRIVATE TYPES
950 typedef BloombergLP::bslstl::Function_Variadic<PROTOTYPE> Base;
951 typedef BloombergLP::bslstl::Function_Rep Function_Rep;
952 typedef BloombergLP::bslmf::MovableRefUtil MovableRefUtil;
953
954 /// Abbreviation for metafunction that determines whether a reference
955 /// from `FROM` can be cast to a reference to `TO` without loss of
956 /// information.
957 template <class FROM, class TO>
958 struct IsReferenceCompatible
959 : BloombergLP::bslstl::Function_IsReferenceCompatible<FROM, TO>::type {
960 };
961
962 /// Abbreviation for metafunction used to provide a C++03-compatible
963 /// implementation of `std::decay` that treats `bslmf::MovableReference`
964 /// as an rvalue reference.
965 template <class TYPE>
966 struct Decay : MovableRefUtil::Decay<TYPE> {
967 };
968
969 /// Abbreviation for a metafunction used to determine whether an object
970 /// of the specified `FUNC` is callable with argument types of the
971 /// specified `PROTOTYPE` and returns a type convertible to the return
972 /// type of the `PROTOTYPE`.
973 template <class FUNC>
974 struct IsInvocableWithPrototype
975 : BloombergLP::bslstl::Function_IsInvocableWithPrototype<PROTOTYPE, FUNC> {
976 };
977
978#ifndef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
979 /// Unique type that evaluates to true or false in a boolean control
980 /// construct such as an `if` or `while` statement. In C++03,
981 /// `function` is implicitly convertible to this type but is not
982 /// implicitly convertible to `bool`. In C++11 and later, `function` is
983 /// explicitly convertible to `bool`, so this type is not needed.
984 typedef BloombergLP::bsls::UnspecifiedBool<function> UnspecifiedBoolUtil;
985 typedef typename UnspecifiedBoolUtil::BoolType UnspecifiedBool;
986
987 private:
988 // NOT IMPLEMENTED
989
990 /// Since `function` does not support `operator==` and `operator!=`,
991 /// they must be deliberately suppressed; otherwise `function` objects
992 /// would be implicitly comparable by implicit conversion to
993 /// `UnspecifiedBool`.
994 bool operator==(const function&) const; // Declared but not defined
995 bool operator!=(const function&) const; // Declared but not defined
996#endif // !defined(BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT)
997
998 // PRIVATE MANIPULATORS
999
1000 /// Set the target of this `function` by constructing from the specified
1001 /// `func` callable object. If the type of `func` is a movable
1002 /// reference, then the target is constructed by extended move
1003 /// construction; otherwise by extended copy construction.
1004 /// Instantiation will fail unless `FUNC` is a callable type that is
1005 /// invocable with arguments in `PROTOTYPE` and yields a return type
1006 /// that is convertible to the return type in `PROTOTYPE`.
1007 template <class FUNC>
1008 void installFunc(BSLS_COMPILERFEATURES_FORWARD_REF(FUNC) func);
1009
1010 public:
1011 // TRAITS
1013 BloombergLP::bslma::UsesBslmaAllocator);
1015 BloombergLP::bslmf::UsesAllocatorArgT);
1018
1019 // TYPES
1020 typedef Function_Rep::allocator_type allocator_type;
1021
1022 // CREATORS
1027
1028 /// Create an empty `function` object. Optionally specify an
1029 /// `allocator` (e.g., the address of a `bslma::Allocator` object) to
1030 /// supply memory; otherwise, the default allocator is used.
1034
1035 /// Create an object wrapping the specified `func` callable object. Use
1036 /// the default allocator to supply memory. If `func` is a null pointer
1037 /// or null pointer-to-member, then the resulting object will be empty.
1038 /// This constructor will not participate in overload resolution if
1039 /// `func` is of the same type as (or reference compatible with) this
1040 /// object (to avoid ambiguity with the copy and move constructors) or
1041 /// is an integral type (to avoid matching null pointer literals). In
1042 /// C++03, this function will not participate in overload resolution if
1043 /// `FUNC` is a `MovableRef` (see overload, below), and instantiation
1044 /// will fail unless `FUNC` is invocable using the arguments and return
1045 /// type specified in `PROTOTYPE`. In C++11 and later, this function
1046 /// will not participate in overload resolution if `FUNC` is not
1047 /// invocable using the arguments and return type specified in `PROTOTYPE`.
1048 ///
1049 /// \note Note that this constructor implicitly converts from
1050 /// any type that is so invocable.
1051 template <class FUNC>
1053 typename enable_if<
1054 ! IsReferenceCompatible<typename Decay<FUNC>::type,
1055 function>::value
1056 && IsInvocableWithPrototype<
1057 typename Decay<FUNC>::type>::value
1058#ifndef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
1059 && ! MovableRefUtil::IsMovableReference<FUNC>::value
1060#endif
1061#ifdef BSLS_PLATFORM_CMP_IBM
1063#endif
1064 , int>::type = 0)
1065 : Base(allocator_type())
1066 {
1067 ///Implementation Note
1068 ///- - - - - - - - - -
1069 // The body of this constructor must be inlined inplace because the use
1070 // of `enable_if` will otherwise break the MSVC 2010 compiler.
1071 //
1072 // The `! bsl::is_function<FUNC>::value` constraint is required in
1073 // C++03 mode when using the IBM XL C++ compiler. In C++03,
1074 // `BSLS_COMPILERFEATURES_FORWARD_REF(FUNC) func` expands to
1075 // `const FUNC& func`. A conforming compiler deduces a
1076 // reference-to-function type for `func` when it binds to a function
1077 // argument. The IBM XL C++ compiler erroneously does not collapse the
1078 // `const` qualifier when `FUNC` is deduced to be a function type, and
1079 // instead attempts to deduce the type of `func` to be a reference to a
1080 // `const`-qualified function. This causes substitution to fail
1081 // because function-typed expressions are never `const`. This
1082 // component solves the problem by accepting a `func` having a function
1083 // type as a pointer to a (non-`const`) function. An overload for the
1084 // corresponding constructor is defined below.
1085
1086 installFunc(BSLS_COMPILERFEATURES_FORWARD(FUNC, func));
1087 }
1088
1089#ifdef BSLS_PLATFORM_CMP_IBM
1090 template <class FUNC>
1091 function(FUNC *func, // IMPLICIT
1092 typename enable_if<is_function<FUNC>::value, int>::type = 0)
1093
1094 : Base(allocator_type())
1095 {
1096 ///Implementation Note
1097 ///- - - - - - - - - -
1098 // This constructor overload only exists to work around an IBM XL C++
1099 // compiler defect. See the implementation notes for the above
1100 // constructor overload for more information.
1101 //
1102 // This constructor also forwards the `func` as a pointer-to-function
1103 // type to downstream operations in order to work around the
1104 // aforementioned reference-to-function type deduction defects.
1105 //
1106 // Further, note that instantiation of this constructor will fail
1107 // unless `FUNC` is invocable using the arguments and return type
1108 // specified in `PROTOTYPE`. This component assumes that the IBM XL
1109 // C++ compiler does not support C++11 or later.
1110
1111 installFunc(func);
1112 }
1113#endif
1114
1115#ifndef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
1116 /// Create an object wrapping the specified `func` callable object.
1117 /// This constructor (ctor 2) is identical to the previous constructor
1118 /// (ctor 1) except that, in C++03 ctor 2 provides for explicit
1119 /// construction from a `MovableRef` referencing a callable type, rather
1120 /// than an implicit conversion for `FUNC` not being a `MovableRef`. In
1121 /// C++11, overload resolution matching an argument of type `T&&` to a
1122 /// parameter of type `T` (exact match) is always preferred over
1123 /// matching `T&&` to `bsl::function` (conversion). In C++03, however
1124 /// `MovableRef` is not a real reference type, so it sometimes creates
1125 /// overload ambiguities whereby matching `MovableRef<T>` to `T`
1126 /// (conversion) is no better than matching `MovableRef<T>` to
1127 /// `bsl::function` (also conversion). This ambiguity is resolved by
1128 /// making this constructor from `MovableRef<T>` explicit, while leaving
1129 /// other constructor from `FUNC` implicit. This means that
1130 /// `move` will fail in a narrow set of cases in C++03, as shown below:
1131 /// @code
1132 /// typedef bsl::function<void(int)> Obj;
1133 /// MyCallableType x;
1134 ///
1135 /// Obj f1 = x; // OK
1136 /// Obj f2 = bslmf::MovableRefUtil::move(x); // No conversion in C++03
1137 /// Obj f3(bslmf::MovableRefUtil::move(x)); // OK, normal ctor call
1138 ///
1139 /// void y(const Obj& f);
1140 /// y(x); // OK
1141 /// y(bslmf::MovableRefUtil::move(x)); // Not found in C++03
1142 /// y(Obj(bslmf::MovableRefUtil::move(x))); // OK, explicit cast
1143 /// @endcode
1144 /// As you can see from the examples above, there are simple workarounds
1145 /// for the problem cases, although generic code might need to be extra
1146 /// careful.
1147 template <class FUNC>
1148 explicit function(const BloombergLP::bslmf::MovableRef<FUNC>& func,
1149 typename enable_if<
1150 ! IsReferenceCompatible<typename Decay<FUNC>::type,
1151 function>::value
1152 && IsInvocableWithPrototype<
1153 typename Decay<FUNC>::type>::value
1154 , int>::type = 0)
1155 : Base(allocator_type())
1156 {
1157 ///Implementation Note
1158 ///- - - - - - - - - -
1159 // The body of this constructor must inlined inplace because the use of
1160 // `enable_if` will otherwise break the MSVC 2010 compiler.
1161
1162 installFunc(BloombergLP::bslmf::MovableRefUtil::move(func));
1163 }
1164#endif
1165
1166 /// Create an object wrapping the specified `func` callable object. Use
1167 /// the specified `allocator` (i.e., the address of a `bslma::Allocator`
1168 /// object) to supply memory. If `func` is a null pointer or null
1169 /// pointer-to-member, then the resulting object will be empty. This
1170 /// constructor will not participate in overload resolution if `func` is
1171 /// of the same type as (or reference compatible with) this object (to
1172 /// avoid ambiguity with the extended copy and move constructors) or is
1173 /// an integral type (to avoid matching null pointer literals). In
1174 /// C++03, this function will not participate in overload resolution if
1175 /// `FUNC` is a `MovableRef` (see overload, below), and instantiation
1176 /// will fail unless `FUNC` is invocable using the arguments and return
1177 /// type specified in `PROTOTYPE`. In C++11 and later, this function
1178 /// will not participate in overload resolution if `FUNC` is not
1179 /// invocable using the arguments and return type specified in `PROTOTYPE`.
1180 ///
1181 /// \note Note that this constructor implicitly converts from
1182 /// any type that is so invocable.
1183 template <class FUNC>
1187 typename enable_if<
1188 ! IsReferenceCompatible<typename Decay<FUNC>::type,
1189 function>::value
1190 && IsInvocableWithPrototype<
1191 typename Decay<FUNC>::type>::value
1192#ifdef BSLS_PLATFORM_CMP_IBM
1194#endif
1195 , int>::type = 0)
1196 : Base(allocator)
1197 {
1198 ///Implementation Note
1199 ///- - - - - - - - - -
1200 // The body of this constructor must inlined inplace because the use of
1201 // `enable_if` will otherwise break the MSVC 2010 compiler.
1202 //
1203 // The `! bsl::is_function<FUNC>::value` constraint is required in
1204 // C++03 mode when using the IBM XL C++ compiler. In C++03,
1205 // `BSLS_COMPILERFEATURES_FORWARD_REF(FUNC) func` expands to
1206 // `const FUNC& func`. A conforming compiler deduces a
1207 // reference-to-function type for `func` when it binds to a function
1208 // argument. The IBM XL C++ compiler erroneously does not collapse the
1209 // `const` qualifier when `FUNC` is deduced to be a function type, and
1210 // instead attempts to deduce the type of `func` to be a reference to a
1211 // `const`-qualified function. This causes substitution to fail
1212 // because function-typed expressions are never `const`. This
1213 // component solves the problem by accepting a `func` having a function
1214 // type as a pointer to a (non-`const`) function. An overload for the
1215 // corresponding constructor is defined below.
1216
1217 installFunc(BSLS_COMPILERFEATURES_FORWARD(FUNC, func));
1218 }
1219
1220#ifdef BSLS_PLATFORM_CMP_IBM
1221 template <class FUNC>
1223 const allocator_type& allocator,
1224 FUNC *func,
1225 typename enable_if<is_function<FUNC>::value, int>::type = 0)
1226 : Base(allocator)
1227 {
1228 ///Implementation Note
1229 ///- - - - - - - - - -
1230 // This constructor overload only exists to work around an IBM XL C++
1231 // compiler defect. See the implementation notes for the above
1232 // constructor overload for more information.
1233 //
1234 // This constructor also forwards the `func` as a pointer-to-function
1235 // type to downstream operations in order to work around the
1236 // aforementioned reference-to-function type deduction defects.
1237 //
1238 // Further, note that instantiation of this constructor will fail
1239 // unless `FUNC` is invocable using the arguments and return type
1240 // specified in `PROTOTYPE`. This component assumes that the IBM XL
1241 // C++ compiler does not support C++11 or later.
1242
1243 installFunc(func);
1244 }
1245#endif
1246
1247 /// Create a `function` having the same value as (i.e., wrapping a copy
1248 /// of the target held by) the specified `original` object. Optionally
1249 /// specify an `allocator` (e.g., the address of a `bslma::Allocator`
1250 /// object) to supply memory; otherwise, the default allocator is used.
1251 function(const function& original);
1254 const function& original);
1255
1256 /// Create a `function` having the same target as the specified
1257 /// `original` object. Use `original.get_allocator()` as the allocator
1258 /// to supply memory. The `original` object is set to empty after the
1259 /// new object is created. If the target qualifies for the small-object
1260 /// optimization (see class-level documentation), then it is
1261 /// move-constructed into the new object; otherwise ownership of the
1262 /// target is transferred without using the target's move constructor.
1263 function(BloombergLP::bslmf::MovableRef<function> original)
1264 BSLS_KEYWORD_NOEXCEPT; // IMPLICIT
1265
1266 /// Create a `function` having the same value as (i.e., wrapping a copy
1267 /// of the target held by) the specified `original` object. Use the
1268 /// specified `allocator` (e.g., the address of a `bslma::Allocator`
1269 /// object) to supply memory. If `allocator == original.allocator()`,
1270 /// this object is created as if by move construction; otherwise it is
1271 /// created as if by extended copy construction using `allocator`.
1274 BloombergLP::bslmf::MovableRef<function> original);
1275
1276 // MANIPULATORS
1277
1278 /// Set the target of this object to a copy of the target (if any)
1279 /// held by the specified `rhs` object, destroy the target (if any)
1280 /// previously held by `*this`, and return `*this`. The result is
1281 /// equivalent to having constructed `*this` from `rhs` using the
1282 /// extended copy constructor with allocator `this->get_allocator()`.
1283 /// If an exception is thrown, `*this` is not modified (i.e., copy
1284 /// assignment provides the strong exception guarantee).
1286
1287 /// Set the target of this object to the target (if any) held by the
1288 /// specified `rhs` object, destroy the target (if any) previously held
1289 /// by `*this`, and return `*this`. The result is equivalent to having
1290 /// constructed `*this` from `rhs` using the extended move constructor
1291 /// with allocator `this->get_allocator()`. If an exception is thrown,
1292 /// `rhs` will have a valid but unspecified value and `*this` will not be modified.
1293 ///
1294 /// \note Note that an exception will never be thrown if
1295 /// `get_allocator() == rhs.get_allocator()`.
1296 function& operator=(BloombergLP::bslmf::MovableRef<function> rhs);
1297
1298 /// Set the target of this object to the specified `rhs` callable
1299 /// object, destroy the previous target (if any), and return `*this`.
1300 /// The result is equivalent to having constructed `*this` from
1301 /// `std::forward<FUNC>(rhs)` and `this->get_allocator()`.
1302 ///
1303 /// \note Note that this assignment operator will not participate in overload resolution
1304 /// if `func` is of the same type as this object (to avoid ambiguity
1305 /// with the copy and move assignment operators.) In C++03,
1306 /// instantiation will fail unless `FUNC` is invocable with the
1307 /// arguments and return type specified in `PROTOTYPE`. In C++11 and
1308 /// later, this assignment operator will not participate in overload
1309 /// resolution unless `FUNC` is invocable with the arguments and return
1310 /// type specified in `PROTOTYPE`.
1311 template <class FUNC>
1312 typename enable_if<
1313 ! IsReferenceCompatible<typename Decay<FUNC>::type, function>::value
1314 && IsInvocableWithPrototype<typename Decay<FUNC>::type>::value
1315 , function&>::type
1317 {
1318 ///Implementation Note
1319 ///- - - - - - - - - -
1320 // The body of this operator must inlined inplace because the use of
1321 // `enable_if` will otherwise break the MSVC 2010 compiler.
1322
1323 function(allocator_arg, this->get_allocator(),
1324 BSLS_COMPILERFEATURES_FORWARD(FUNC, rhs)).swap(*this);
1325 return *this;
1326 }
1327
1328#ifdef BSLS_PLATFORM_CMP_IBM
1329 /// Set the target of this object to the specified `rhs` function
1330 /// pointer. This overload exists only for the IBM compiler, which has
1331 /// trouble decaying functions to function pointers in
1332 /// pass-by-const-reference template arguments.
1333 template <class FUNC>
1335 operator=(FUNC *rhs)
1336 {
1337 ///Implementation Note
1338 ///- - - - - - - - - -
1339 // The body of this operator must inlined inplace.
1340 //
1341 // Further, note that instantiation of this assignment operator will
1342 // fail unless `FUNC` is invocable using the arguments and return type
1343 // specified in `PROTOTYPE`. This component assumes that the IBM XL
1344 // C++ compiler does not support C++11 or later.
1345
1346 function(allocator_arg, this->get_allocator(), rhs).swap(*this);
1347 return *this;
1348 }
1349#endif
1350
1351 /// Destroy the current target (if any) of this object, then set the
1352 /// target to the specified `rhs` wrapper containing a reference to a
1353 /// callable object and return `*this`. The result is equivalent to
1354 /// having constructed `*this` from `rhs` and `this->get_allocator()`.
1355 ///
1356 /// \note Note that this assignment is a separate overload only because it is
1357 /// unconditionally `noexcept`.
1358 template <class FUNC>
1359 typename enable_if<
1360 IsInvocableWithPrototype<typename Decay<FUNC>::type>::value
1361 , function &>::type
1363 {
1364 /// Implementation Note
1365 ///- - - - - - - - - -
1366 // The body of this operator must inlined inplace because the use of
1367 // 'enable_if' will otherwise break the MSVC 2010 compiler.
1368
1369 function(allocator_arg, this->get_allocator(), rhs).swap(*this);
1370 return *this;
1371 }
1372
1373 /// Set this object to empty and return `*this`.
1375
1376 // Inherit 'operator()' from 'Function_Variadic' base class.
1377
1378 /// If this object is empty, throw `bsl::bad_function_call`; otherwise
1379 /// invoke the target object with the specified `args...` and return the result (after conversion to `RET`).
1380 ///
1381 /// \note Note that, even though it is
1382 /// declared `const`, this call operator can mutate the target object
1383 /// and is thus considered a manipulator rather than an accessor.
1384 using Base::operator();
1385
1386 /// Exchange the targets held by this `function` and the specified `other` `function`.
1387 ///
1388 /// \pre The behavior is undefined unless
1389 /// `get_allocator() == other.get_allocator()`.
1391
1392 /// If `TP` is the same type as the target object, returns a pointer
1393 /// granting modifiable access to the target; otherwise return a null
1394 /// pointer.
1395 template<class TP> TP* target() BSLS_KEYWORD_NOEXCEPT;
1396
1397 // ACCESSORS
1398#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1399 /// (C++11 and later) Return false if this object is empty, otherwise return true.
1400 ///
1401 /// \note Note that this is an explicit conversion operator and
1402 /// is typically invoked implicitly in contexts such as in the condition
1403 /// of an `if` or `while` statement, though it can also be invoked via
1404 /// an explicit cast.
1405 explicit // Explicit conversion available only with C++11
1406 operator bool() const BSLS_KEYWORD_NOEXCEPT;
1407#else
1408 /// (C++03 only) Return a null value if this object is empty, otherwise an arbitrary non-null value.
1409 ///
1410 /// \note Note that this operator will be
1411 /// invoked implicitly in boolean contexts such as in the condition of
1412 /// an `if` or `while` statement, but does not constitute an implicit
1413 /// conversion to `bool`.
1414 operator UnspecifiedBool() const BSLS_KEYWORD_NOEXCEPT
1415 {
1416 // Inplace inlined to work around xlC bug when out-of-line.
1417 return UnspecifiedBoolUtil::makeValue(0 != this->d_rep.invoker());
1418 }
1419#endif
1420
1421 /// Return (a copy of) the allocator used to supply memory for this
1422 /// `function`.
1424
1425 /// If `TP` is the same type as the target object, returns a pointer
1426 /// granting read-only access to the target; otherwise return a null
1427 /// pointer.
1428 template<class TP> const TP* target() const BSLS_KEYWORD_NOEXCEPT;
1429
1430 /// Return `typeid(void)` if this object is empty; otherwise
1431 /// `typeid(FUNC)` where `FUNC` is the type of the target object.
1432 const std::type_info& target_type() const BSLS_KEYWORD_NOEXCEPT;
1433
1434#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1435 // LEGACY METHODS
1436
1437 /// Return `*this`, converted to a mutable `bdef_Function` reference by downcasting.
1438 ///
1439 /// \pre The behavior is undefined unless `bdef_Function<F*>`
1440 /// is derived from `bsl::function<F>` and adds no new data members.
1441 ///
1442 /// @deprecated Use @ref bsl::function` instead of `bdef_Function.
1443 operator BloombergLP::bdef_Function<PROTOTYPE *>&() BSLS_KEYWORD_NOEXCEPT;
1444
1445 /// Return `*this` converted to a const `bdef_Function` reference by downcasting.
1446 ///
1447 /// \pre The behavior is undefined unless `bdef_Function<F*>`
1448 /// is derived from `bsl::function<F>` and adds no new data members.
1449 ///
1450 /// @deprecated Use @ref bsl::function` instead of `bdef_Function.
1451 operator const BloombergLP::bdef_Function<PROTOTYPE *>&() const
1453
1454 // LEGACY ACCESSORS
1455
1456 /// Return `get_allocator().mechanism()`.
1457 /// \note Note that this function exists
1458 /// for BDE compatibility and is not part of the C++ Standard Library.
1459 ///
1460 /// @deprecated Use @ref get_allocator() instead.
1461 BloombergLP::bslma::Allocator *allocator() const BSLS_KEYWORD_NOEXCEPT;
1462
1463 /// Return `true` if this `function` is empty or if it is non-empty and
1464 /// its target qualifies for the small-object optimization (and is thus
1465 /// allocated within this object's footprint); otherwise, return false.
1466 ///
1467 /// @deprecated Runtime checking of this optimization is discouraged.
1468 bool isInplace() const BSLS_KEYWORD_NOEXCEPT;
1469#endif
1470};
1471
1472#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1473// CLASS TEMPLATE DEDUCTION GUIDES
1474
1475/// Deduce the template parameter `PROTOTYPE` from the signature of the
1476/// function supplied to the constructor of `function`.
1477template<class RET, class... ARGS>
1478function(RET(*)(ARGS...)) -> function<RET(ARGS...)>;
1479
1480/// Deduce the template parameter `PROTOTYPE` from the signature of the
1481/// function supplied to the constructor of `function`.
1482template<class ALLOC, class RET, class... ARGS>
1483function(allocator_arg_t, ALLOC, RET(*)(ARGS...)) -> function<RET(ARGS...)>;
1484
1485
1486/// This struct provides a set of template `meta-functions` that extract
1487/// the signature of a class member function, stripping any qualifiers such
1488/// as `const`, `noexcept` or `&`.
1489///
1490/// See @ref bslstl_function
1491struct FunctionDeductionHelper {
1492
1493 public:
1494 // PUBLIC TYPES
1495 template<class FUNCTOR>
1496 struct StripSignature {};
1497
1498 template<class RET, class FUNCTOR, class ...ARGS>
1499 struct StripSignature<RET (FUNCTOR::*) (ARGS...)>
1500 { using Sig = RET(ARGS...); };
1501
1502 template<class RET, class FUNCTOR, class ...ARGS>
1503 struct StripSignature<RET (FUNCTOR::*) (ARGS...) const>
1504 { using Sig = RET(ARGS...); };
1505
1506 template<class RET, class FUNCTOR, class ...ARGS>
1507 struct StripSignature<RET (FUNCTOR::*) (ARGS...) noexcept>
1508 { using Sig = RET(ARGS...); };
1509
1510 template<class RET, class FUNCTOR, class ...ARGS>
1511 struct StripSignature<RET (FUNCTOR::*) (ARGS...) const noexcept>
1512 { using Sig = RET(ARGS...); };
1513
1514 template<class RET, class FUNCTOR, class ...ARGS>
1515 struct StripSignature<RET (FUNCTOR::*) (ARGS...) &>
1516 { using Sig = RET(ARGS...); };
1517
1518 template<class RET, class FUNCTOR, class ...ARGS>
1519 struct StripSignature<RET (FUNCTOR::*) (ARGS...) const &>
1520 { using Sig = RET(ARGS...); };
1521
1522 template<class RET, class FUNCTOR, class ...ARGS>
1523 struct StripSignature<RET (FUNCTOR::*) (ARGS...) & noexcept>
1524 { using Sig = RET(ARGS...); };
1525
1526 template<class RET, class FUNCTOR, class ...ARGS>
1527 struct StripSignature<RET (FUNCTOR::*) (ARGS...) const & noexcept>
1528 { using Sig = RET(ARGS...); };
1529};
1530
1531/// Deduce the template parameter `PROTOTYPE` from the signature of the
1532/// `operator()` of the functor supplied to the constructor of `function`.
1533template <
1534 class FP,
1535 class PROTOTYPE = typename
1536 FunctionDeductionHelper::StripSignature<decltype(&FP::operator())>::Sig
1537 >
1538function(FP) -> function<PROTOTYPE>;
1539
1540/// Deduce the template parameter `PROTOTYPE` from the signature of the
1541/// `operator()` of the functor supplied to the constructor of `function`.
1542template <
1543 class ALLOC,
1544 class FP,
1545 class PROTOTYPE = typename
1546 FunctionDeductionHelper::StripSignature<decltype(&FP::operator())>::Sig
1547 >
1548function(allocator_arg_t, ALLOC, FP) -> function<PROTOTYPE>;
1549#endif
1550
1551// FREE FUNCTIONS
1552template <class PROTOTYPE>
1554
1555/// Return true if the `function` argument is empty, otherwise return false.
1556template <class PROTOTYPE>
1558
1559template <class PROTOTYPE>
1561
1562/// Return false if the `function` argument is empty, otherwise return true.
1563template <class PROTOTYPE>
1565
1566/// Exchange the targets held by the specified `a` and specified `b` objects.
1567///
1568/// \pre The behavior is undefined unless 'a.get_allocator() ==
1569/// b.get_allocator()'.
1570template <class PROTOTYPE>
1572
1573} // close namespace bsl
1574
1575// ============================================================================
1576// TEMPLATE AND INLINE FUNCTION DEFINITIONS
1577// ============================================================================
1578
1579
1580
1581#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1582
1583 // --------------------------------
1584 // class template Function_Variadic
1585 // --------------------------------
1586
1587// CREATORS
1588template <class RET, class... ARGS>
1589inline
1591Function_Variadic(const allocator_type& allocator)
1592 : d_rep(allocator)
1593{
1594}
1595
1596// MANIPULATORS
1597template <class RET, class... ARGS>
1598inline
1599RET bslstl::Function_Variadic<RET(ARGS...)>::operator()(ARGS... args) const
1600{
1601 // BDE_VERIFY pragma: push
1602 // BDE_VERIFY pragma: -SAL01 // Possible strict-aliasing violation
1603 Invoker *invoker_p = reinterpret_cast<Invoker*>(d_rep.invoker());
1604 // BDE_VERIFY pragma: pop
1605
1606 if (! invoker_p) {
1608 }
1609
1610 // It is not necessary to call 'std::forward<ARGS>' because 'args...' is
1611 // not composed of forwarding references. The arguments to 'invoker_p',
1612 // however, are not the same as 'args...' but compatible types produced by
1613 // 'bslmf::ForwardingTypes' for efficiency.
1614 return invoker_p(&d_rep, args...);
1615}
1616
1617#endif
1618
1619namespace bslstl {
1620
1621#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=13
1622
1623 // -------------------------------------------------
1624 // struct template Function_IsInvocableWithPrototype
1625 // -------------------------------------------------
1626
1627#ifdef BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE
1628
1629/// This component-private `struct` template provides a boolean metafunction
1630/// that derives from `bsl::true_type` if a `bsl::function` object having a
1631/// prototype of `RET(ARGS...)` is constructible from an object of type
1632/// `FUNC`, and derives from `bsl::false_type` otherwise. This metafunction
1633/// is a wrapper around `bsl::invoke_result` that unwraps `FUNC` if it is a
1634/// specialization of `bslalg::NothrowMovableWrapper`; and, if
1635/// `bsl::invoke_result` provides a nested `type` typedef for `FUNC` and
1636/// `RET` is non-void, checks that the return type of the invoke operation
1637/// on `FUNC` is convertible to `RET`.
1638template <class RET, class FUNC, class... ARGS>
1639struct Function_IsInvocableWithPrototype<RET(ARGS...), FUNC>
1640: Function_InvokerUtil::IsFuncInvocable<RET(ARGS...), FUNC> {
1641};
1642
1643#else // if !defined(BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE)
1644
1645/// This component-private `struct` template provides a partial
1646/// specialization of `Function_IsInvocableWithPrototype` for any `FUNC`
1647/// type, and for `PROTOTYPE` types that are function types. This
1648/// specialization only exists in pre-C++11 (e.g. C++03) compilers. It
1649/// approximates a boolean metafunction for detecting whether the specified
1650/// `FUNC` type is Lvalue-Callable with the prototype `RET(ARGS...)`. This
1651/// approximation is extremely coarse, and only checks that the `FUNC` is
1652/// not an integral type. It does this for the sole purpose of ensuring
1653/// that there are no overload resolution ambiguities in the constructors
1654/// and assignment operators of `bsl::function`, which provide overloads for
1655/// both integral types (to accept the literal `0` is a null pointer
1656/// constant), and for callable types like `FUNC`.
1657template <class RET, class FUNC, class... ARGS>
1658struct Function_IsInvocableWithPrototype<RET(ARGS...), FUNC>
1659: bsl::integral_constant<bool, !bsl::is_integral<FUNC>::value> {
1660};
1661
1662#endif // !defined(BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE)
1663#endif
1664
1665} // close package namespace
1666
1667
1668 // ----------------------------
1669 // class template bsl::function
1670 // ----------------------------
1671
1672// PRIVATE MANIPULATORS
1673template <class PROTOTYPE>
1674template <class FUNC>
1675inline
1678{
1679 typedef BloombergLP::bslstl::Function_InvokerUtil InvokerUtil;
1680 typedef InvokerUtil::GenericInvoker GenericInvoker;
1681 typedef typename Decay<FUNC>::type DecayedFunc;
1682
1683 const DecayedFunc& decayedFunc = func; // Force function-to-pointer decay.
1684 GenericInvoker *const invoker =
1685 InvokerUtil::invokerForFunc<PROTOTYPE>(decayedFunc);
1686
1687 this->d_rep.installFunc(BSLS_COMPILERFEATURES_FORWARD(FUNC, func),
1688 invoker);
1689}
1690
1691// CREATORS
1692template <class PROTOTYPE>
1697
1698template <class PROTOTYPE>
1703
1704template <class PROTOTYPE>
1705inline
1712
1713template <class PROTOTYPE>
1714inline
1721
1722template <class PROTOTYPE>
1724 : Base(allocator_type())
1725{
1726 this->d_rep.copyInit(original.d_rep);
1727}
1728
1729template <class PROTOTYPE>
1732 const function& original)
1733 : Base(allocator)
1734{
1735 this->d_rep.copyInit(original.d_rep);
1736}
1737
1738template <class PROTOTYPE>
1739inline
1741 BloombergLP::bslmf::MovableRef<function> original) BSLS_KEYWORD_NOEXCEPT
1742 : Base(MovableRefUtil::access(original).get_allocator())
1743{
1744 this->d_rep.moveInit(&MovableRefUtil::access(original).d_rep);
1745}
1746
1747template <class PROTOTYPE>
1751 BloombergLP::bslmf::MovableRef<function> original)
1752 : Base(allocator)
1753{
1754 this->d_rep.moveInit(&MovableRefUtil::access(original).d_rep);
1755}
1756
1757// MANIPULATORS
1758template <class PROTOTYPE>
1761{
1762 function temp(allocator_arg, this->get_allocator(), rhs);
1763 this->d_rep.makeEmpty(); // Won't throw
1764 this->d_rep.moveInit(&temp.d_rep); // Won't throw
1765 return *this;
1766}
1767
1768template <class PROTOTYPE>
1771 BloombergLP::bslmf::MovableRef<function> rhs)
1772{
1773 function temp(allocator_arg, this->get_allocator(),
1774 MovableRefUtil::move(rhs));
1775 this->d_rep.makeEmpty(); // Won't throw
1776 this->d_rep.moveInit(&temp.d_rep); // Won't throw
1777 return *this;
1778}
1779
1780template <class PROTOTYPE>
1783{
1784 this->d_rep.makeEmpty();
1785 return *this;
1786}
1787
1788template <class PROTOTYPE>
1789inline
1791{
1792 this->d_rep.swap(other.d_rep); // Won't throw
1793}
1794
1795template <class PROTOTYPE>
1796template<class TP>
1797inline
1799{
1800 return this->d_rep.template target<TP>();
1801}
1802
1803// ACCESSORS
1804
1805#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1806template <class PROTOTYPE>
1807inline
1809{
1810 // If there is an invoker, then this function is non-empty (return true);
1811 // otherwise it is empty (return false).
1812 return 0 != this->d_rep.invoker();
1813}
1814#endif // BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
1815
1816template <class PROTOTYPE>
1817inline
1823
1824template <class PROTOTYPE>
1825template<class TP>
1826inline
1828{
1829 return this->d_rep.template target<TP>();
1830}
1831
1832template <class PROTOTYPE>
1833const std::type_info&
1835{
1836 return this->d_rep.target_type();
1837}
1838
1839#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1840// CONVERSIONS TO LEGACY TYPE
1841template <class PROTOTYPE>
1842inline
1843bsl::function<PROTOTYPE>::operator BloombergLP::bdef_Function<PROTOTYPE *>&()
1845{
1846 typedef BloombergLP::bdef_Function<PROTOTYPE *> Ret;
1847 return *static_cast<Ret*>(this);
1848}
1849
1850template <class PROTOTYPE>
1851inline
1853operator const BloombergLP::bdef_Function<PROTOTYPE *>&() const
1855{
1856 typedef const BloombergLP::bdef_Function<PROTOTYPE *> Ret;
1857 return *static_cast<Ret*>(this);
1858}
1859
1860template <class PROTOTYPE>
1861inline
1862BloombergLP::bslma::Allocator *
1864{
1865 return get_allocator().mechanism();
1866}
1867
1868template <class PROTOTYPE>
1869inline
1871{
1872 return this->d_rep.isInplace();
1873}
1874#endif // BDE_OMIT_INTERNAL_DEPRECATED
1875
1876// FREE FUNCTIONS
1877template <class PROTOTYPE>
1878inline
1881{
1882 return !f;
1883}
1884
1885template <class PROTOTYPE>
1886inline
1887bool bsl::operator==(bsl::nullptr_t,
1889{
1890 return !f;
1891}
1892
1893template <class PROTOTYPE>
1894inline
1897{
1898 return !!f;
1899}
1900
1901template <class PROTOTYPE>
1902inline
1905{
1906 return !!f;
1907}
1908
1909template <class PROTOTYPE>
1910inline
1913{
1914 a.swap(b);
1915}
1916
1917 // --------------------------------------------------------------
1918 // specialization of class template Function_InvokerUtil_Dispatch
1919 // --------------------------------------------------------------
1920
1921
1922namespace bslstl {
1923
1924/// Specialization of null checker for instantiations of `bsl::function`.
1925/// This specialization treats an empty `bsl::function` as a null object.
1926template <class PROTO>
1927struct Function_InvokerUtilNullCheck<bsl::function<PROTO> > {
1928
1929 // CLASS METHODS
1930
1931 /// Return true if the `bsl::function` specified by `f` is empty; else
1932 /// false.
1933 static bool isNull(const bsl::function<PROTO>& f)
1934 {
1935 return !f;
1936 }
1937};
1938
1939} // close package namespace
1940
1941
1942// Undo `BSLS_ASSERT` filename fix -- See @ref bsls_assertimputil
1943#ifdef BSLS_ASSERTIMPUTIL_AVOID_STRING_CONSTANTS
1944#undef BSLS_ASSERTIMPUTIL_FILE
1945#define BSLS_ASSERTIMPUTIL_FILE BSLS_ASSERTIMPUTIL_DEFAULTFILE
1946#endif
1947
1948#endif // End C++11 code
1949
1950#endif // End C++11 code
1951
1952// ----------------------------------------------------------------------------
1953// Copyright 2020 Bloomberg Finance L.P.
1954//
1955// Licensed under the Apache License, Version 2.0 (the "License");
1956// you may not use this file except in compliance with the License.
1957// You may obtain a copy of the License at
1958//
1959// http://www.apache.org/licenses/LICENSE-2.0
1960//
1961// Unless required by applicable law or agreed to in writing, software
1962// distributed under the License is distributed on an "AS IS" BASIS,
1963// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1964// See the License for the specific language governing permissions and
1965// limitations under the License.
1966// ----------------------------- END-OF-FILE ----------------------------------
1967
1968/** @} */
1969/** @} */
1970/** @} */
Definition bslstl_function.h:737
Forward declaration.
Definition bslstl_function.h:946
function(const BloombergLP::bslmf::MovableRef< FUNC > &func, typename enable_if< ! IsReferenceCompatible< typename Decay< FUNC >::type, function >::value &&IsInvocableWithPrototype< typename Decay< FUNC >::type >::value, int >::type=0)
Definition bslstl_function.h:1148
function(allocator_arg_t, const allocator_type &allocator, BSLS_COMPILERFEATURES_FORWARD_REF(FUNC) func, typename enable_if< ! IsReferenceCompatible< typename Decay< FUNC >::type, function >::value &&IsInvocableWithPrototype< typename Decay< FUNC >::type >::value, int >::type=0)
Definition bslstl_function.h:1184
BSLMF_NESTED_TRAIT_DECLARATION(function, bsl::is_nothrow_move_constructible)
BSLMF_NESTED_TRAIT_DECLARATION(function, BloombergLP::bslma::UsesBslmaAllocator)
BSLMF_NESTED_TRAIT_DECLARATION(function, BloombergLP::bslmf::UsesAllocatorArgT)
enable_if< IsInvocableWithPrototype< typenameDecay< FUNC >::type >::value, function & >::type operator=(bsl::reference_wrapper< FUNC > rhs) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1362
Function_Rep::allocator_type allocator_type
Definition bslstl_function.h:1020
enable_if<!IsReferenceCompatible< typenameDecay< FUNC >::type, function >::value &&IsInvocableWithPrototype< typenameDecay< FUNC >::type >::value, function & >::type operator=(BSLS_COMPILERFEATURES_FORWARD_REF(FUNC) rhs)
Definition bslstl_function.h:1316
Definition bslmf_referencewrapper.h:182
Imp::Type Type
Definition bslmf_forwardingtype.h:441
Definition bslstl_function_rep.h:132
~Function_Variadic()=default
Destroy this object and its target object.
RET result_type
Definition bslstl_function.h:860
Function_Rep d_rep
Definition bslstl_function.h:845
Function_Rep::allocator_type allocator_type
Definition bslstl_function.h:861
Definition bslstl_function.h:812
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE)
Definition bsls_deprecatefeature.h:387
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_DELETED
Definition bsls_keyword.h:651
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
BloombergLP::bslma::Allocator * allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1863
function & operator=(const function &rhs)
Definition bslstl_function.h:1760
function & operator=(BloombergLP::bslmf::MovableRef< function > rhs)
Definition bslstl_function.h:1770
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1819
const std::type_info & target_type() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1834
bool isInplace() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1870
function(allocator_arg_t, const allocator_type &allocator, const function &original)
Definition bslstl_function.h:1730
function(allocator_arg_t, const allocator_type &allocator, BloombergLP::bslmf::MovableRef< function > original)
Definition bslstl_function.h:1748
function & operator=(nullptr_t) BSLS_KEYWORD_NOEXCEPT
Set this object to empty and return *this.
Definition bslstl_function.h:1782
void swap(function &other) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1790
TP * target() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1798
function() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1693
function(const function &original)
Definition bslstl_function.h:1723
function(BloombergLP::bslmf::MovableRef< function > original) BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function.h:1740
Definition bdlat_valuetypefunctions.h:939
BloombergLP::bsls::Nullptr_Impl::Type nullptr_t
Definition bsls_nullptr.h:283
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
bool operator==(const memory_resource &a, const memory_resource &b)
bool operator!=(const memory_resource &a, const memory_resource &b)
Definition bslstl_algorithm.h:84
Definition bdldfp_decimal.h:5549
Definition bslmf_allocatorargt.h:433
Definition bslmf_enableif.h:530
Definition bslmf_integralconstant.h:261
Definition bslmf_isfunction.h:232
Definition bslmf_isnothrowmoveconstructible.h:361
BSLS_DEPRECATE_FEATURE("bsl", "deprecated_cpp17_standard_library_features", "do not use") typedef ARG1 first_argument_type
BSLS_DEPRECATE_FEATURE("bsl", "deprecated_cpp17_standard_library_features", "do not use") typedef ARG argument_type
Definition bslstl_function.h:763
static bool isNull(const bsl::function< PROTO > &f)
Definition bslstl_function.h:1933
Definition bslstl_function_invokerutil.h:318
static BSLA_NORETURN void throwBadFunctionCall()
Definition bslstl_function.h:905