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. |
---|
11 | This leads to unnecessary code repetition. |
---|
12 | </div> |
---|
13 | <div> |
---|
14 | Consider the implementation of the <code>is_function<></code> metafunction is Boost. |
---|
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. |
---|
17 | Because of the special treatment of parameter lists, it is not possible to directly match a function with an arbitrary parameter list. |
---|
18 | Instead, the <code>is_function_tester()</code> must be overloaded for every distinct number of parameters that is to be supported. |
---|
19 | For example: |
---|
20 | </div> |
---|
21 | <div class="code"><pre> |
---|
22 | template<class R> |
---|
23 | yes_type is_function_tester(R (*)()); |
---|
24 | |
---|
25 | template<class R, class A0> |
---|
26 | yes_type is_function_tester(R (*)(A0)); |
---|
27 | |
---|
28 | template<class R, class A0, class A1> |
---|
29 | yes_type is_function_tester(R (*)(A0, A1)); |
---|
30 | |
---|
31 | template<class R, class A0, class A1, class A2> |
---|
32 | yes_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. |
---|
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. |
---|
47 | Unfortunately, using external code generators has many disadvantages: |
---|
48 | <ul> |
---|
49 | <li>Writing the generator takes time. (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. (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. |
---|
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. |
---|
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 <boost/preprocessor/arithmetic/inc.hpp> |
---|
80 | #include <boost/preprocessor/punctuation/comma_if.hpp> |
---|
81 | #include <boost/preprocessor/repetition.hpp> |
---|
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<class R BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, class A)> \ |
---|
89 | yes_type is_function_tester(R (*)(BOOST_PP_ENUM_PARAMS(N, A))); \ |
---|
90 | /**/ |
---|
91 | |
---|
92 | BOOST_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 | <i>© Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i> |
---|
102 | </div> |
---|
103 | <div style="margin-left: 0px;"> |
---|
104 | Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. |
---|
105 | This document is provided "as is" without express or implied warranty and with no claim as to its suitability for any purpose. |
---|
106 | </div> |
---|
107 | <hr size="1"> |
---|
108 | <div style="margin-left: 0px;"> |
---|
109 | <i>© Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i> |
---|
110 | </br><i>© Copyright Paul Mensonides 2002</i> |
---|
111 | </div> |
---|
112 | <div style="margin-left: 0px;"> |
---|
113 | <p><small>Distributed under the Boost Software License, Version 1.0. (See |
---|
114 | accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or |
---|
115 | copy at <a href= |
---|
116 | "http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p> |
---|
117 | </div> |
---|
118 | </body> |
---|
119 | </html> |
---|