BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_function_invokerutil.h
Go to the documentation of this file.
1/// @file bslstl_function_invokerutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_function_invokerutil.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_FUNCTION_INVOKERUTIL
9#define INCLUDED_BSLSTL_FUNCTION_INVOKERUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_function_invokerutil bslstl_function_invokerutil
15/// @brief Provide invoker adaptors for `bsl::function`
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_function_invokerutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_function_invokerutil-purpose"> Purpose</a>
25/// * <a href="#bslstl_function_invokerutil-classes"> Classes </a>
26/// * <a href="#bslstl_function_invokerutil-description"> Description </a>
27/// * <a href="#bslstl_function_invokerutil-macros"> Macros </a>
28/// * <a href="#bslstl_function_invokerutil-return-value-of-function_invokerutil-invokerforfunc"> Return value of Function_InvokerUtil::invokerForFunc </a>
29/// * <a href="#bslstl_function_invokerutil-customization-point-function_invokerutilnullcheck"> Customization point Function_InvokerUtilNullCheck </a>
30///
31/// # Purpose {#bslstl_function_invokerutil-purpose}
32/// Provide invoker adaptors for `bsl::function`
33///
34/// # Classes {#bslstl_function_invokerutil-classes}
35///
36/// - Function_InvokerUtil: Utility for returning an appropriate invoker function
37/// - Function_InvokerUtilNullCheck: Customization point to detect null invocable
38///
39///@MACROS
40/// BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE: defined if supported
41///
42/// @see bslstl_function
43///
44/// # Description {#bslstl_function_invokerutil-description}
45/// This component provides a struct, `Function_InvokerUtil`,
46/// containing a function template, `invokerForFunc`, that returns a pointer to
47/// a function that is used to invoke a callable object of a particular type.
48/// The returned type is custom-generated for each specific target type. This
49/// component is for private use only.
50///
51/// The client of this component, `bsl::function`, is a complex class that is
52/// templated in two ways:
53///
54/// 1. The class itself has a template parameter representing the prototype
55/// (argument and return types) of its call operator. E.g., type
56/// `bsl::function<int(char*)>` has member `int operator()(char*);`.
57/// 2. Several of its constructors take an argument of template parameter
58/// callable type and wrap it, using type erasure, so that the type of the
59/// wrapped target is not part of the type of the `bsl::function`.
60///
61/// Only the invocation mechanism needs both kinds of template parameters; other
62/// parts of `bsl::function` (e.g., `bslstl::Function_Rep`) concern themselves
63/// with only the callable object type, not with the prototype of the call
64/// operator. This component factors out most of that complexity so as to
65/// minimise code size, especially when using the `sim_cpp11_features.pl` script
66/// to simulate C++11 variadic templates in C++03.
67///
68/// The classes in this component are stateless and contain only static
69/// functions.
70///
71/// ## Macros {#bslstl_function_invokerutil-macros}
72///
73///
74/// If this component supports checking whether an object of an arbitrary
75/// non-cvref-qualified type is invocable under a particular prototype, the
76/// `BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE` macro is defined,
77/// and it is not defined otherwise.
78///
79/// ## Return value of Function_InvokerUtil::invokerForFunc {#bslstl_function_invokerutil-return-value-of-function_invokerutil-invokerforfunc}
80///
81///
82/// The function pointer, `invoker_p`, returned by
83/// `Function_InvokerUtil::invokerForFunc<RET(ARG0, ARG1, ...)>` takes an
84/// argument of type `Function_Rep *` and zero or more argument types `ARG0`,
85/// `ARG1`, ..., as specified by the template argument. Calling
86/// `invoker_p(rep, arg0, arg1, ...)` gets the target, `f` from `rep` and
87/// invokes it with the supplied arguments. Invocation of `f` follows the
88/// definition of *INVOKE* in section [func.require] of the C++ standard. These
89/// rules are summarized in the following table:
90/// @code
91/// +----------------------------+-----------------------+
92/// | Type of target object, 'f' | Invocation expression |
93/// +============================+=======================+
94/// | Pointer to function or | f(arg0, arg1, ...) |
95/// | functor class | |
96/// +----------------------------+-----------------------+
97/// | Pointer to member function | (arg0X.*f)(arg1, ...) |
98/// +----------------------------+-----------------------+
99/// | pointer to data member | arg0X.*f |
100/// +----------------------------+-----------------------+
101/// @endcode
102/// The arguments to `f` must be implicitly convertible from the corresponding
103/// argument types `ARG0`, `ARG1`, ... and the return value of the call
104/// expression must be implicitly convertible to `RET`, unless `RET` is `void`.
105///
106/// In the case of a pointer to member function, `R (T::*f)(...)`, or pointer to
107/// data member `R T::*f`, `arg0X` is one of the following:
108///
109/// * `arg0` if `ARG0` is `T` or derived from `T`.
110/// * `arg0.get()` if `ARG0` is a specialization of @ref reference_wrapper .
111/// * `(*arg0)` if `ARG0` is a pointer type or pointer-like type (e.g., a smart
112/// pointer).
113///
114/// Note that, consistent with the C++ Standard definition of *INVOKE*, we
115/// consider pointer-to-member-function and pointer-to-data-member types to be
116/// "callable" even though, strictly speaking, they lack an `operator()`.
117///
118/// ## Customization point Function_InvokerUtilNullCheck {#bslstl_function_invokerutil-customization-point-function_invokerutilnullcheck}
119///
120///
121/// The class template, `Function_InvokerUtilNullCheck<T>` provides a single,
122/// `static` member function `isNull(const T& f)` that returns `true` iff `f`
123/// represents a "null value". By default,
124/// `Function_InvokerUtilNullCheck<T>::isNull` returns `true` iff `T` is a
125/// pointer or pointer-to-member type and has a null value. For non-pointer
126/// types, the primary template always returns `false`. However, other
127/// components can provide specializations of `Function_InvokerUtilNullCheck`
128/// that add the notion of "nullness" to other invocable types. In particular,
129/// `bslstl_function.h` specializes this template for `bsl::function` and
130/// `bdef_function.h` specializes this template for @ref bdef_function . In both
131/// cases, a function object is considered null if it is empty, i.e., it does
132/// not wrap an invocable object. Although it is theoretically possible to
133/// specialize `Function_InvokerUtilNullCheck` for types not related to
134/// `bsl::function`, doing so would go outside of the behavior of the standard
135/// `std::function` type that `bsl::function` is emulating. For this reason,
136/// `Function_InvokerUtilNullCheck` is tucked away in this private component for
137/// use only through explicit collaboration.
138/// @}
139/** @} */
140/** @} */
141
142/** @addtogroup bsl
143 * @{
144 */
145/** @addtogroup bslstl
146 * @{
147 */
148/** @addtogroup bslstl_function_invokerutil
149 * @{
150 */
151
152#include <bslscm_version.h>
153
155
157#include <bslmf_conditional.h>
158#include <bslmf_forwardingtype.h>
160#include <bslmf_invokeresult.h>
162#include <bslmf_isvoid.h>
164#include <bslmf_movableref.h>
165
166#include <bsla_noreturn.h>
168#include <bsls_keyword.h>
169#include <bsls_libraryfeatures.h>
170#include <bsls_nullptr.h>
171
172#include <bslstl_function_rep.h>
174
175#include <utility>
176
177#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
178// clang-format off
179// Include version that can be compiled with C++03
180// Generated on Mon Jan 13 08:31:39 2025
181// Command line: sim_cpp11_features.pl bslstl_function_invokerutil.h
182
183# define COMPILING_BSLSTL_FUNCTION_INVOKERUTIL_H
185# undef COMPILING_BSLSTL_FUNCTION_INVOKERUTIL_H
186
187// clang-format on
188#else
189
190#ifndef BSLS_PLATFORM_CMP_SUN
191#define BSLSTL_FUNCTION_INVOKERUTIL_CAST_RESULT(RET, X) static_cast<RET>(X)
192#else
193#define BSLSTL_FUNCTION_INVOKERUTIL_CAST_RESULT(RET, X) (RET)(X)
194#endif
195
196#if defined(BSLMF_INVOKERESULT_SUPPORT_CPP17_SEMANTICS) \
197 && defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE) \
198 && defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) \
199 && defined(BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY)
200#define BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE
201#endif
202
203
204namespace bslstl {
205
206#ifdef BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE
207
208/// forward declaration
209template <class PROTOTYPE, class FUNC>
210struct Function_InvokerUtil_IsFuncInvocable;
211
212#endif
213
214 // ===========================
215 // struct Function_InvokerUtil
216 // ===========================
217
218/// This struct is a namespace containing a single function template,
219/// `invokerForFunc`, that returns a pointer to a function that is used to
220/// invoke a callable object of a particular type.
221///
222/// See @ref bslstl_function_invokerutil
224
225 // TYPES
226 enum {
227 // Enumeration of the different types of callable objects.
228
235 };
236
237 /// Generic function pointer. This type is as close as we can get to
238 /// `void *` for function pointers.
240
241#ifdef BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE
242 /// This `struct` template implements a Boolean metafunction that
243 /// publicly inherits from `bsl::true_type` if an object of the
244 /// specified `FUNC` type is invocable under the specified `PROTOTYPE`,
245 /// and publicly inherits from `bsl::false_type` otherwise. An object
246 /// of `FUNC` type is invocable under the `PROTOTYPE` if it is
247 /// Lvalue-Callable with the arguments of the `PROTOTYPE` (as forwarded
248 /// by the facilities of 'bslmf_forwardingtype), and returns an object
249 /// of type explicitly convertible to the return type of the
250 /// `PROTOTYPE`. If the return type of the `PROTOTYPE` is `void`, then
251 /// any type is considered explicitly convertible to the return type of
252 /// the `PROTOTYPE`. This `struct` template requires `PROTOTYPE` to be
253 /// an unqualified function type.
254 ///
255 ///
256 /// \note Note that `IsFuncInvocable` is qualitatively different than
257 /// `std::is_invocable_r`, in that it makes concessions for supporting
258 /// legacy behavior of `bsl::function`.
259 /// `std::is_invocable_r<RET, FUNC, ARGS...>` requires that the return
260 /// type of the invocation of `FUNC` with `ARGS...` be implicitly
261 /// convertible to `RET`, as opposed to explicitly convertible.
262 /// Further, the use of `bslmf::ForwardingType` to forward arguments in
263 /// the invoker of a `bsl::function` creates qualitatively different
264 /// behavior than the argument forwarding mechanism used by the standard
265 /// `INVOKE` pseudo-expression.
266 template <class PROTOTYPE, class FUNC>
267 struct IsFuncInvocable
268 : Function_InvokerUtil_IsFuncInvocable<PROTOTYPE, FUNC> {
269 };
270#endif
271
272 // CLASS METHODS
273
274 /// Return a null pointer.
275 /// \note Note that template argument `PROTOTYPE` must
276 /// be supplied excplicitly, as there is no way to deduce it from the
277 /// function arguments.
278 template <class PROTOTYPE>
280
281 /// Return a pointer to the invoker for a callable object of (template
282 /// paramter) type `FUNC`. If the specified `f` object is a null
283 /// pointer or null pointer-to-member, return a null pointer.
284 ///
285 /// \note Note that template argument `PROTOTYPE` must be supplied excplicitly, as there
286 /// is no way to deduce it from the function arguments.
287 template <class PROTOTYPE, class FUNC>
288 static GenericInvoker *invokerForFunc(const FUNC& f);
289
290 /// Throw a `bsl::bad_function_call` exception in an exception-enabled
291 /// build; otherwise, invoke the currently installed assertion violation handler.
292 ///
293 /// \note Note that providing a function to throw an exception moves
294 /// the code generated to throw the exception into just one place rather
295 /// than inline in every function template instantiation that would call
296 /// it. It also insulates the header files from the declaration of the
297 /// exception class itself, so that only clients catching
298 /// @ref bad_function_call need to include its header.
300 static void throwBadFunctionCall();
301};
302
303 // =============================================
304 // template struct Function_InvokerUtilNullCheck
305 // =============================================
306
307/// Provides an `isNull` static method that that returns whether or not its
308/// argument is "null", i.e., it cannot be invoked. For must `FUNC` types
309/// `isNull` always returns `false` as every instance of `FUNC` is
310/// invocable. However, specializations of this class, especially for
311/// pointer types, have `isNull` functions that sometimes return `true`.
312/// This class is a customization point: types outside of this component can
313/// (but rarely should) specialize this template. In particular,
314/// @ref bslstl_function contains a specialization for `bsl::function`.
315///
316/// See @ref bslstl_function_invokerutil
317template <class FUNC>
319
320 // CLASS METHODS
321
322 /// Return `false`.
323 static bool isNull(const FUNC&);
324};
325
326/// Specialization of dispatcher for pointer objects.
327template <class FUNC>
329
330 // CLASS METHODS
331
332 /// Return `true` if the specified `f` pointer is null; otherwise
333 /// `false`.
334 static bool isNull(FUNC *f);
335};
336
337/// Specialization of dispatcher for pointer-to-member objects.
338template <class CLASS, class MEMTYPE>
339struct Function_InvokerUtilNullCheck<MEMTYPE CLASS::*> {
340
341 public:
342 // CLASS METHODS
343
344 /// Return `true` if the specified `f` pointer to member is null;
345 /// otherwise `false`.
346 static bool isNull(MEMTYPE CLASS::* f);
347};
348
349#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=13
350
351 // ====================================================
352 // template struct Function_InvokerUtil_IsFuncInvocable
353 // ====================================================
354
355#ifdef BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE
356
357/// forward declaration
358template <class VOID_TYPE, class RET, class FUNC, class... ARGS>
359struct Function_InvokerUtil_IsFuncInvocableImp;
360
361/// This `struct` template implements a Boolean metafunction that publicly
362/// inherits from `bsl::true_type` if an object of the specified `FUNC` type
363/// is invocable with the specified `RET` and `ARGS...`, and publicly
364/// inherits from `bsl::false_type` otherwise. An object of `FUNC` type is
365/// invocable with `RET` and `ARGS...` if it is Lvalue-Callable with
366/// arguments having the types of the `ARGS...`, and returns an object of
367/// type explicitly convertible to `RET`. If `RET` is `void`, then any type
368/// is considered explicitly convertible to `RET`.
369template <class RET, class FUNC, class... ARGS>
370struct Function_InvokerUtil_IsFuncInvocable<RET(ARGS...), FUNC>
371: Function_InvokerUtil_IsFuncInvocableImp<void, RET, FUNC, ARGS...> {
372};
373
374 // =======================================================
375 // template struct Function_InvokerUtil_IsFuncInvocableImp
376 // =======================================================
377
378/// forward declaration
379template <class ARG>
380struct Function_InvokerUtil_ForwardType;
381
382/// forward declaration
383template <class FROM, class TO>
384struct Function_InvokerUtil_IsExplicitlyConvertible;
385
386/// forward declaration
387template <class FUNC, class... ARGS>
388struct Function_InvokerUtil_ResultType;
389
390/// This component-private `struct` template provides the primary template
391/// definition for the `Function_InvokerUtil_IsFuncInvocableImp` Boolean
392/// metafunction, which is an implementation detail of the
393/// `Function_InvokerUtil_IsFuncInvocable` Boolean metafunction. This
394/// specialization is instantiated when `std::invoke_result<T, FWD_ARGS...>`
395/// does not provide a nested `type` typedef, where `T` is the result of
396/// stripping a nothrow-movable wrapper from `FUNC`, if present, and adding
397/// an lvalue reference, and where `FWD_ARGS...` are the types that result
398/// from forwarding objects of respective `ARGS...` types. This `struct`
399/// template requires that the specified `VOID_TYPE` type to be `void`.
400template <class VOID_TYPE, class RET, class FUNC, class... ARGS>
401struct Function_InvokerUtil_IsFuncInvocableImp : bsl::false_type {
402};
403
404/// This component-private `struct` template provides a partial
405/// specialization of `Function_InvokerUtil_IsFuncInvocableImp` for `FUNC`
406/// types for which `bsl::invoke_result<T, FWD_ARGS...>` provides a nested
407/// `type` typedef, where `T` is the result of stripping a nothrow-movable
408/// wrapper from `FUNC`, if present, and adding an lvalue reference, and
409/// where `FWD_ARGS...` are the types that result from forwarding objects
410/// of respective `ARGS...` types.
411///
412/// Specifically, `T` is
413/// `bslalg::NothrowMovableUtil::UnwrappedType<FUNC>::type&`, and
414/// `FWD_ARGS...` are the types of respective
415/// `bslmf::ForwardingTypeUtil<ARGS...>::forwardToTarget(args...)`
416/// expressions where `args...` are lvalue expressions of respective
417/// `bslmf::ForwardingType<ARGS>::Type...` types. See the class-level
418/// documentation of the primary `Function_InvokerUtil::IsFuncInvocable`
419/// declaration for more information about the behavior of this `struct`
420/// template.
421template <class RET, class FUNC, class... ARGS>
422struct Function_InvokerUtil_IsFuncInvocableImp<
423 typename bslmf::VoidType<
424 typename Function_InvokerUtil_ResultType<FUNC, ARGS...>::type>::type,
425 RET,
426 FUNC,
427 ARGS...>
429 bsl::is_void<RET>::value,
430 bsl::true_type,
431 Function_InvokerUtil_IsExplicitlyConvertible<
432 typename Function_InvokerUtil_ResultType<FUNC, ARGS...>::type,
433 RET> >::type {
434};
435
436 // ===============================================
437 // template struct Function_InvokerUtil_ResultType
438 // ===============================================
439
440/// forward declaration
441template <class VOID_TYPE, class FUNC, class... ARGS>
442struct Function_InvokerUtil_ResultTypeImp;
443
444/// This component-private `struct` template provides a metafunction that
445/// conditionally defines a nested `type` typedef if the standard
446/// `INVOKE(f, fwdArgs...)` pseudo-expression is well-formed, where `f` is
447/// an lvalue of `bslalg::NothrowMoveableUtil::UnwrappedType<FUNC>` type,
448/// and `fwdArgs...` are defined to be the expressions
449/// `bslmf::ForwardingTypeUtil<ARGS>::forwardToTarget(args)...` where
450/// `args...` are lvalue expressions of the corresponding
451/// `bslmf::ForwardingType<ARGS>::Type...` types. If such an `INVOKE`
452/// expression is well-formed, this struct defines `type` to be the result
453/// type of the expression, and defines no such typedef otherwise.
454template <class FUNC, class... ARGS>
455struct Function_InvokerUtil_ResultType
456: Function_InvokerUtil_ResultTypeImp<void, FUNC, ARGS...> {
457};
458
459 // ==================================================
460 // template struct Function_InvokerUtil_ResultTypeImp
461 // ==================================================
462
463/// This component-private `struct` template provides the primary template
464/// definition for the `Function_InvokerUtil_ResultTypeImp` metafunction,
465/// which is an implementation detail of the
466/// `Function_InvokerUtil_ResultType` metafunction. This specialization is
467/// instantiated when the standard `INVOKE(f, fwdArgs...)` pseudo-expression
468/// is not well-formed, where `f` is an lvalue of
469/// `bslalg::NothrowMoveableUtil::UnwrappedType<FUNC>` type, and
470/// `fwdArgs...` are defined to be the expressions
471/// `bslmf::ForwardingTypeUtil<ARGS>::forwardToTarget(args)...` where
472/// `args...` are lvalue expressions of the corresponding
473/// `bslmf::ForwardingType<ARGS>::Type...` types.
474///
475/// See @ref bslstl_function_invokerutil
476template <class VOID_TYPE, class FUNC, class... ARGS>
477struct Function_InvokerUtil_ResultTypeImp {
478};
479
480template <class FUNC, class... ARGS>
481struct Function_InvokerUtil_ResultTypeImp<
482 typename bslmf::VoidType<
483 typename Function_InvokerUtil_ForwardType<ARGS>::Type...>::type,
484 FUNC,
485 ARGS...>
487 typename bsl::add_lvalue_reference<typename bslalg::NothrowMovableUtil::
488 UnwrappedType<FUNC>::type>::type,
489 typename Function_InvokerUtil_ForwardType<ARGS>::Type...> {
490
491 // This component-private 'struct' template provides a partial
492 // specialization of 'Function_InvokerUtil_ResultTypeImp' for 'FUNC' and
493 // 'ARGS...' types for which standard 'INVOKE(f, fwdArgs...)'
494 // pseudo-expression is well-formed, where 'f' is an lvalue of
495 // 'bslalg::NothrowMoveableUtil::UnwrappedType<FUNC>' type, and
496 // 'fwdArgs...' are defined to be the expressions
497 // 'bslmf::ForwardingTypeUtil<ARGS>::forwardToTarget(args)...' where
498 // 'args...' are lvalue expressions of the corresponding
499 // 'bslmf::ForwardingType<ARGS>::Type...' types. This 'struct' defines a
500 // nested typedef 'type' that is the type of this expression.
501};
502
503 // ================================================
504 // template struct Function_InvokerUtil_ForwardType
505 // ================================================
506
507/// forward declaration
508template <class VOID_TYPE, class ARG>
509struct Function_InvokerUtil_ForwardTypeImp;
510
511/// This component-private `struct` template provides a metafunction that
512/// conditionally defines a nested `type` typedef that is the type resulting
513/// from forwarding an lvalue of the specified `ARG` type using the
514/// machinery from @ref bslmf_forwardingtype . If it is not possible to forward
515/// an object of `ARG` type (if, for example, `ARG` is `void`) then this
516/// `struct` template does not define a `type` typedef.
517///
518/// Specifically, `type` is defined to be the type of the expression
519/// `bslmf::ForwardingTypeUtil<ARG>::forwardingToTarget(arg)`, where `arg`
520/// is an lvalue expression of `bslmf::ForwardingType<ARG>::Type` type.
521/// `type` is not defined when this expression is not well-formed.
522template <class ARG>
523struct Function_InvokerUtil_ForwardType
524: Function_InvokerUtil_ForwardTypeImp<void, ARG> {
525};
526
527 // ===================================================
528 // template struct Function_InvokerUtil_ForwardTypeImp
529 // ===================================================
530
531/// This component-private `struct` template provides the primary template
532/// definition for the `Function_InvokerUtil_ForwardTypeImp` metafunction,
533/// which is an implementation detail of the
534/// `Function_InvokerUtil_IsFuncInvocable` metafunction. This
535/// specialization is instantiated when the expression
536/// `bslmf::ForwardingTypeUtil<ARG>::forwardToTarget(arg)` is not
537/// well-formed, where `arg` is an lvalue expression of
538/// `bslmf::ForwardingType<ARG>::Type` type.
539///
540/// See @ref bslstl_function_invokerutil
541template <class VOID_TYPE, class ARG>
542struct Function_InvokerUtil_ForwardTypeImp {
543};
544
545/// This component-private `struct` template provides a partial
546/// specialization of `Function_InvokerUtil_ForwardTypeImp` for `ARG` types
547/// for which the expression
548/// `bslmf::ForwardingTypeUtil<ARG>::forwardToTarget(arg)` is well-formed,
549/// where `arg` is an lvalue expression of
550/// `bslmf::ForwardingType<ARG>::Type` type. This `struct` template
551/// defines a nested `type` typedef that is the type of the expression.
552/// This is the type resulting from forwarding an lvalue of the specified
553/// `ARG` type using the machinery from @ref bslmf_forwardingtype .
554template <class ARG>
555struct Function_InvokerUtil_ForwardTypeImp<
556 typename bslmf::VoidType<decltype(
557 bslmf::ForwardingTypeUtil<ARG>::forwardToTarget(
558 std::declval<typename bsl::add_lvalue_reference<
559 typename bslmf::ForwardingType<ARG>::Type>::type>()))>::type,
560 ARG> {
561
562 // TYPES
563
564 /// `Type` is an alias to the "forwarded" type of the specified `ARG`
565 /// type. Specifically, it is the type of the expression
566 /// `bslmf::ForwardingTypeUtil<ARG>::forwardingToTarget(arg)`, where
567 /// `arg` is an lvalue expression of `bslmf::ForwardingType<ARG>::Type`
568 /// type.
570 std::declval<typename bsl::add_lvalue_reference<
571 typename bslmf::ForwardingType<ARG>::Type>::type>())) Type;
572};
573
574 // ============================================================
575 // template struct Function_InvokerUtil_IsExplicitlyConvertible
576 // ============================================================
577
578/// forward declaration
579template <class VOID_TYPE, class FROM, class TO>
580struct Function_InvokerUtil_IsExplicitlyConvertibleImp;
581
582/// This component-private `struct` template provides a Boolean metafunction
583/// that publicly derives from `bsl::true_type` if the specified `FROM` type
584/// can be explicitly converted to the specified `TO` type, and derives from
585/// `bsl::false_type` otherwise. The type `FROM` is explicitly convertible
586/// to the type `TO` if the expression
587/// `static_cast<TO>(std::declval<FROM>())` is well-formed.
588template <class FROM, class TO>
589struct Function_InvokerUtil_IsExplicitlyConvertible
590: Function_InvokerUtil_IsExplicitlyConvertibleImp<void, FROM, TO> {
591};
592
593/// A type is always explicitly convertible to itself. This is important
594/// for classes with deleted copy constructors and/or assignment operators,
595/// because starting in C++17, they can be returned from functions, due to
596/// "return value optimization (RVO)".
597template <class FROM_TO>
598struct Function_InvokerUtil_IsExplicitlyConvertible<FROM_TO, FROM_TO>
600};
601
602 // ===============================================================
603 // template struct Function_InvokerUtil_IsExplicitlyConvertibleImp
604 // ===============================================================
605
606/// This component-private `struct` template provides the primary
607/// specialization of the `Function_InvokerUtil_IsExplicitlyConvertibleImp`
608/// metafunction. This specialization is instantiated when the specified
609/// `FROM` type is not explicitly convertible to the specified `TO` type,
610/// and publicly ihherits from `bsl::false_type`. This `struct` template
611/// requires the specified `VOID_TYPE` type to be `void`.
612template <class VOID_TYPE, class FROM, class TO>
613struct Function_InvokerUtil_IsExplicitlyConvertibleImp : bsl::false_type {
614};
615
616/// This component-private `struct` template provides a partial
617/// specialization of the `Function_InvokerUtil_IsExplicitlyConvertibleImp`
618/// metafunction. This specialization is instantiated when the specified
619/// `FROM` type is explicitly convertible to the specified `TO` type, and
620/// publicly inherits from `bsl::true_type`.
621template <class FROM, class TO>
622struct Function_InvokerUtil_IsExplicitlyConvertibleImp<
623 typename bslmf::VoidType<decltype(
624 static_cast<TO>(std::declval<FROM>()))>::type,
625 FROM,
626 TO> : bsl::true_type {
627};
628
629#endif // defined(BSLSTL_FUNCTION_INVOKERUTIL_SUPPORT_IS_FUNC_INVOCABLE)
630#endif
631
632 // =============================================
633 // template struct Function_InvokerUtil_Dispatch
634 // =============================================
635
636/// Specializations of this class contain a static `invoke` method that can
637/// invoke a callable object of type `FUNC`, converting each argument in
638/// `PROTOTYPE` (a function prototype) to the corresponding argument in the
639/// invocation of the callable object and converting the return value of the
640/// invocation to the return type of `PROTOTYPE`. The `INVOCATION_TYPE`
641/// specifies the category of callable object: pointer to function, pointer
642/// to member function, pointer to data member, inplace functor (i.e., one
643/// that qualifies for the small-object optimization) and out-of-place
644/// functor (i.e., one that is not stored in the small-object buffer).
645template <int INVOCATION_TYPE, class PROTOTYPE, class FUNC>
647
648#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES // $var-args=13
649
650// STATIC METHODS OF PRIVATE NESTED *Invoker CLASS TEMPLATES
651
652/// Specialization of dispatcher for pointer-to-function objects.
653template <class FUNC, class RET, class... ARGS>
655 RET(ARGS...), FUNC> {
656
657 // CLASS METHODS
658
659 /// For the specified `rep` and `args`, return
660 /// `rep.target<FUNC>()(args...)`.
661 static RET invoke(const Function_Rep *rep,
662 typename bslmf::ForwardingType<ARGS>::Type... args);
663};
664
665/// Specialization of dispatcher for pointer to member function objects.
666template <class FUNC, class RET, class ARG0, class... ARGS>
668 RET(ARG0, ARGS...), FUNC> {
669
670 private:
671 // PRIVATE CLASS METHODS
672
673 /// Use the specified `obj` to invoke the specified `f` pointer to
674 /// member function with the specified `args` and return the result,
675 /// i.e., `(obj.*f)(args...)`.
676 static RET invokeImp(bsl::true_type /* isDirect */,
677 FUNC f,
679 typename bslmf::ForwardingType<ARGS>::Type... args);
680
681 /// Dereference the specified `obj` and usit to invoke the specified `f`
682 /// pointer to member function with the specified `args` and return the
683 /// result, i.e., `((*obj).*f)(args...)`.
684 static RET invokeImp(bsl::false_type /* isDirect */,
685 FUNC f,
687 typename bslmf::ForwardingType<ARGS>::Type... args);
688
689 public:
690 // CLASS METHODS
691
692 /// Given pointer to member function, `f`, as the target of the
693 /// specified `rep`, use the specified `obj` to invoke `f` with the
694 /// specified `args` and return the result, i.e., `(obj.*f)(args...)`.
695 /// If `obj` is a pointer or smart-pointer, dereference `obj` first,
696 /// i.e., call `((*obj).*f)(args...)`.
697 static RET invoke(const Function_Rep *rep,
699 typename bslmf::ForwardingType<ARGS>::Type... args);
700};
701
702/// Specialization of dispatcher for pointer to data member objects.
703template <class MEMBER_TYPE, class CLASS_TYPE, class RET, class ARG0>
705 RET(ARG0), MEMBER_TYPE CLASS_TYPE::*> {
706 private:
707 // PRIVATE CLASS METHODS
708 typedef MEMBER_TYPE CLASS_TYPE::* Func;
709
710 /// Return the specified `f` member of the specified `obj`, i.e.,
711 /// `obj.*f`.
712 static RET invokeImp(bsl::true_type /* isDirect */,
713 Func f,
715
716 /// Return the specified `f` member of the object obtained by
717 /// dereferencing the specified `obj`, i.e., `(*obj).f`.
718 static RET invokeImp(bsl::false_type /* isDirect */,
719 Func f,
721
722 public:
723 // CLASS METHODS
724
725 /// Given pointer to data member, `f`, as the target of the specified
726 /// `rep`, return the specified `f` member of the specified `obj`, i.e.,
727 /// `obj.*f`. If `obj` is a pointer or smart-pointer, dereference `obj`
728 /// first, i.e., return `(*obj).*f`.
729 static RET invoke(const Function_Rep *rep,
731};
732
733/// Specialization of dispatcher functor class objects that are suitable for
734/// the small-object optimization and are thus allocated inplace.
735template <class FUNC, class RET, class... ARGS>
737 RET(ARGS...), FUNC> {
738
739 // CLASS METHODS
740
741 /// For the specified `args` and `rep`, return
742 /// `(*rep.target<FUNC>())(args...)`.
743 static RET invoke(const Function_Rep *rep,
744 typename bslmf::ForwardingType<ARGS>::Type... args);
745};
746
747/// Specialization of dispatcher functor class objects that are not suitable
748/// for the small-object optimization and are thus allocated out of place.
749template <class FUNC, class RET, class... ARGS>
751 RET(ARGS...), FUNC> {
752
753 // CLASS METHODS
754
755 /// For the specified `args` and `rep`, return
756 /// `(*rep.target<FUNC>())(args...)`.
757 static RET invoke(const Function_Rep *rep,
758 typename bslmf::ForwardingType<ARGS>::Type... args);
759};
760
761#endif
762
763// ===========================================================================
764// TEMPLATE AND INLINE FUNCTION IMPLEMENTATIONS
765// ===========================================================================
766
767 // ---------------------------
768 // struct Function_InvokerUtil
769 // ---------------------------
770
771template <class PROTOTYPE>
772inline
778
779template <class PROTOTYPE, class FUNC>
782{
784
785 // Strip 'NothrowMovableWrapper' (if any) off of 'FUNC' type.
786 typedef typename
788
789 // Categorize the type of invocable corresponding to 'FUNC'. Note that the
790 // parameter to 'Soo::Inplace' is 'FUNC', not 'UwFuncType'. That is
791 // because 'Soo::Inplace' takes the wrapper into account when determining
792 // whether the type should be inplace or not.
793 static const int k_INVOCATION_TYPE =
797 Soo::IsInplaceFunc<FUNC>::value ? e_InplaceFunctor :
798 e_OutofplaceFunctor;
799
800 // Instantiate the class for checking for null object
801 typedef Function_InvokerUtilNullCheck<UwFuncType> NullCheckerClass;
802
803 // Instantiate the class for dispatching the invoker
804 typedef Function_InvokerUtil_Dispatch<k_INVOCATION_TYPE,
805 PROTOTYPE,
806 UwFuncType> DispatcherClass;
807
808 // If a the object is "null", e.g., for a pointer, then return null.
809 if (NullCheckerClass::isNull(bslalg::NothrowMovableUtil::unwrap(f)))
810 {
811 return 0; // RETURN
812 }
813
814 // Verify the assumption that all function pointers are the same size.
815 BSLMF_ASSERT(sizeof(&DispatcherClass::invoke) ==
817
818 // Return a pointer to the actual invoker function
819 return reinterpret_cast<Function_Rep::GenericInvoker *>(
820 &DispatcherClass::invoke);
821}
822
823 // ---------------------------------------------
824 // struct template Function_InvokerUtilNullCheck
825 // ---------------------------------------------
826
827// STATIC MEMBER FUNCTIONS
828
829template <class FUNC>
830inline
832{
833 return false;
834}
835
836template <class FUNC>
837inline
839{
840 return 0 == f;
841}
842
843template <class CLASS, class MEMTYPE>
844inline
845bool
847{
848 return 0 == f;
849}
850
851
852 // ---------------------------------------------
853 // struct template Function_InvokerUtil_Dispatch
854 // ---------------------------------------------
855
856#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
857
858template <class FUNC, class RET, class... ARGS>
859RET
860Function_InvokerUtil_Dispatch<Function_InvokerUtil::e_FunctionPtr,
861 RET(ARGS...), FUNC>::
862invoke(const Function_Rep *rep,
863 typename bslmf::ForwardingType<ARGS>::Type... args)
864{
865 FUNC f = *rep->targetRaw<FUNC, true>();
866
867 // Note that 'FUNC' might be different than 'RET(*)(ARGS...)'. All that is
868 // required is that it be Callable with 'ARGS...' and return something
869 // convertible to 'RET'.
870
871 // Cast to 'RET' is needed to avoid compilation error if 'RET' is 'void'
872 // and 'f' returns non-void.
874 RET,
876}
877
878template <class FUNC, class RET, class ARG0, class... ARGS>
879inline
880RET
882 RET(ARG0, ARGS...), FUNC>::
883invokeImp(bsl::true_type /* isDirect */,
884 FUNC f,
886 typename bslmf::ForwardingType<ARGS>::Type... args)
887{
888 typedef typename
890
891 // In C++03, an rvalue is forwarded as a const lvalue. Fortunately, we can
892 // recover the correct constness by casting 'obj' back to a reference to
893 // the original type.
895 RET, (const_cast<Arg0Ref>(obj).*f)(
897}
898
899template <class FUNC, class RET, class ARG0, class... ARGS>
900inline
901RET
902Function_InvokerUtil_Dispatch<Function_InvokerUtil::e_MemFunctionPtr,
903 RET(ARG0, ARGS...), FUNC>::
904invokeImp(bsl::false_type /* isDirect */,
905 FUNC f,
907 typename bslmf::ForwardingType<ARGS>::Type... args)
908{
909 typedef typename
911
912 // In C++03, an rvalue is forwarded as a const lvalue. Fortunately, we can
913 // recover the correct constness from by casting back to a reference to
914 // the original type.
916 RET, ((*const_cast<Arg0Ref>(obj)).*f)(
918}
919
920template <class FUNC, class RET, class ARG0, class... ARGS>
921RET
922Function_InvokerUtil_Dispatch<Function_InvokerUtil::e_MemFunctionPtr,
923 RET(ARG0, ARGS...), FUNC>::
924invoke(const Function_Rep *rep,
926 typename bslmf::ForwardingType<ARGS>::Type... args)
927{
928 typedef typename
930
931 /// `true_type` if `ARG0` is a reference to `ClassType` or class derived
932 /// from `ClassType; otherwise, `false_type'.
933 typedef typename bsl::is_convertible<
935 ClassType *
936 >::type IsDirect;
937
938 FUNC f = *rep->targetRaw<FUNC, true>();
939
941 invokeImp(IsDirect(), f, obj,
942 args...));
943}
944
945template <class MEMBER_TYPE, class CLASS_TYPE, class RET, class ARG0>
946inline
947RET
949 RET(ARG0), MEMBER_TYPE CLASS_TYPE::*>::
950invokeImp(bsl::true_type /* isDirect */,
951 Func f,
953{
954 typedef typename
956
957 // In C++03, an rvalue is forwarded as a const lvalue. Fortunately, we can
958 // recover the correct constness by casting 'obj' back to a reference to
959 // the original type.
961 RET, (const_cast<Arg0Ref>(obj).*f));
962}
963
964template <class MEMBER_TYPE, class CLASS_TYPE, class RET, class ARG0>
965inline
966RET
967Function_InvokerUtil_Dispatch<Function_InvokerUtil::e_MemDataPtr,
968 RET(ARG0), MEMBER_TYPE CLASS_TYPE::*>::
969invokeImp(bsl::false_type /* isDirect */,
970 Func f,
972{
973 typedef typename
975
976 // In C++03, an rvalue is forwarded as a const lvalue. Fortunately, we can
977 // recover the correct constness from by casting back to a reference to
978 // the original type.
980 RET, ((*const_cast<Arg0Ref>(obj)).*f));
981}
982
983template <class MEMBER_TYPE, class CLASS_TYPE, class RET, class ARG0>
984RET
985Function_InvokerUtil_Dispatch<Function_InvokerUtil::e_MemDataPtr,
986 RET(ARG0), MEMBER_TYPE CLASS_TYPE::*>::
987invoke(const Function_Rep *rep,
989{
990 /// `true_type` if `ARG0` is a reference to `CLASS_TYPE` or class derived from `CLASS_TYPE; otherwise, `false_type'.
991 ///
992 /// \note Note that this
993 /// differs from the corresponding check for pointers to member
994 /// functions because a pointer to data member for class type `T` can
995 /// be used to access (as const) a member of a cv-qualified `T`.
996 typedef typename bsl::is_convertible<
998 const volatile CLASS_TYPE *
999 >::type IsDirect;
1000
1001 Func f = *rep->targetRaw<Func, true>();
1002
1004 RET, invokeImp(IsDirect(), f, obj));
1005}
1006
1007template <class FUNC, class RET, class... ARGS>
1008RET
1009Function_InvokerUtil_Dispatch<Function_InvokerUtil::e_InplaceFunctor,
1010 RET(ARGS...), FUNC>::
1011invoke(const Function_Rep *rep,
1012 typename bslmf::ForwardingType<ARGS>::Type... args)
1013{
1014 FUNC& f = *rep->targetRaw<FUNC, true>();
1015
1016 // Cast to 'RET' is needed to avoid compilation error if 'RET' is void and
1017 // 'f' returns non-void.
1019 RET,
1021}
1022
1023template <class FUNC, class RET, class... ARGS>
1024RET
1026 RET(ARGS...), FUNC>::
1027invoke(const Function_Rep *rep,
1028 typename bslmf::ForwardingType<ARGS>::Type... args)
1029{
1030 FUNC& f = *rep->targetRaw<FUNC, false>();
1031
1032 // Cast to 'RET' is needed to avoid compilation error if 'RET' is void and
1033 // 'f' returns non-void.
1035 RET,
1037}
1038
1039#endif
1040
1041} // close package namespace
1042
1043
1044#endif // End C++11 code
1045
1046#endif // ! defined(INCLUDED_BSLSTL_FUNCTION_INVOKERUTIL)
1047
1048// ----------------------------------------------------------------------------
1049// Copyright 2020 Bloomberg Finance L.P.
1050//
1051// Licensed under the Apache License, Version 2.0 (the "License");
1052// you may not use this file except in compliance with the License.
1053// You may obtain a copy of the License at
1054//
1055// http://www.apache.org/licenses/LICENSE-2.0
1056//
1057// Unless required by applicable law or agreed to in writing, software
1058// distributed under the License is distributed on an "AS IS" BASIS,
1059// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1060// See the License for the specific language governing permissions and
1061// limitations under the License.
1062// ----------------------------- END-OF-FILE ----------------------------------
1063
1064/** @} */
1065/** @} */
1066/** @} */
Definition bslmf_invokeresult.h:362
Provide a namespace for the forwardToTarget function.
Definition bslmf_forwardingtype.h:456
Imp::Type Type
Definition bslmf_forwardingtype.h:441
Definition bslstl_function_rep.h:132
void GenericInvoker()
Definition bslstl_function_rep.h:375
Definition bslstl_function_smallobjectoptimization.h:78
#define BSLA_NORETURN
Definition bsla_noreturn.h:169
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLSTL_FUNCTION_INVOKERUTIL_CAST_RESULT(RET, X)
Definition bslstl_function_invokerutil.h:191
TP * targetRaw() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_function_rep.h:740
BloombergLP::bsls::Nullptr_Impl::Type nullptr_t
Definition bsls_nullptr.h:283
Definition bdlbb_blob.h:579
Definition bslstl_algorithm.h:84
Definition bslmf_addlvaluereference.h:128
Definition bslmf_conditional.h:123
Definition bslmf_integralconstant.h:261
Definition bslmf_isconvertible.h:875
Definition bslmf_ismemberpointer.h:143
NothrowMovableUtil_Traits< TYPE >::UnwrappedType type
Definition bslalg_nothrowmovableutil.h:376
static UnwrappedType< TYPE >::type & unwrap(TYPE &f)
Definition bslmf_functionpointertraits.h:163
Definition bslmf_memberfunctionpointertraits.h:164
Definition bslmf_memberfunctionpointertraits.h:150
t_TYPE type
Definition bslmf_movableref.h:1188
Definition bslstl_function_invokerutil.h:318
static bool isNull(const FUNC &)
Return false.
Definition bslstl_function_invokerutil.h:831
static RET invoke(const Function_Rep *rep, typename bslmf::ForwardingType< ARG0 >::Type obj)
Definition bslstl_function_invokerutil.h:646
Definition bslstl_function_invokerutil.h:223
static GenericInvoker * invokerForFunc(const bsl::nullptr_t &)
Function_Rep::GenericInvoker GenericInvoker
Definition bslstl_function_invokerutil.h:239
@ e_Null
Definition bslstl_function_invokerutil.h:229
@ e_MemDataPtr
Definition bslstl_function_invokerutil.h:232
@ e_FunctionPtr
Definition bslstl_function_invokerutil.h:230
@ e_InplaceFunctor
Definition bslstl_function_invokerutil.h:233
@ e_OutofplaceFunctor
Definition bslstl_function_invokerutil.h:234
@ e_MemFunctionPtr
Definition bslstl_function_invokerutil.h:231
static GenericInvoker * invokerForFunc(const FUNC &f)
static BSLA_NORETURN void throwBadFunctionCall()