BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlf.h
Go to the documentation of this file.
1/// @file bdlf.h
2///
3///
4/// @defgroup bdlf Package bdlf
5/// @brief Basic Development Library Functors (bdlf)
6/// @addtogroup bdl
7/// @{
8/// @addtogroup bdlf
9/// @{
10/// * <a href="#bdlf-purpose"> Purpose</a>
11/// * <a href="#bdlf-mnemonic"> Mnemonic </a>
12/// * <a href="#bdlf-description"> Description </a>
13/// * <a href="#bdlf-hierarchical-synopsis"> Hierarchical Synopsis </a>
14/// * <a href="#bdlf-component-synopsis"> Component Synopsis </a>
15/// * <a href="#bdlf-related-packages-in-package-group-bdl"> Related Packages in Package Group bdl </a>
16/// * <a href="#bdlf-relationship-to-packages-in-bdl"> Relationship to Packages in bdl </a>
17/// * <a href="#bdlf-functors-and-function-pointers"> Functors and Function Pointers </a>
18/// * <a href="#bdlf-functors-in-the-bdlf-package"> Functors in the bdlf package </a>
19/// * <a href="#bdlf-signature-specific-functors"> Signature-Specific Functors </a>
20/// * <a href="#bdlf-envelope-letter-idiom"> Envelope-Letter Idiom </a>
21/// * <a href="#bdlf-binders"> Binders </a>
22/// * <a href="#bdlf-general-function-objects"> General (Run-Time Polymorphic) Function Objects </a>
23/// * <a href="#bdlf-functors-and-binders"> Functors and Binders </a>
24/// * <a href="#bdlf-usage"> Usage </a>
25///
26/// # Purpose {#bdlf-purpose}
27/// Provide signature-specific function objects (functors).
28///
29/// # Mnemonic {#bdlf-mnemonic}
30/// Basic Development Library Functors (bdlf)
31///
32/// @see
33///
34/// # Description {#bdlf-description}
35/// The 'bdlf' package provides components to implement function
36/// objects (functors) that return void and take between zero and nine arguments
37/// of arbitrary type. Function objects created by 'bdlf' components can be
38/// invoked in a manner similar to that of the following free function:
39/// @code
40/// void functionObject(arglist);
41/// @endcode
42/// where 'arglist' contains between zero and nine arguments. Functor classes are
43/// differentiated by the number and type of arguments they expect. The 'bdlf'
44/// package contains 10 separate components that differ in the number of arguments
45/// their functors expect; within each component, templates are used to support
46/// variations in argument type.
47///
48/// In addition, three components (@ref bdlf_bind , @ref bdlf_memfn and @ref bdlf_function )
49/// provide more general functors that can conform to a specified prototype and
50/// return an arbitrary type, and that can be invoked in the same manner as
51/// before. The functors created by these two components currently support from
52/// zero up to 14 arguments. @ref bdlf_bind provides compile-time polymorphism, and
53/// adapts an invocable object so that it conforms to a different interface and
54/// can be invoked with fewer arguments and/or with the arguments in a different
55/// order. This transformation is type-safe, in that type violations provoke
56/// compilation errors. @ref bdlf_memfn provides a wrapper that allows a member
57/// function to be invoked like a free function, either by providing the object
58/// instance as first parameter, or by wrapping the object instance inside the
59/// function object. @ref bdlf_function provides run-time polymorphism and is
60/// especially suited for callbacks because it adapts any invocable with a
61/// compatible prototype to a specified callback interface, at run-time and
62/// without the need for recompilation.
63///
64/// ## Hierarchical Synopsis {#bdlf-hierarchical-synopsis}
65///
66/// The 'bdlf' package currently has 6 components having 3 levels of physical
67/// dependency. The list below shows the hierarchical ordering of the components.
68/// The order of components within each level is not architecturally significant,
69/// just alphabetical.
70/// @code
71/// 3. bdlf_bind
72///
73/// 2. bdlf_memfn
74/// bdlf_noop
75/// bdlf_overloaded
76/// bdlf_placeholder
77///
78/// 1. bdlf_noop_cpp03 !PRIVATE!
79/// @endcode
80///
81/// ## Component Synopsis {#bdlf-component-synopsis}
82///
83/// @ref bdlf_bind :
84/// Provide a signature-specific function object (functor).
85///
86/// @ref bdlf_memfn :
87/// Provide member function pointer wrapper classes and utility.
88///
89/// @ref bdlf_noop :
90/// Provide a functor class that does nothing.
91///
92/// @ref bdlf_noop_cpp03 : !PRIVATE!
93/// Provide C++03 implementation for bdlf_noop.h
94///
95/// @ref bdlf_overloaded :
96/// Provide a type for constructing overload sets.
97///
98/// @ref bdlf_placeholder :
99/// Provide a parameterized placeholder and specialized placeholders.
100///
101/// ## Related Packages in Package Group bdl {#bdlf-related-packages-in-package-group-bdl}
102///
103/// Package 'bdlf' is designed to use three other packages in 'bdl'. 'bdlf'
104/// provides the primary interface that a client will see, and the other packages
105/// play supporting roles.
106///
107/// The packages are:
108///
109/// 'bdlf':
110/// Provides functors to clients in a canonical form.
111///
112/// 'bdlfr':
113/// This package is *DEPRECATED*. A common reference-counted base class,
114/// used by 'bdlfi'. These classes provide reference counting and object
115/// deletion for derived classes.
116///
117/// 'bdlfi':
118/// This package is *DEPRECATED*. Concrete reference-counted function
119/// objects, held and managed by a 'bdlf' object; classes in 'bdlfi'
120/// implement behavior declared in 'bdlfr'.
121///
122/// 'bdlfu':
123/// This package is *DEPRECATED*. Factory method utilities to initialize
124/// 'bdlf' functors by creating a reference-counted function object (from
125/// 'bdlfi') and assigning it to a 'bdlf' functor. Subsequent invocations of
126/// the 'bdlf' functor will be delegated to the 'bdlfi' object.
127///
128/// ## Relationship to Packages in bdl {#bdlf-relationship-to-packages-in-bdl}
129///
130/// The 'bdlf', 'bdlfr', 'bdlfi', and 'bdlfu' packages provide identical
131/// functionality to the corresponding packages in the 'bce' package group:
132/// 'bcef', 'bcefr', 'bcefi', and 'bcefu', respectively. The difference between
133/// the two sets of packages is that the 'bce' packages provide thread safety,
134/// whereas the 'bdl' packages do not. In particular, package 'bcefr' implements
135/// reference counting via atomic operators provided in package @ref bces_atomicutil .
136///
137/// ## Functors and Function Pointers {#bdlf-functors-and-function-pointers}
138///
139/// Function pointers should be familiar to both C and C++ programmers. A
140/// function pointer is a pointer to a C-style function. In C++, the function
141/// pointer is declared to point to a function with a specific return type and a
142/// specific number of arguments of specific types. For instance,
143/// @code
144/// void (*fp)(int, const char*);
145/// @endcode
146/// declares a function pointer 'fp' that points to a function returning 'void',
147/// and taking exactly two arguments, an 'int' and a const pointer to 'char'.
148///
149/// Assume, then, that we have one or more functions declared with the matching
150/// signature:
151/// @code
152/// void f1(int x, const char* s);
153/// void f2(int x, const char* s);
154/// @endcode
155/// After assigning a value to the function pointer, we can call the corresponding
156/// function:
157/// @code
158/// fp = f1;
159/// .
160/// .
161/// .
162/// int my_x = 0;
163/// int my_s = "Text String";
164/// fp(my_x, my_s); // invokes function f1
165/// @endcode
166/// Functors are objects that behave syntactically and semantically like
167/// functions. Functors implement a function-call operator ('operator()') whose
168/// signature characterizes the particular functor's type. In this example, for
169/// instance, we could define a functor like this:
170/// @code
171/// class MyFunctor {
172/// // Class MyFunctor can be used like a function.
173/// .
174/// .
175/// .
176/// public:
177/// void operator()(int x, const char* s);
178/// // this provides invocation semantics
179/// .
180/// .
181/// .
182/// };
183///
184/// MyFunctor fn;
185/// .
186/// .
187/// .
188/// int my_x = 0;
189/// int my_s = "Text String";
190/// fn(my_x, my_s); // "invokes" functor fn via fn::operator()
191/// @endcode
192/// Functors provide some interesting advantages over simple function pointers.
193/// Unlike a function pointer, a functor may be created with one or more arbitrary
194/// objects (sometimes called "user data") to be passed (typically as trailing
195/// arguments) to the underlying function. By "pre-binding" particular arguments
196/// to the underlying function, a functor can reduce the number of arguments a
197/// caller must supply when the functor is invoked. In this way, function objects
198/// can be used to coerce functions with extra arguments of arbitrary type into a
199/// standard calling signature. Even (non-'static') *member* functions can be
200/// encapsulated within functors and treated uniformly, simply by supplying the
201/// appropriate object at construction. Both the *object* pointer and a *member*
202/// *function* pointer are stored in the functor; the given object pointer is
203/// dereferenced when the functor is invoked.
204///
205/// ## Functors in the bdlf package {#bdlf-functors-in-the-bdlf-package}
206///
207///
208/// ### Signature-Specific Functors {#bdlf-signature-specific-functors}
209///
210/// Individual components are "numbered" to indicate the number of arguments
211/// (between 0 and 6) that a particular functor accepts. Each component defines a
212/// templated class, whose template parameters correspond in number to the functor
213/// arguments. When instantiated, the template argument types match the argument
214/// types used in invoking the functor. The component name is @ref bdlf_vfunc
215/// followed by 0 to 6; the letter 'v' indicates that the corresponding functor
216/// will return 'void'. For the example above, we would use component
217/// @ref bdlf_vfunc2 to create a functor object whose 'operator()' member function
218/// obeys the required signature.
219/// @code
220/// #include <bdlf_vfunc2.h>
221///
222/// bdlf_Vfunc2<int, const char*> fn; // template arguments specify arg
223/// // types
224/// // NOTE: This example is incomplete.
225/// // We still need code to initialize 'fn'
226/// .
227/// .
228/// .
229/// int my_x = 0;
230/// int my_s = "Text String";
231/// fn(my_x, my_s); // "invokes" functor fn
232/// @endcode
233/// Before a 'bdlf' functor is invoked as illustrated, the client is responsible
234/// for ensuring that it is valid; that is, it must contain a pointer to a
235/// function that will be called when the functor is invoked. The function to be
236/// called is external to the functor, and supplied by the client. This "external
237/// function" may be a free function, a static class method, or a (non-'static')
238/// member function for some class. The client, then, needs a canonical
239/// mechanism, regardless of the function type, to create a reference to that
240/// function, and to bind the reference to the 'bdlf' functor.
241///
242/// The most common way to accomplish this is to use a "factory method" defined in
243/// the 'bdlfu' package. The 'bdlfu' package contains 10 components which provide
244/// these factory methods. Parallel to 'bdlf', these components are "numbered" to
245/// support functors with different numbers of arguments. The factory methods are
246/// also templatized to support varying argument types.
247///
248/// Each 'bdlfu' component contains 4 different types of factory methods, varying
249/// by the type of function pointer required. For example, @ref bdlfu_vfunc2 defines
250/// the following *factory* *method* *families*:
251/// @code
252/// bdlfu_Vfunc2::makeF(); // generate a pointer to a free function
253/// // and assign it to a 'bdlf_Vfunc2' object
254/// bdlfu_Vfunc2::makeM(); // generate a pointer to a member function
255/// // and assign it to a 'bdlf_Vfunc2' object
256/// bdlfu_Vfunc2::makeC() // generate a pointer to a const member
257/// // function and assign it to a 'bdlf_Vfunc2'
258/// // object
259/// bdlfu_Vfunc2::makeNull(); // initialize a 'bdlf_Vfunc2' object with
260/// // an empty function
261/// @endcode
262/// These factory methods (except for 'makeNull') are templatized to support
263/// different return and argument types; in addition, each *factory* *method*
264/// *family* consists of a set of overloaded functions that support varying
265/// numbers of arguments on the underlying functions (member or free). All
266/// classes returned by functions in component @ref bdlfu_vfunc2 are defined in
267/// component @ref bdlfi_vfunc2 . See package documentation for the {'bdlfu'} package
268/// for details.
269///
270/// For the simple example above, we would use component 'bdlfu_Vfunc2' as follows
271/// to initialize the 'bdlf_Vfunc2' object:
272/// @code
273/// #include <bdlf_vfunc2.h>
274/// #include <bdlfu_vfunc2.h>
275///
276/// void f1(int x, const char* s);
277/// void f2(int x, const char* s);
278///
279/// bdlf_Vfunc2<int, const char*> fn; // template arguments define arg types
280/// bdlfu_Vfunc2::makeF(&fn,f1); // bind functor fn to function f1
281/// .
282/// .
283/// .
284/// int my_x = 0;
285/// int my_s = "Text String";
286/// fn(my_x, my_s); // "invokes" functor fn
287/// @endcode
288/// The 'bdlfu_Vfunc2::makeF' *factory* *method* in the above example expects two
289/// arguments. The first is a pointer to the functor object itself, and the
290/// second is a pointer to a free function with a signature matching the functor
291/// object, that is, expecting args of 'int' and 'const char*', and returning
292/// 'void'.
293///
294/// The 'makeF()' functions create instances of classes from the 'bdlfi'
295/// component; the specific classes are determined by the number and types of
296/// arguments on the 'bdlf' functor and the free function. Similarly, class
297/// member functions can be used to initialize a 'bdlf' functor by invoking a
298/// 'bdlfu_Vfunc2::makeM()' or 'bdlfu_Vfunc2::makeC()' function.
299///
300/// The 'bdlfu' and 'bdlfi' packages will also allow clients to match a functor to
301/// a free or member function in situations where the function requires more
302/// arguments than the functor invocation can support. See the documentation for
303/// package {'bdlfu'} for details describing how to do this; see package
304/// documentation for {'bdlfi'} for implementation details.
305///
306/// Note that because each required argument type 'T' is passed by ('const' 'T&'),
307/// a compiler will generate an error if the user declares a callback function
308/// taking an argument via a non-'const' reference parameter. This is intended to
309/// support and enforce the rule that all modifiable arguments are passed using
310/// pointers and not using references. For rare situations where clients want to
311/// use a callback function supplied by a third party, and that callback function
312/// uses non-'const' references, a wrapper function must be declared that converts
313/// non-'const' references to 'const' references or pointers as appropriate.
314///
315/// ### Envelope-Letter Idiom {#bdlf-envelope-letter-idiom}
316///
317/// The functors in the 'bdlf' package are implemented using the envelope-letter
318/// idiom. The classes in 'bdlf' are *"envelopes"*; classes in 'bdlfr' and
319/// 'bdlfi' are *"letters"*. The use of the envelope-letter idiom allows clients
320/// to wrap arbitrary functions, whose signatures may differ from the function
321/// signatures in 'bdlf', with functors that support standard, well-known
322/// signatures.
323///
324/// Each 'bdlf_Vfunc*' functor *(envelope)* holds a pointer to an
325/// object *(letter)* from the corresponding 'bdlfi_vfunc*' component. The 'bdlf'
326/// *envelope* forwards or delegates client requests to its *letter* object: in
327/// particular, the 'operator()' member function used by clients to invoke the
328/// functor is delegated to the *letter* object for execution.
329///
330/// The *letter* object is polymorphic: all *letter* classes in a given 'bdlfi'
331/// component are derived from a common protocol or abstract base class (defined
332/// in 'bdlfr'). The 'bdlf' *envelope* uses the abstract 'bdlfr' protocol to
333/// delegate invocation requests. Different polymorphic *letter* types are used
334/// to support different external function types and signatures, and the single
335/// *envelope* type is used to provide a consistent function signature to clients.
336///
337/// Since polymorphism is used to support different bindings to external member or
338/// free functions, clients must be able to generate a specific type of *letter*
339/// object for a given *envelope*, based upon the type and signature of the
340/// specific external function. This may be done directly through public
341/// interfaces of the corresponding 'bdlfi' component, but in most cases it is
342/// simpler to use a suite of template functions provided by the corresponding
343/// 'bdlfu' package. Different template functions are provided to match (1) the
344/// desired function-call-operator signature and (2) the supplied user data.
345/// Because the C++ compiler will deduce template parameters from argument types,
346/// clients need not specify them. See the {'bdlfu'} package for more information
347/// on populating 'bdlf' functors with specific *letter* objects.
348///
349/// See also J.O. Coplien, "Advanced Programming Styles and Idioms", Sections
350/// 5.5-5.6, for a complete discussion of the envelope/letter idiom.
351///
352/// ### Binders {#bdlf-binders}
353///
354/// The @ref bdlf_bind component provides a mechanism for creating function objects
355/// different from the 'bdlf_vfunc*' components. @ref bdlf_bind is used to *adapt*
356/// an invocable object so that it conforms to a different interface and can be
357/// invoked with fewer arguments and/or with the arguments in a different order.
358/// It does this by *binding* some or all of the original invocable's arguments to
359/// fixed values that are known at construction time and binding the remaining
360/// arguments to placeholders for arguments that are provided at invocation time.
361/// A binder can be used as an argument for any template function that requires an
362/// invocable with compatible parameters.
363///
364/// The @ref bdlf_bind component defines binder objects and factory methods that can
365/// bind any arguments into a functor in any order, enabling some of the arguments
366/// of the invocable to be specified at the construction time, and leaving (via
367/// place-holders, defined in component @ref bdlf_placeholder ) some others to be
368/// specified (later) at invocation time. A binder is created by one of the three
369/// *factory* *method* *families* defined in component @ref bdlf_bind :
370/// @code
371/// bdlf_BindUtil::bind(); // generate a binder with specified invocable and
372/// // bound arguments (invocation arguments are
373/// // indicated by place-holders)
374/// bdlf_BindUtil::bindA(); // same as above but also specify the allocator
375/// // used to supply memory for creating the binder
376/// bdlf_BindUtil::bindR(); // same as 'bdlf_BindUtil::bind()' but explicitly
377/// // specify the return type (in case it cannot be
378/// // deduced by the compiler but should not be left
379/// // undefined)
380/// @endcode
381/// Binders where the signature of the invocable can be deduced are called
382/// *explicit*. Not all binders are explicit. For non-explicit binders, the
383/// signature of a 'bdlf_Bind' object is not embedded in the type, and several
384/// overloads can be invoked through the same binder. Unlike 'bdlf_Vfunc*'
385/// objects, different binders accepting the same signature may have different
386/// types depending on the types of the bound arguments if they are non-explicit.
387/// The return type (not necessarily void) is also part of the signature. Thus,
388/// @ref bdlf_bind provides compile-time polymorphism but not run-time polymorphism.
389///
390/// A broad discussion of binding, along with limitations of the 'usage examples,
391/// can be found in the component documentation of component @ref bdlf_bind .
392///
393/// ### General (Run-Time Polymorphic) Function Objects {#bdlf-general-function-objects}
394///
395/// In addition to signature-specific objects and binders, the 'bdlf' package
396/// provides a run-time polymorphic 'bdlf_Function' template. A 'bdlf_Function'
397/// instantiation is capable of holding *any* invocable object of compatible
398/// prototype, including a function pointer, 'bdlf_MemFn' wrapper, any concrete
399/// implementation of the 'bdlfr_Vfunc*'protocols, any instances of the
400/// 'bdlf_Vfunc' family, and any other function object having an 'operator()'
401/// method including an instance of a 'bdlf_Bind' instantiation.
402///
403/// Like a binder, a 'bdlf_Function' instantiation can have a return value (or
404/// return 'void'). An instance does not store bound arguments directly. It
405/// accepts all its arguments at invocation time only, although using polymorphic
406/// representations and the 'bdlfu_Vfunc*::make*' factory methods, it is possible
407/// to bind the last arguments of an invocable and wrap this into a
408/// 'bdlf_Function' object which will then accept only the remaining arguments
409/// upon invocation. As mentioned above, it is also possible to assign a
410/// 'bdlf_Bind' object to a 'bdlf_Function' instance to bind and route arguments
411/// to the invocable in an arbitrary manner.
412///
413/// Unlike a binder, the signature of a 'bdlf_Function' object is part of the type
414/// and invocation arguments are cast to their corresponding type before they are
415/// passed to the invocable. Most importantly, the same functor may be assigned
416/// from various types (pointer to function, 'bdlf_MemFn' wrapper, user-defined
417/// function objects, or even 'bdlf_Bind' binders).
418///
419/// ### Functors and Binders {#bdlf-functors-and-binders}
420///
421/// 'bdlf_Function' objects (functors) and 'bdlf_Bind' objects (binders) are both
422/// mechanisms for binding arguments and calling an invocable. They differ in
423/// their purpose, though. In the last section, we detailed the main features of
424/// the @ref bdlf_function and @ref bdlf_bind components. In this section we point out
425/// the differences, and how they interact.
426///
427/// The main difference is compile-time (for @ref bdlf_bind ) vs. run-time (for
428/// @ref bdlf_function ) polymorphism. An instantiation of 'bdlf_Function' is a type
429/// of functor that can hold any invocable object with compatible prototype.
430/// Regardless of what type of (compatible) invocable is used to create the
431/// 'bdlf_Function', the type of the resulting functor does not change. Thus,
432/// 'bdlf_Function' has run-time polymorphism and is ideally suited for callbacks
433/// because it *adapts* the invocable to the callback interface. Run-time
434/// polymorphism is extremely useful for defining callback types and storing
435/// callbacks, since passing a new type of callback does not require
436/// re-compilation. Compile-time polymorphism provides the ability to invoke
437/// several overloads through the same functor (binder) and to bind and route
438/// arguments to the invocable in an arbitrary manner.
439///
440/// In cases where both binders and functors could be used, 'bdlf_Function' has
441/// certain advantages, not least of which is simplicity (leading to shorter
442/// compilation times), and the memory optimization documented below, whereby
443/// small objects are constructed in-place but larger objects are dynamically
444/// allocated. Note that binders are always constructed in-place and can have
445/// rather large footprints. Functors (including instances of 'bdlfr_Vfunc*'
446/// derived types) can implement various strategies like sharing and copy-on-write
447/// to reduce the cost of copying and the footprint at the same time.
448///
449/// ## Usage {#bdlf-usage}
450///
451/// 'bdlf'-style functors provide a type-neutral, exception-safe (and
452/// *potentially*, but not yet, thread-safe) *properly* *managed* alternative to
453/// the traditional callback paradigm (where "client data" is placed in a single
454/// structure whose address is cast to type 'void *'). The following example
455/// illustrates how functor callbacks can be added to a graphical object.
456///
457/// Let's suppose that the implementor of the 'MyGuiButton' class allows the
458/// client to specify a callback function that should be called whenever a button
459/// is pressed. Furthermore, the implementor agrees to provide to the callback
460/// function two arguments at its invocation: a modifiable object of type
461/// 'MyGuiContext', and a non-modifiable object of type 'MyGuiLocation'.
462/// @code
463/// class MyGuiContext {
464/// int d_changedFlag;
465///
466/// public:
467/// MyGuiContext() : d_changedFlag(0) { }
468/// int isChanged() { return d_changedFlag; }
469/// void changeState() { ++d_changedFlag; }
470///
471/// // 'MyGuiContext' implementation
472/// };
473///
474/// class MyGuiLocation {
475/// public:
476/// MyGuiLocation() { };
477///
478/// // 'MyGuiLocation' implementation
479/// };
480/// @endcode
481/// Here is the implementation of the 'MyGuiButton' class:
482/// @code
483/// class MyGuiButton {
484/// bdlf_Vfunc2<MyGuiContext *, MyGuiLocation> d_callback;
485/// // Functor to execute when button is pressed.
486///
487/// public:
488/// MyGuiButton(const bdlf_Vfunc2<MyGuiContext *,
489/// MyGuiLocation>& buttonPressCallback);
490/// // Create a graphical button object that executes the
491/// // specified callback when 'pressButton' is invoked.
492///
493/// void pressButton(MyGuiContext *context,
494/// const MyGuiLocation& location);
495/// // Execute the callback owned by this button object.
496/// };
497///
498/// MyGuiButton::MyGuiButton(const bdlf_Vfunc2<MyGuiContext *,
499/// MyGuiLocation>& buttonPressCallback)
500/// : d_callback(buttonPressCallback) // Retain a "copy" of the specified
501/// // functor.
502/// {
503/// }
504///
505/// void MyGuiButton::pressButton(MyGuiContext *context,
506/// const MyGuiLocation& location)
507/// {
508/// d_callback(context, location);
509/// // Execute the contained callback object.
510/// }
511/// @endcode
512/// The 'context' and 'location' arguments are mandatory for every function called
513/// at the press of the button (the number '2' in the name of 'bdlf_Vfunc2' class
514/// specifies the number of required arguments). However, we also allow the user
515/// of 'MyGuiButton' class to invoke the function with a number of additional
516/// parameters, as in the 'buttonpressFunction' function presented below.
517/// @code
518/// static void buttonpressFunction(MyGuiContext *a,
519/// const MyGuiLocation& b,
520/// int *invocationCounter)
521/// // This function will be invoked by a functor to increment the
522/// // specified 'invocationCounter'.
523/// {
524/// a->changeState();
525/// ++*invocationCounter;
526/// }
527/// @endcode
528/// The 'bdlf_Vfunc2<MyGuiContext, MyGuiLocation>' class used in 'MyGuiButton'
529/// class has a private member of an abstract class @ref bdlfr_vfunc2 , whose
530/// 'execute' method is called when the functor is being called. The 'execute'
531/// method of the @ref bdlfr_vfunc2 class, the functor invocation operator of the
532/// 'bdlf_Vfunc2' class, and the 'pressButton' method of 'MyGuiButton' class have
533/// two parameters. The 'buttonpressFunction' callback function, however, has to
534/// be called with three arguments. To achieve the proper calling signature the
535/// user implements a concrete class derived from @ref bdlfr_vfunc2 as follows:
536/// @code
537/// template <class F, class A1, class A2, class D1>
538/// class FuncRep : public bdlfr_Vfunc2<A1, A2> {
539/// // This class defines the representation for a function object (functor),
540/// // characterized by a function-call operator taking two arguments and
541/// // returning 'void', that holds a pure procedure (i.e., free function,
542/// // static member function, or functor) taking one additional trailing
543/// // argument, and this argument's corresponding value.
544///
545/// F d_f; // function pointer or function object (functor)
546/// D1 d_d1; // first embedded argument
547///
548/// private:
549/// // not implemented
550/// FuncRep(const FuncRep<F, A1, A2, D1>&);
551/// FuncRep<F, A1, A2, D1>& operator=(const FuncRep<F, A1, A2, D1>&);
552///
553/// private:
554/// ~FuncRep()
555/// // Destroy this functor. Note that destructor can be invoked only
556/// // through the static 'deleteObject' method of the base class.
557/// {
558/// };
559///
560/// public:
561/// // CREATORS
562/// FuncRep(const F& procedure,
563/// const D1& embeddedArg1,
564/// bdlma_Allocator *basicAllocator)
565/// // Create a representation for a function object (functor) taking two
566/// // arguments and returning 'void', using the specified 'procedure'
567/// // taking 1 additional trailing argument, and this argument's
568/// // specified 'embeddedArg1' value. Use the specified
569/// // 'basicAllocator' to supply memory.
570/// : bdlfr_Vfunc1<A1, A2>(basicAllocator)
571/// , d_f(procedure)
572/// , d_d1(embeddedArg1)
573/// {
574/// };
575///
576/// // ACCESSORS
577/// void execute(const A1& argument1, const A2& argument2) const
578/// // Invoke the underlying procedure (free function, static member
579/// // function, or functor) with the specified 'argument1' and
580/// // 'argument2' followed by the argument value specified at
581/// // construction.
582/// {
583/// d_f(argument1, argument2, d_d1);
584/// };
585/// };
586/// @endcode
587/// Note that the required arguments are passed in at the functor invocation, and
588/// optional arguments are passed in at the functor initialization. By BDE
589/// convention, a function signature consists of output parameters, and then input
590/// parameters. Since here we have two parameter lists (one passed in by the
591/// caller, and one passed in by the callee) we can follow this convention within
592/// each list only. We choose to pass in first the required arguments (passed by
593/// the caller) and then the optional arguments (supplied by the callee). This
594/// order allows a callee to add parameters easily at the end of the function
595/// parameter list. The number of required parameters is a part of the
596/// 'MyGuiButton' interface, and hence will never change.
597///
598/// The following code shows how we:
599///
600/// 1. Create the functor representation-(letter).
601///
602/// 2. Create the functor initialized with the representation.
603///
604/// 3. Register the functor as a callback with an instance of the 'MyGuiButton'
605/// class.
606///
607/// 4. Invoke the functor.
608///
609/// The code is as follows:
610/// @code
611/// // (1) Create the representation.
612///
613/// typedef void (*BpFun)(const MyGuiContext *, const MyGuiLocation&, int *);
614/// bdlma_Allocator *myAllocator = bdlma_Default::defaultAllocator();
615///
616/// int globalCounter = 0;
617///
618/// bdlfr_Vfunc2<MyGuiContext *, MyGuiLocation> *rep = new(myAllocator)
619/// FuncRep<BpFun, MyGuiContext *, MyGuiLocation, int*>
620/// (buttonpressFunction, &globalCounter, myAllocator);
621///
622/// // (2) Create the functor using the representation.
623///
624/// bdlf_Vfunc2<MyGuiContext *, MyGuiLocation> callbackFunctor(rep);
625///
626/// // (3) Register the functor as a callback.
627///
628/// MyGuiButton button(callbackFunctor);
629///
630/// // (4) Use the object.
631///
632/// MyGuiContext gc;
633/// const MyGuiLocation gl; assert(0 == globalCounter);
634/// assert(0 == gc.isChanged());
635/// button.pressButton(&gc, gl); assert(1 == globalCounter);
636/// assert(1 == gc.isChanged());
637/// button.pressButton(&gc, gl); assert(2 == globalCounter);
638/// assert(2 == gc.isChanged());
639/// @endcode
640///
641/// @}
642/** @} */