]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/preprocessor/doc/topics/motivation.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / preprocessor / doc / topics / motivation.html
CommitLineData
7c673cae
FG
1<html>
2<head>
3 <title>motivation.html</title>
4 <link rel="stylesheet" type="text/css" href="../styles.css">
5</head>
6<body>
7<h4>Motivation</h4>
8<div>
9 The C++ function and template parameter lists are special syntactic constructs, and it is impossible to directly
10 manipulate or generate them using C++ constructs.&nbsp;
11 This leads to unnecessary code repetition.
12</div>
13<div>
14 Consider the implementation of the <code>is_function&lt;&gt;</code> metafunction is Boost.&nbsp;
15 The implementation uses an overloaded <code>is_function_tester()</code> function that is used for testing if a type is convertible
16 to a pointer to a function.&nbsp;
17 Because of the special treatment of parameter lists, it is not possible to directly match a function with an arbitrary parameter list.&nbsp;
18 Instead, the <code>is_function_tester()</code> must be overloaded for every distinct number of parameters that is to be supported.&nbsp;
19 For example:
20</div>
21<div class="code"><pre>
22template&lt;class R&gt;
23yes_type is_function_tester(R (*)());
24
25template&lt;class R, class A0&gt;
26yes_type is_function_tester(R (*)(A0));
27
28template&lt;class R, class A0, class A1&gt;
29yes_type is_function_tester(R (*)(A0, A1));
30
31template&lt;class R, class A0, class A1, class A2&gt;
32yes_type is_function_tester(R (*)(A0, A1, A2));
33
34// ...
35</pre></div>
36<div>
37 The need for this kind of repetition occurs particularly frequently while implementing generic components or metaprogramming facilities,
38 but the need also manifests itself in many far simpler situations.
39</div>
40<h4>Typical Solutions</h4>
41<div>
42 Typically the repetition is done manually.&nbsp;
43 Manual code repetition is highly unproductive, but sometimes more readable to the untrained eye.
44</div>
45<div>
46 Another solution is to write an external program for generating the repeated code or use some other extra linguistic means such as a smart editor.&nbsp;
47 Unfortunately, using external code generators has many disadvantages:
48 <ul>
49 <li>Writing the generator takes time.&nbsp; (This could be helped by using a standard generator.)</li>
50 <li>It is no longer productive to manipulate C++ code directly.</li>
51 <li>Invoking the generator may be difficult.</li>
52 <li>Automating the invocation of the generator can be difficult in certain environments.&nbsp; (Automatic invocation is desirable for active libraries.)</li>
53 <li>Porting and distributing the generator may be difficult or simply takes precious time.</li>
54 </ul>
55</div>
56<h4>What about the preprocessor?</h4>
57<div>
58 Because C++ comes with a preprocessor, one would assume that it would support these kinds of needs directly.&nbsp;
59 Using the preprocessor in this case is highly desirable because:
60 <ul>
61 <li>The preprocessor is highly portable.</li>
62 <li>The preprocessor is automatically invoked as part of the compilation process.</li>
63 <li>Preprocessor metacode can be directly embedded into the C++ source code.</li>
64 <li>Compilers generally allow viewing or outputting the preprocessed code, which can be used for debugging or to copy and paste the generated code.</li>
65 </ul>
66</div>
67<div>
68 Most unfortunately, the preprocessor is a very low level preprocessor that specifically does not support repetition or recursive macros.&nbsp;
69 Library support is needed!
70</div>
71<div>
72 <i>For detailed information on the capabilities and limitations of the preprocessor, please refer to the C++ standard <a href="../bibliography.html#std">[Std]</a>.</i>
73</div>
74<h4>The Motivation Example Revisited</h4>
75<div>
76 Using the primitives of the preprocessor library, the <code>is_function_tester()</code>'s could be implemented like this:
77</div>
78<div class="code"><pre>
79#include &lt;boost/preprocessor/arithmetic/inc.hpp&gt;
80#include &lt;boost/preprocessor/punctuation/comma_if.hpp&gt;
81#include &lt;boost/preprocessor/repetition.hpp&gt;
82
83#ifndef MAX_IS_FUNCTION_TESTER_PARAMS
84#define MAX_IS_FUNCTION_TESTER_PARAMS 15
85#endif
86
87#define IS_FUNCTION_TESTER(Z, N, _) \
88 template&lt;class R BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class A)&gt; \
89 yes_type is_function_tester(R (*)(BOOST_PP_ENUM_PARAMS(N, A))); \
90 /**/
91
92BOOST_PP_REPEAT(BOOST_PP_INC(MAX_IS_FUNCTION_TESTER_PARAMS), IS_FUNCTION_TESTER, _)
93
94#undef IS_FUNCTION_TESTER
95</pre></div>
96<div>
97 In order to change the maximum number of function parameters supported, you now simply change the <code>MAX_IS_FUNCTION_TESTER_PARAMS</code> definition and recompile.
98</div>
99<hr size="1">
100<div style="margin-left: 0px;">
101