]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [library Boost.FunctionTypes |
2 | [quickbook 1.3] | |
3 | [version 2.5] | |
4 | [authors [Schwinger, Tobias]] | |
5 | [copyright 2004-2007 Tobias Schwinger] | |
6 | [license | |
7 | Distributed under the Boost Software License, Version 1.0. | |
8 | (See accompanying file LICENSE_1_0.txt or copy at | |
9 | [@http://www.boost.org/LICENSE_1_0.txt]) | |
10 | ] | |
11 | [purpose Meta-programming support library] | |
12 | [category template] | |
13 | [category generic] | |
14 | [last-revision $Date$] | |
15 | ] | |
16 | ||
17 | [def __unspecified__ /unspecified/] | |
18 | ||
19 | [def __mpl__ [@../../../mpl/index.html MPL]] | |
20 | [def __mpl_integral_constant__ __mpl__ - [@../../../mpl/doc/refmanual/integral-constant.html Integral Constant]] | |
21 | [def __mpl_fwd_seq__ __mpl__ - [@../../../mpl/doc/refmanual/forward-sequence.html Forward Sequence]] | |
22 | [def __mpl_fb_ext_ra_seq__ __mpl__ - [@../../../mpl/doc/refmanual/front-extensible-sequence.html Front] / [@../../../mpl/doc/refmanual/back-extensible-sequence.html Back ][@../../../mpl/doc/refmanual/extensible-sequence.html Extensible ][@../../../mpl/doc/refmanual/random-access-sequence.html Random Access Sequence]] | |
23 | [def __mpl_lambda_expression__ __mpl__ - [@../../../mpl/doc/refmanual/lambda-expression.html Lambda Expression]] | |
24 | ||
25 | [def __is_function [link boost_functiontypes.reference.classification.is_function is_function]] | |
26 | [def __is_function_pointer [link boost_functiontypes.reference.classification.is_function_pointer is_function_pointer]] | |
27 | [def __is_function_reference [link boost_functiontypes.reference.classification.is_function_reference is_function_reference]] | |
28 | [def __is_member_function_pointer [link boost_functiontypes.reference.classification.is_member_function_pointer is_member_function_pointer]] | |
29 | [def __is_callable_builtin [link boost_functiontypes.reference.classification.is_callable_builtin is_callable_builtin]] | |
30 | [def __is_nonmember_callable_builtin [link boost_functiontypes.reference.classification.is_nonmember_callable_builtin is_nonmember_callable_builtin]] | |
31 | ||
32 | [def __components [link boost_functiontypes.reference.decomposition.components components]] | |
33 | [def __parameter_types [link boost_functiontypes.reference.decomposition.parameter_types parameter_types]] | |
34 | [def __function_arity [link boost_functiontypes.reference.decomposition.function_arity function_arity]] | |
35 | [def __result_type [link boost_functiontypes.reference.decomposition.result_type result_type]] | |
36 | ||
37 | [def __function_type [link boost_functiontypes.reference.synthesis.function_type function_type]] | |
38 | [def __function_pointer [link boost_functiontypes.reference.synthesis.function_pointer function_pointer]] | |
39 | [def __function_reference [link boost_functiontypes.reference.synthesis.function_reference function_reference] | |
40 | [def __member_function_pointer [link boost_functiontypes.reference.synthesis.member_function_pointer member_function_pointer]] | |
41 | ||
42 | [def __null_tag [link boost_functiontypes.reference.tag_types.null_tag null_tag]] | |
43 | ||
44 | [/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] | |
45 | ||
46 | [section:introduction Introduction] | |
47 | ||
48 | Boost.FunctionTypes provides functionality to classify, decompose and synthesize | |
49 | function, function pointer, function reference and pointer to member types. | |
50 | ||
51 | We collectively refer to these types as /callable builtin/ types. | |
52 | ||
53 | In particular, the library can be used to: | |
54 | ||
55 | * test whether a type is a specific callable, builtin type, | |
56 | * extract all component properties from callable, builtin types, and | |
57 | * create callable, builtin types from specified properties. | |
58 | ||
59 | The library is designed to work well with other Boost libraries and uses | |
60 | well-accepted concepts introduced by Boost and TR1. | |
61 | ||
62 | Templates that encapsulate boolean or numeric properties define a static member | |
63 | constant called [^value]. | |
64 | ||
65 | __is_function_pointer< bool(*)(int) >::value // == true | |
66 | ||
67 | __function_arity< bool(*)(int) >::value // == 1 | |
68 | ||
69 | Templates that encapsulate properties that are single types contain a type | |
70 | member called [^type]. | |
71 | ||
72 | __function_type< mpl::vector<bool,int> >::type // is bool(int) | |
73 | ||
74 | __result_type< bool(&)(int) >::type // is bool | |
75 | ||
76 | Templates that encapsulate properties that are type lists model an | |
77 | MPL-compatible type sequence. | |
78 | ||
79 | __parameter_types< bool(int) > // models an MPL sequence | |
80 | ||
81 | [endsect] | |
82 | ||
83 | [section:use_cases Use Cases] | |
84 | ||
85 | Generic libraries that accept callable arguments are common in C++. | |
86 | Accepting a callable argument of builin type often involves a lot of repetitive | |
87 | code because the accepting function is overloaded for different function | |
88 | arities. Further, member functions may have [^const]/[^volatile]-qualifiers, | |
89 | a function may take a variable number of (additional, POD-typed) arguments (such | |
90 | as [^printf]) and several C++ implementations encode a calling convention with | |
91 | each function's type to allow calls across language or (sub-)system boundaries. | |
92 | ||
93 | template<typename R> | |
94 | void accept_function(R(* func)()); | |
95 | ||
96 | template<typename R> | |
97 | void accept_function(R(& func)()); | |
98 | ||
99 | template<typename R, typename C> | |
100 | void accept_function(R(C::* func)()); | |
101 | ||
102 | template<typename R, typename C> | |
103 | void accept_function(R(C::* func)() const); | |
104 | ||
105 | template<typename R, typename C> | |
106 | void accept_function(R(C::* func)() volatile); | |
107 | ||
108 | template<typename R, typename C> | |
109 | void accept_function(R(C::* func)() const volatile); | |
110 | ||
111 | template<typename R> | |
112 | void accept_function(R(* func)(...)); | |
113 | ||
114 | template<typename R> | |
115 | void accept_function(R(& func)(...)); | |
116 | ||
117 | template<typename R, typename C> | |
118 | void accept_function(R(C::* func)(...)); | |
119 | ||
120 | template<typename R, typename C> | |
121 | void accept_function(R(C::* func)(...) const); | |
122 | ||
123 | template<typename R, typename C> | |
124 | void accept_function(R(C::* func)(...) volatile); | |
125 | ||
126 | template<typename R, typename C> | |
127 | void accept_function(R(C::* func)(...) const volatile); | |
128 | ||
129 | // ... | |
130 | ||
131 | // needs to be repeated for every additional function parameter | |
132 | // times the number of possible calling conventions | |
133 | ||
134 | The "overloading approach" obviously does not scale well: There might be several | |
135 | functions that accept callable arguments in one library and client code might | |
136 | end up using several libraries that use this pattern. | |
137 | On the developer side, library developers spend their time solving the same | |
138 | problem, working around the same portability issues, and apply similar | |
139 | optimizations to keep the compilation time down. | |
140 | ||
141 | Using Boost.FunctionTypes it is possible to write a single function template | |
142 | instead: | |
143 | ||
144 | template<typename F> | |
145 | void accept_function(F f) | |
146 | { | |
147 | // ... use Boost.FunctionTypes to analyse F | |
148 | } | |
149 | ||
150 | The combination with a tuples library that provides an invoker component, such | |
151 | as [@../../../fusion/index.html Boost.Fusion], allows to build flexible callback | |
152 | facilities that are entirely free of repetitive code as shown by the | |
153 | [@../../../function_types/example/interpreter.hpp interpreter example]. | |
154 | ||
155 | When taking the address of an overloaded function or function template, the | |
156 | type of the function must be known from the context the expression is used | |
157 | in. The code below shows three examples for choosing the [^float(float)] | |
158 | overload of [^std::abs]. | |
159 | ||
160 | float (*ptr_absf)(float) = & std::abs; | |
161 | ||
162 | ||
163 | void foo(float(*func)(float)); | |
164 | ||
165 | void bar() | |
166 | { | |
167 | foo(& std::abs); | |
168 | } | |
169 | ||
170 | ||
171 | std::transform(b, e, o, static_cast<float(*)(float)>(& std::abs)); | |
172 | ||
173 | The library's type synthesis capabilities can be used to automate overload | |
174 | selection and instantiation of function templates. Given an overloaded function | |
175 | template | |
176 | ||
177 | template<typename R, typename T0> | |
178 | R overloaded(T0); | |
179 | ||
180 | template<typename R, typename T0, typename T1> | |
181 | R overloaded(T0,T1); | |
182 | ||
183 | template<typename R. typename T0, typename T1, typename T2> | |
184 | R overloaded(T0,T1,T2); | |
185 | ||
186 | we can pick any of the three overloads and instantiate the template with | |
187 | template arguments from a type sequence in a single expression: | |
188 | ||
189 | static_cast<__function_pointer<Seq>::type>(& overloaded) | |
190 | ||
191 | This technique can be occasionally more flexible than template argument | |
192 | deduction from a function call because the exact types from the sequence | |
193 | are used to specialize the template (including possibly cv-qualified | |
194 | reference types and the result type). It is applied twice in the | |
195 | [@../../../function_types/example/interface.hpp interface example]. | |
196 | ||
197 | Another interersting property of callable, builtin types is that they can be | |
198 | valid types for non-type template parameters. This way, a function can be | |
199 | pinpointed at compile time, allowing the compiler to eliminate the call by | |
200 | inlining. | |
201 | The [@../../../function_types/example/fast_mem_fn.hpp fast_mem_fn example] | |
202 | exploits this characteristic and implements a potentially inlining version of | |
203 | [@../../../bind/mem_fn.html boost::mem_fn] | |
204 | limited to member functions that are known at compile time. | |
205 | ||
206 | [endsect] | |
207 | ||
208 | ||
209 | [/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] | |
210 | [section:about_tag_types About Tag Types] | |
211 | ||
212 | Boost.FunctionTypes uses tag types to encode properties that are not types | |
213 | per se, such as calling convention or whether a function is variadic or cv- | |
214 | qualified. | |
215 | ||
216 | These tags can be used to determine whether one property of a type has a | |
217 | particular value. | |
218 | ||
219 | is_function<int(...), variadic>::value // == true | |
220 | is_function<int() , variadic>::value // == false | |
221 | ||
222 | A compound property tag describes a combination of possible values of different | |
223 | properties. | |
224 | The type [^components<F>], where [^F] is a callable builtin type, is a compound | |
225 | property tag that describes [^F]. | |
226 | The [^tag] class template can be used to combine property tags. | |
227 | ||
228 | tag<non_const,default_cc> // combination of two properties | |
229 | ||
230 | When several values for the same property are specified in [^tag]'s argument | |
231 | list, only the rightmost one is used; others are ignored. | |
232 | ||
233 | tag<components<F>, default_cc> // overrides F's calling convention property | |
234 | ||
235 | When compound property tag is specified to analyse a type, all of its component | |
236 | properties must match. | |
237 | ||
238 | is_member_function_pointer< F, tag<const_qualified,default_cc> >::value | |
239 | // true for | |
240 | // F = void(a_class::*)() const | |
241 | // false for | |
242 | // F = void(a_class::*)() | |
243 | // F = void(__fastcall a_class::*)() const | |
244 | ||
245 | Default values are selected for properties not specified by the tag in the | |
246 | context of type synthesis. | |
247 | ||
248 | // given S = mpl::vector<int,a_class const &> | |
249 | ||
250 | member_function_pointer<S>::type // is int (a_class::*)() const | |
251 | // note: the cv-qualification is picked based on the class type, | |
252 | // a nonvariadic signature and the default calling convention | |
253 | // are used | |
254 | ||
255 | member_function_pointer<S,non_const>::type // is int (a_class::*)() | |
256 | // no const qualification, as explicitly specified by the tag type | |
257 | ||
258 | [endsect] | |
259 | ||
260 | ||
261 | [/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] | |
262 | ||
263 | [section:reference Reference] | |
264 | ||
265 | ||
266 | [section:classification Class templates for type classification] | |
267 | ||
268 | [section:is_function is_function] | |
269 | ||
270 | template<typename T, typename Tag = __null_tag> | |
271 | struct is_function; | |
272 | ||
273 | [*Header] | |
274 | ||
275 | #include <boost/function_types/is_function.hpp> | |
276 | ||
277 | [variablelist | |
278 | [[[^T]][Type to analyze]] | |
279 | [[[^Tag]][Further properties required for a positive result]] | |
280 | [[[^is_function<T,Tag>]][Predicate value as __mpl_integral_constant__]] | |
281 | [[[^is_function<T,Tag>::value]][Constant boolean value]] | |
282 | ] | |
283 | ||
284 | Determines whether a given type is a function, possibly with | |
285 | additional properties as specified by a property tag. | |
286 | ||
287 | [endsect] | |
288 | ||
289 | ||
290 | [section:is_function_pointer is_function_pointer] | |
291 | ||
292 | template<typename T, typename Tag = __null_tag> | |
293 | struct is_function_pointer; | |
294 | ||
295 | [*Header] | |
296 | ||
297 | #include <boost/function_types/is_function_pointer.hpp> | |
298 | ||
299 | [variablelist | |
300 | [[[^T]][Type to analyze]] | |
301 | [[[^Tag]][Further properties required for a positive result]] | |
302 | [[[^is_function_pointer<T,Tag>]][Predicate value __mpl_integral_constant__]] | |
303 | [[[^is_function_pointer<T,Tag>::value]][Constant boolean value]] | |
304 | ] | |
305 | ||
306 | Determines whether a given type is a function pointer, possibly with | |
307 | additional properties as specified by a property tag. | |
308 | ||
309 | [endsect] | |
310 | ||
311 | ||
312 | [section:is_function_reference is_function_reference] | |
313 | ||
314 | template<typename T, typename Tag = __null_tag> | |
315 | struct is_function_reference; | |
316 | ||
317 | [*Header] | |
318 | ||
319 | #include <boost/function_types/is_function_reference.hpp> | |
320 | ||
321 | [variablelist | |
322 | [[[^T]][Type to analyze]] | |
323 | [[[^Tag]][Further properties required for a positive result]] | |
324 | [[[^is_function_reference<T,Tag>]][Predicate value __mpl_integral_constant__]] | |
325 | [[[^is_function_reference<T,Tag>::value]][Constant boolean value]] | |
326 | ] | |
327 | ||
328 | Determines whether a given type is a function reference, possibly with | |
329 | additional properties as specified by a property tag. | |
330 | ||
331 | [endsect] | |
332 | ||
333 | ||
334 | [section:is_member_pointer is_member_pointer] | |
335 | ||
336 | template<typename T, typename Tag = __null_tag> | |
337 | struct is_member_pointer; | |
338 | ||
339 | [*Header] | |
340 | ||
341 | #include <boost/function_types/is_member_pointer.hpp> | |
342 | ||
343 | [variablelist | |
344 | [[[^T]][Type to analyze]] | |
345 | [[[^Tag]][Further properties required for a positive result]] | |
346 | [[[^is_member_pointer<T,Tag>]][Predicate value __mpl_integral_constant__]] | |
347 | [[[^is_member_pointer<T,Tag>::value]][Constant boolean value]] | |
348 | ] | |
349 | ||
350 | Determines whether a given type is a pointer to member (object or function) | |
351 | type, possibly with additional properties as specified by a property tag. | |
352 | ||
353 | [endsect] | |
354 | ||
355 | ||
356 | [section:is_member_object_pointer is_member_object_pointer] | |
357 | ||
358 | template<typename T> | |
359 | struct is_member_object_pointer; | |
360 | ||
361 | [*Header] | |
362 | ||
363 | #include <boost/function_types/is_member_object_pointer.hpp> | |
364 | ||
365 | [variablelist | |
366 | [[[^T]][Type to analyze]] | |
367 | [[[^is_member_object_pointer<T>]][Predicate value __mpl_integral_constant__]] | |
368 | [[[^is_member_object_pointer<T>::value]][Constant boolean value]] | |
369 | ] | |
370 | ||
371 | Determines whether a given type is a pointer to member object type. | |
372 | ||
373 | [endsect] | |
374 | ||
375 | ||
376 | [section:is_member_function_pointer is_member_function_pointer] | |
377 | ||
378 | template<typename T, typename Tag = __null_tag> | |
379 | struct is_member_function_pointer; | |
380 | ||
381 | [*Header] | |
382 | ||
383 | #include <boost/function_types/is_member_function_pointer.hpp> | |
384 | ||
385 | [variablelist | |
386 | [[[^T]][Type to analyze]] | |
387 | [[[^Tag]][Further properties required for a positive result]] | |
388 | [[[^is_member_function_pointer<T,Tag>]][Predicate value __mpl_integral_constant__]] | |
389 | [[[^is_member_function_pointer<T,Tag>::value]][Constant boolean value]] | |
390 | ] | |
391 | ||
392 | Determines whether a given type is a member function pointer, possibly with | |
393 | additional properties as specified by a property tag. | |
394 | ||
395 | [endsect] | |
396 | ||
397 | ||
398 | [section:is_callable_builtin is_callable_builtin] | |
399 | ||
400 | template<typename T, typename Tag = __null_tag> | |
401 | struct is_callable_builtin; | |
402 | ||
403 | [*Header] | |
404 | ||
405 | #include <boost/function_types/is_callable_builtin.hpp> | |
406 | ||
407 | [variablelist | |
408 | [[[^T]][Type to analyze]] | |
409 | [[[^Tag]][Further properties required for a positive result]] | |
410 | [[[^is_callable_builtin<T,Tag>]][Predicate value as __mpl_integral_constant__]] | |
411 | [[[^is_callable_builtin<T,Tag>::value]][Constant boolean value]] | |
412 | ] | |
413 | ||
414 | Determines whether a given type is a callable builtin, possibly with | |
415 | additional properties as specified by a property tag. | |
416 | ||
417 | [endsect] | |
418 | ||
419 | ||
420 | ||
421 | [section:is_nonmember_callable_builtin is_nonmember_callable_builtin] | |
422 | ||
423 | template<typename T, typename Tag = __null_tag> | |
424 | struct is_nonmember_callable_builtin; | |
425 | ||
426 | [*Header] | |
427 | ||
428 | #include <boost/function_types/is_nonmember_callable_builtin.hpp> | |
429 | ||
430 | [variablelist | |
431 | [[[^T]][Type to analyze]] | |
432 | [[[^Tag]][Further properties required for a positive result]] | |
433 | [[[^is_nonmember_callable_builtin<T,Tag>]][Predicate value as __mpl_integral_constant__]] | |
434 | [[[^is_nonmember_callable_builtin<T,Tag>::value]][Constant boolean value]] | |
435 | ] | |
436 | ||
437 | Determines whether a given type is a callable builtin that is not a | |
438 | member function pointer, possibly with | |
439 | additional properties as specified by a property tag. | |
440 | ||
441 | [endsect] | |
442 | ||
443 | ||
444 | [endsect] [/ Class templates for type classification ] | |
445 | ||
446 | [/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] | |
447 | ||
448 | [section:decomposition Class templates for type decomposition] | |
449 | ||
450 | ||
451 | [section:result_type result_type] | |
452 | ||
453 | template<typename F> | |
454 | struct result_type; | |
455 | ||
456 | [*Header] | |
457 | ||
458 | #include <boost/function_types/result_type.hpp> | |
459 | ||
460 | [variablelist | |
461 | [[[^F]][Type to analyze]] | |
462 | [[[^result_type<F>::type]][Result type of [^F]]] | |
463 | ] | |
464 | ||
465 | Extracts the result type of a callable, builtin type. | |
466 | ||
467 | If [^F] is no callable, builtin type, any attempt to access the | |
468 | [^type] member results in a compile error. | |
469 | ||
470 | [endsect] | |
471 | ||
472 | ||
473 | [section:parameter_types parameter_types] | |
474 | ||
475 | template<typename F, class ClassTransform = add_reference<_> > | |
476 | struct parameter_types; | |
477 | ||
478 | [*Header] | |
479 | ||
480 | #include <boost/function_types/parameter_types.hpp> | |
481 | ||
482 | [variablelist | |
483 | [[[^F]][Type to analyze]] | |
484 | [[[^ClassTransform]] | |
485 | [__mpl_lambda_expression__ to transform the | |
486 | class type if [^F] is a member function pointer]] | |
487 | ||
488 | [[[^parameter_types<F,ClassTransform>]] | |
489 | [__mpl_fb_ext_ra_seq__ of parameter types]] | |
490 | ] | |
491 | ||
492 | Extracts the parameter types of a callable, builtin type. | |
493 | ||
494 | If [^F] is no callable, builtin type, any attempt to access the | |
495 | sequence results in a compile error. | |
496 | ||
497 | [endsect] | |
498 | ||
499 | ||
500 | [section:function_arity function_arity] | |
501 | ||
502 | template<typename F> | |
503 | struct function_arity; | |
504 | ||
505 | [*Header] | |
506 | ||
507 | #include <boost/function_types/function_arity.hpp> | |
508 | ||
509 | [variablelist | |
510 | [[[^F]][Callable builtin type]] | |
511 | [[[^function_arity<F>]][Function arity as __mpl_integral_constant__]] | |
512 | [[[^function_arity<F>::value]][Constant value of the function arity]] | |
513 | ] | |
514 | ||
515 | Extracts the function arity, that is the number of parameters. | |
516 | The hidden [^this] of member function pointers counts, in other words | |
517 | the arity value is always greater than or equal to one if [^F] is a | |
518 | member function pointer. | |
519 | ||
520 | If [^F] is no callable, builtin type, any attempt to access the | |
521 | value results in a compile error. | |
522 | ||
523 | [endsect] | |
524 | ||
525 | ||
526 | [section:components components] | |
527 | ||
528 | template<typename T, class ClassTransform = add_reference<_> > | |
529 | struct components; | |
530 | ||
531 | [*Header] | |
532 | ||
533 | #include <boost/function_types/components.hpp> | |
534 | ||
535 | [variablelist | |
536 | [[[^T]][Type to analyze]] | |
537 | [[[^ClassTransform]] | |
538 | [__mpl_lambda_expression__ to transform the | |
539 | class type if [^T] is a member function pointer]] | |
540 | ||
541 | [[[^components<T,ClassTransform>]] | |
542 | [__mpl_fb_ext_ra_seq__ of all | |
543 | component types and property tag]] | |
544 | [[[^components<T,ClassTransform>::types]] | |
545 | [Decorated MPL Sequence, exposed for optimization]] | |
546 | ] | |
547 | ||
548 | Extracts all properties of a callable builtin type, that is the result type, | |
549 | followed by the parameter types (including the type of [^this] for member | |
550 | function pointers). | |
551 | ||
552 | If [^T] is no callable builtin type, the component types are an empty | |
553 | sequence and the Tag's meaning is equivalent to the [^__null_tag]. | |
554 | ||
555 | [endsect] | |
556 | ||
557 | [endsect] [/ Class templates for type decomposition] | |
558 | ||
559 | [/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] | |
560 | ||
561 | [section:synthesis Class templates for type synthesis] | |
562 | ||
563 | ||
564 | [section:function_type function_type] | |
565 | ||
566 | template<typename Types, typename Tag = __null_tag> | |
567 | struct function_type; | |
568 | ||
569 | [*Header] | |
570 | ||
571 | #include <boost/function_types/function_type.hpp> | |
572 | ||
573 | [variablelist | |
574 | [[[^Types]][Component types in form of an __mpl_fwd_seq__ or another callable, builtin type]] | |
575 | [[[^Tag]][Further properties]] | |
576 | [[[^function_type<Types,Tag>::type]][Synthesized type]] | |
577 | ] | |
578 | ||
579 | Synthesizes a function type from given properties. | |
580 | ||
581 | If the template parameters do not describe a valid type, any attempt | |
582 | to access the [^type] member will result in a compile error. | |
583 | ||
584 | [endsect] | |
585 | ||
586 | ||
587 | [section:function_pointer function_pointer] | |
588 | ||
589 | template<typename Types, typename Tag = __null_tag> | |
590 | struct function_pointer; | |
591 | ||
592 | [*Header] | |
593 | ||
594 | #include <boost/function_types/function_pointer.hpp> | |
595 | ||
596 | [variablelist | |
597 | [[[^Types]][Component types in form of an __mpl_fwd_seq__ or another callable, builtin type]] | |
598 | [[[^Tag]][Further properties]] | |
599 | [[[^function_pointer<Types,Tag>::type]][Synthesized type]] | |
600 | ] | |
601 | ||
602 | Synthesizes a function pointer type from given properties. | |
603 | ||
604 | If the template parameters do not describe a valid type, any attempt | |
605 | to access the [^type] member will result in a compile error. | |
606 | ||
607 | [endsect] | |
608 | ||
609 | ||
610 | [section:function_reference function_reference] | |
611 | ||
612 | template<typename Types, typename Tag = __null_tag> | |
613 | struct function_reference; | |
614 | ||
615 | [*Header] | |
616 | ||
617 | #include <boost/function_types/function_reference.hpp> | |
618 | ||
619 | [variablelist | |
620 | [[[^Types]][Component types in form of an __mpl_fwd_seq__ or another callable, builtin type]] | |
621 | [[[^Tag]][Further properties]] | |
622 | [[[^function_reference<Types,Tag>::type]][Synthesized type]] | |
623 | ] | |
624 | ||
625 | Synthesizes a function reference type from given properties. | |
626 | ||
627 | If the template parameters do not describe a valid type, any attempt | |
628 | to access the [^type] member will result in a compile error. | |
629 | ||
630 | [endsect] | |
631 | ||
632 | ||
633 | [section:member_function_pointer member_function_pointer] | |
634 | ||
635 | template<typename Types, typename Tag = __null_tag> | |
636 | struct member_function_pointer; | |
637 | ||
638 | [*Header] | |
639 | ||
640 | #include <boost/function_types/member_function_pointer.hpp> | |
641 | ||
642 | [variablelist | |
643 | [[[^Types]][Component types in form of an __mpl_fwd_seq__ or another callable, builtin type]] | |
644 | [[[^Tag]][Further properties]] | |
645 | [[[^member_function_pointer<Types,Tag>::type]][Synthesized type]] | |
646 | ] | |
647 | ||
648 | Synthesizes a member function pointer type from given properties. | |
649 | ||
650 | An optional reference or possibly cv-qualified pointer is removed from | |
651 | the second type in the sequence to determine the the class type. | |
652 | The cv-qualification of the resulting type applies to the member | |
653 | function, unless otherwise explicitly specified by the property tag. | |
654 | ||
655 | If the template parameters do not describe a valid type, any attempt | |
656 | to access the [^type] member will result in a compile error. | |
657 | ||
658 | [endsect] | |
659 | ||
660 | ||
661 | [endsect] [/ Class templates for type synthesis ] | |
662 | ||
663 | [/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] | |
664 | ||
665 | [section:tag_types Tag Types] | |
666 | ||
667 | [section:variadic variadic] | |
668 | ||
669 | typedef __unspecified__ variadic; | |
670 | ||
671 | [*Header] | |
672 | ||
673 | #include <boost/function_types/property_tags.hpp> | |
674 | ||
675 | States that a function type takes a variable number of arguments through | |
676 | an ellipsis parameter (such as [^printf]). | |
677 | ||
678 | [endsect] | |
679 | ||
680 | [section:non_variadic non_variadic] | |
681 | ||
682 | typedef __unspecified__ non_variadic; | |
683 | ||
684 | [*Header] | |
685 | ||
686 | #include <boost/function_types/property_tags.hpp> | |
687 | ||
688 | States that a function type does not have an ellipsis parameter. | |
689 | ||
690 | [endsect] | |
691 | ||
692 | [section:default_cc default_cc] | |
693 | ||
694 | typedef __unspecified__ default_cc; | |
695 | ||
696 | [*Header] | |
697 | ||
698 | #include <boost/function_types/property_tags.hpp> | |
699 | ||
700 | States that a function type encodes the default calling convention. | |
701 | ||
702 | [endsect] | |
703 | ||
704 | [section:const_qualified const_qualified] | |
705 | ||
706 | typedef __unspecified__ const_qualified; | |
707 | ||
708 | [*Header] | |
709 | ||
710 | #include <boost/function_types/property_tags.hpp> | |
711 | ||
712 | States that a function type is const qualified. | |
713 | ||
714 | [endsect] | |
715 | ||
716 | [section:non_const non_const] | |
717 | ||
718 | typedef __unspecified__ non_const; | |
719 | ||
720 | [*Header] | |
721 | ||
722 | #include <boost/function_types/property_tags.hpp> | |
723 | ||
724 | States that a function type is not const qualified. | |
725 | ||
726 | [endsect] | |
727 | ||
728 | [section:volatile_qualified volatile_qualified] | |
729 | ||
730 | typedef __unspecified__ volatile_qualified; | |
731 | ||
732 | [*Header] | |
733 | ||
734 | #include <boost/function_types/property_tags.hpp> | |
735 | ||
736 | States that a function type is volatile qualified. | |
737 | ||
738 | [endsect] | |
739 | ||
740 | [section:non_volatile non_volatile] | |
741 | ||
742 | typedef __unspecified__ non_volatile; | |
743 | ||
744 | [*Header] | |
745 | ||
746 | #include <boost/function_types/property_tags.hpp> | |
747 | ||
748 | States that a function type is not volatile qualified. | |
749 | ||
750 | [endsect] | |
751 | ||
752 | [section:non_cv non_cv] | |
753 | ||
754 | typedef __unspecified__ non_cv; | |
755 | ||
756 | [*Header] | |
757 | ||
758 | #include <boost/function_types/property_tags.hpp> | |
759 | ||
760 | States that a function type is neither const nor volatile qualified. | |
761 | Equivalent to `__tag<__non_const,__non_volatile>`, but involves | |
762 | fewer template instantiations when evaluated. | |
763 | ||
764 | [endsect] | |
765 | ||
766 | [section:const_non_volatile const_non_volatile] | |
767 | ||
768 | typedef __unspecified__ const_non_volatile; | |
769 | ||
770 | [*Header] | |
771 | ||
772 | #include <boost/function_types/property_tags.hpp> | |
773 | ||
774 | States that a function type is const but not volatile qualified. | |
775 | Equivalent to `__tag<__const_qualified,__non_volatile>`, but involves | |
776 | fewer template instantiations when evaluated. | |
777 | ||
778 | [endsect] | |
779 | ||
780 | [section:volatile_non_const volatile_non_const] | |
781 | ||
782 | typedef __unspecified__ volatile_non_const; | |
783 | ||
784 | [*Header] | |
785 | ||
786 | #include <boost/function_types/property_tags.hpp> | |
787 | ||
788 | States that a function type is volatile but not const qualified. | |
789 | Equivalent to `__tag<__volatile_qualified,__non_const>`, but involves | |
790 | fewer template instantiations when evaluated. | |
791 | ||
792 | [endsect] | |
793 | ||
794 | [section:cv_qualfied cv_qualfied] | |
795 | ||
796 | typedef __unspecified__ cv_qualified; | |
797 | ||
798 | [*Header] | |
799 | ||
800 | #include <boost/function_types/property_tags.hpp> | |
801 | ||
802 | States that a function type is both const and volatile qualified. | |
803 | Equivalent to `__tag<__const_qualified,__volatile_qualified>`, but involves | |
804 | fewer template instantiations when evaluated. | |
805 | ||
806 | [endsect] | |
807 | ||
808 | [section:null_tag null_tag] | |
809 | ||
810 | typedef __unspecified__ null_tag; | |
811 | ||
812 | [*Header] | |
813 | ||
814 | #include <boost/function_types/property_tags.hpp> | |
815 | ||
816 | States nothing. | |
817 | ||
818 | [endsect] | |
819 | ||
820 | [section:tag tag] | |
821 | ||
822 | template<class Tag1, class Tag2, | |
823 | class Tag3 = null_tag, class Tag4 = null_tag> | |
824 | struct tag; | |
825 | ||
826 | [*Header] | |
827 | ||
828 | #include <boost/function_types/property_tags.hpp> | |
829 | ||
830 | [variablelist | |
831 | [[[^Tag['N]]][Property tag]] | |
832 | [[[^tag<Tag1,Tag2...>]][Compound property tag]] | |
833 | ] | |
834 | ||
835 | Combination of up to four property tags. If the arguments describe different | |
836 | values for the same property the value of the rightmost argument is used. | |
837 | ||
838 | [endsect] | |
839 | ||
840 | [endsect] [/ Tag Types] | |
841 | ||
842 | [/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] | |
843 | ||
844 | [section:macros Macros] | |
845 | ||
846 | [section:BOOST_FT_MAX_ARITY BOOST_FT_MAX_ARITY] | |
847 | ||
848 | Expands to a numeric value that describes the maximum function arity | |
849 | supported by the library. | |
850 | ||
851 | Defaults to 20 if not explicitly defined by the user before inclusion | |
852 | of the first library header. | |
853 | ||
854 | [endsect] | |
855 | ||
856 | ||
857 | ||
858 | [*The following macros do not need to be defined, unless to configure | |
859 | the library to work with a compiler and/or calling convention not covered by | |
860 | the auto-detection mechanism in [^boost/function_types/config/compiler.hpp].] | |
861 | ||
862 | ||
863 | [section:BOOST_FT_CC_NAMES BOOST_FT_CC_NAMES] | |
864 | ||
865 | Expands to a [@../../../preprocessor/doc/data/sequences.html sequence] of | |
866 | ternary [@../../../preprocessor/doc/data/tuples.html tuples] (these data | |
867 | types are defined in the [@../../../preprocessor/doc/index.html | |
868 | documentation of the Boost Preprocessor library]). | |
869 | Each sequence element describes one calling convention specifier. | |
870 | The first element in each tuple is the macro suffix for | |
871 | [link boost_functiontypes.reference.macros.BOOST_FT_CC [^BOOST_FT\_CC\_*]], | |
872 | the second element is the name of the tag that describes the calling | |
873 | convention and the third is the name of the specifier. | |
874 | The specifier is allowed to be an empty string, so the third tuple element | |
875 | is either [@../../../preprocessor/doc/ref/empty.html [^BOOST_PP_EMPTY]] or | |
876 | [@../../../preprocessor/doc/ref/identity.html [^BOOST_PP_IDENTITY]][^(['name])]. | |
877 | ||
878 | Define this macro to extend the set of possible names for custom calling | |
879 | conventions. The macro expands to nothing by default. | |
880 | ||
881 | The following names are predefined by the library and must not occur in the | |
882 | definition of [^BOOST_FT_CC_NAMES]: | |
883 | ||
884 | #define BOOST_FT_BUILTIN_CC_NAMES \ | |
885 | (( IMPLICIT , implicit_cc , BOOST_PP_EMPTY ))\ | |
886 | (( CDECL , cdecl_cc , BOOST_PP_IDENTITY(__cdecl ) ))\ | |
887 | (( STDCALL , stdcall_cc , BOOST_PP_IDENTITY(__stdcall ) ))\ | |
888 | (( PASCAL , pascal_cc , BOOST_PP_IDENTITY(pascal ) ))\ | |
889 | (( FASTCALL , fastcall_cc , BOOST_PP_IDENTITY(__fastcall) ))\ | |
890 | (( CLRCALL , clrcall_cc , BOOST_PP_IDENTITY(__clrcall ) ))\ | |
891 | (( THISCALL , thiscall_cc , BOOST_PP_IDENTITY(__thiscall) ))\ | |
892 | (( IMPLICIT_THISCALL , thiscall_cc , BOOST_PP_EMPTY )) | |
893 | // Don't get confused by the last line, here (thiscall can't be specified | |
894 | // explicitly prior to MSVC 8). | |
895 | ||
896 | [endsect] | |
897 | ||
898 | [section:BOOST_FT_CC BOOST_FT\_CC\_*] | |
899 | ||
900 | Enables a specific calling convention. * denotes the macro suffix, as | |
901 | defined by | |
902 | [link boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES [^BOOST_FT_CC_NAMES]] | |
903 | or | |
904 | [link boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES [^BOOST_FT_BUILTIN_CC_NAMES]]. | |
905 | ||
906 | The macro expands to a list of restrictions, separated by the [^|] character. | |
907 | Possible items are: | |
908 | ||
909 | * callable_builtin | |
910 | * member | |
911 | * non_member | |
912 | * variadic | |
913 | * non_variadic | |
914 | ||
915 | If no such macro is defined for a particular calling convention, it is disabled. | |
916 | Example: | |
917 | ||
918 | #define BOOST_FT_CC_STDCALL non_variadic|callable_builtin | |
919 | // enables stdcall calling convention for all non-variadic, | |
920 | // callable, builtin types | |
921 | ||
922 | [endsect] | |
923 | ||
924 | [section:BOOST_FT_COMMON_X86_CCs BOOST_FT_COMMON_X86_CCs] | |
925 | ||
926 | Defining this macro causes the following macros to be defined, if not defined | |
927 | already: | |
928 | ||
929 | #define BOOST_FT_CC_CDECL BOOST_FT_COMMON_X86_CCs | |
930 | #define BOOST_FT_CC_STDCALL non_variadic|BOOST_FT_COMMON_X86_CCs | |
931 | #define BOOST_FT_CC_FASTCALL non_variadic|BOOST_FT_COMMON_X86_CCs | |
932 | ||
933 | [endsect] | |
934 | ||
935 | [section:BOOST_FT_SYNTAX BOOST_FT_SYNTAX] | |
936 | ||
937 | This macro allows to change the syntax of callable builtin types. | |
938 | It is useful to handle the compiler specific placement of the calling | |
939 | convention specifier. | |
940 | ||
941 | The default definition is as follows: | |
942 | ||
943 | #define BOOST_FT_SYNTAX(result,lparen,cc_spec,type_mod,name,rparen) \ | |
944 | result() lparen() cc_spec() type_mod() name() rparen() | |
945 | ||
946 | [endsect] | |
947 | ||
948 | [section:BOOST_FT_NULLARY_PARAM BOOST_FT_NULLARY_PARAM] | |
949 | ||
950 | Set to [^void] for compilers that insist on a [^void] parameter for | |
951 | nullary function types, empty by default. | |
952 | ||
953 | [endsect] | |
954 | ||
955 | [section:BOOST_FT_NO_CV_FUNC_SUPPORT BOOST_FT_NO_CV_FUNC_SUPPORT] | |
956 | ||
957 | Disables support for cv-qualified function types. | |
958 | Cv-qualified function types are illegal by the current standard | |
959 | version, but there is a pending defect report on that issue. | |
960 | It defaults to [^1] until the standard changes, setting this macro | |
961 | to [^0] may not work. | |
962 | ||
963 | [endsect] | |
964 | ||
965 | ||
966 | ||
967 | [*The following macros are useful for testing when changing the source code of | |
968 | the library.] | |
969 | ||
970 | ||
971 | ||
972 | [section:BOOST_FT_PREPROCESSING_MODE BOOST_FT_PREPROCESSING_MODE] | |
973 | ||
974 | Makes the compiler preprocess as much as possible of the library code | |
975 | (rather than loading already-preprocessed header files) if defined. | |
976 | ||
977 | [endsect] | |
978 | ||
979 | [section:BOOST_FT_CC_PREPROCESSING BOOST_FT_CC_PREPROCESSING] | |
980 | ||
981 | Makes the compiler preprocess the loop over possible names for custom | |
982 | calling conventions (rather than loading an already-preprocessed header | |
983 | file) if defined. | |
984 | ||
985 | This macro is defined automatically if | |
986 | [link boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES [^BOOST_FT_CC_NAMES]] | |
987 | has been defined. | |
988 | ||
989 | [endsect] | |
990 | ||
991 | [endsect] | |
992 | ||
993 | [endsect] | |
994 | ||
995 | [/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] | |
996 | ||
997 | [section:rationale Rationale] | |
998 | ||
999 | [heading Error handling rationale] | |
1000 | ||
1001 | The library does not define the required members of class templates in | |
1002 | case of an error. This technique causes the compiler to stop displaying | |
1003 | diagnostics in client code, at the point where the error actually is, | |
1004 | instead of tracing template instantiations into the implementation of | |
1005 | the library. | |
1006 | ||
1007 | The library's components have limited error conditions, so problematic | |
1008 | input can be spotted easily. | |
1009 | ||
1010 | ||
1011 | [heading Why MPL Sequences?] | |
1012 | ||
1013 | MPL provides algorithms on Sequences, so transformations (such as turning | |
1014 | by-value parameter types into const references for optimized forwarding | |
1015 | or computing a signature to specialize | |
1016 | [@../../../function/index.html [^boost::function]] after applying | |
1017 | [@../../../bind/index.html [^boost::bind]]) can be expressed more | |
1018 | easily. The MPL Sequence concept is compatible with several other Boost | |
1019 | libraries (most importantly [@../../../fusion/index.html Fusion]), | |
1020 | so another reason is interoperability. | |
1021 | ||
1022 | ||
1023 | [heading Pointer to member object types] | |
1024 | ||
1025 | Despite their syntax, pointer to member object types can be seen as | |
1026 | dereferencing functionals. | |
1027 | ||
1028 | ||
1029 | [heading The ClassTransform template parameter] | |
1030 | ||
1031 | [^This]-pointer, [^this]-reference or just the object (or maybe even a | |
1032 | smart pointer to the object) plus adjustments of cv-qualification - all | |
1033 | these cases have their place, somewhere and there is no single best answer. | |
1034 | ||
1035 | Special treatment of the class type within the sequence can significantly | |
1036 | complicate client code. A custom [^ClassTransform] argument allows the | |
1037 | client to adjust the class type before the sequence is formed and then | |
1038 | treat all parameters uniformly. | |
1039 | ||
1040 | ||
1041 | [heading Why tag types?] | |
1042 | ||
1043 | Let's consider the alternatives. | |
1044 | ||
1045 | The first one is just using more templates so every property has to be | |
1046 | asked for explicitly. This approach results in more complicated client | |
1047 | code if more than one propery has to be checked and in a exponentially | |
1048 | larger library interface. | |
1049 | ||
1050 | The second alternative is having the client pass in bit patterns via | |
1051 | non-type template parameters. The logic has to be performed by the | |
1052 | client and there are much more error conditions. Further, class templates | |
1053 | with non-type template parameters do not work within MPL lambda | |
1054 | expressions and can cause problems with older compilers. | |
1055 | ||
1056 | [heading Is it safe to have the synthesis templates take a callable | |
1057 | builtin type or an MPL sequence as the first template argument?] | |
1058 | ||
1059 | Yes, but it isn't immediately obvious as the set of possible MPL sequences | |
1060 | isn't inherently disjoint from the set of callable builtin types. | |
1061 | ||
1062 | However, any attempt to make a builtin type work as an MPL sequence is | |
1063 | a bad idea, because builtin types are accessible before the headers that | |
1064 | make the type a sequence have been included, which can easily violate the | |
1065 | ODR. | |
1066 | ||
1067 | [heading Why does the hidden [^this] parameter count for the | |
1068 | function arity of member functions?] | |
1069 | ||
1070 | It was found preferable that the following condition holds: | |
1071 | ||
1072 | mpl::size< __parameter_types<T> >::value == __function_arity<T>::value | |
1073 | ||
1074 | [heading Why ignore top-level cv-qualifiers on pointers?] | |
1075 | ||
1076 | A cv-qualified pointer is still a pointer. It usually doesn't matter and | |
1077 | even if it does, it's a job for | |
1078 | [@../../../type_traits/index.html Boost.TypeTraits]. | |
1079 | ||
1080 | ||
1081 | [endsect] | |
1082 | ||
1083 | [section:acknowledgements Acknowledgements] | |
1084 | ||
1085 | Thanks go to the following people for supporting the development of this | |
1086 | library in one or the other way: | |
1087 | ||
1088 | * David Abrahams | |
1089 | * Tom Brinkman | |
1090 | * Aleksey Gurtovoy | |
1091 | * Jody Hagins | |
1092 | * Hartmut Kaiser | |
1093 | * Andy Little | |
1094 | * John Maddock | |
1095 | * Paul Mensonides | |
1096 | * Alexander Nasonov | |
1097 | * Richard Smith | |
1098 | * Rob Stewart | |
1099 | * Jonathan Turkanis | |
1100 | * Pavel Vozenilek | |
1101 | * Steven Watanabe | |
1102 | * K. Noel Belcourt | |
1103 | ||
1104 | [endsect] | |
1105 |