]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/preprocessor/doc/topics/evaluated_slots.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / preprocessor / doc / topics / evaluated_slots.html
1 <html>
2 <head>
3 <title>evaluated_slots.html</title>
4 <link rel="stylesheet" type="text/css" href="../styles.css">
5 </head>
6 <body>
7 <h4>Evaluated Slots</h4>
8 <div>
9 The evaluated slot mechanism is a tool to fully evaluate a constant integral expression and avoid the lazy evaluation normally performed by the preprocessor.
10 </div>
11 <h4>Tutorial</h4>
12 <div>
13 In order to understand the use of such a mechanism, I will start with a simple file-iteration example.&nbsp;
14 Consider the following scenario....
15 </div>
16 <div class ="code"><pre>
17 for (int i = 0; i < 10; ++i) {
18 for (int j = 0; j < i; ++j) {
19 // ... use i and j
20 }
21 }
22 </pre></div>
23 <div>
24 The above is a simple runtime model of the following multidimensional file-iteration....
25 </div>
26 <div class="code"><pre>
27 // file.hpp
28 #if !BOOST_PP_IS_ITERATING
29 #ifndef FILE_HPP_
30 #define FILE_HPP_
31
32 #include &lt;boost/preprocessor/iteration/iterate.hpp&gt;
33
34 #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 9, "file.hpp"))
35 #include BOOST_PP_ITERATE()
36
37 #endif // FILE_HPP_
38 #elif BOOST_PP_ITERATION_DEPTH() == 1
39 #define I BOOST_PP_ITERATION()
40
41 #define BOOST_PP_ITERATION_PARAMS_2 (3, (0, I, "file.hpp"))
42 #include BOOST_PP_ITERATE()
43
44 #undef I
45 #elif BOOST_PP_ITERATION_DEPTH() == 2
46 #define J BOOST_PP_ITERATION()
47
48 // use I and J
49
50 #undef J
51 #endif
52 </pre></div>
53 <div>
54 There is a problem with the code above.&nbsp;
55 The writer expected <i>I</i> to refer the previous iteration frame.&nbsp;
56 However, that is not the case.&nbsp;
57 When the user refers to <i>I</i>, he is actually referring to <b>BOOST_PP_ITERATION</b>(),
58 not the value of <b>BOOST_PP_ITERATION</b>() at the point of definition.&nbsp;
59 Instead, it refers to exactly the same value to which <i>J</i> refers.
60 </div>
61 <div>
62 The problem is that the preprocessor always evaluates everything with lazy evaluation.&nbsp;
63 To solve the problem, we need <i>I</i> to be <i>evaluated</i> here:
64 </div>
65 <div class="code"><pre>
66 // ...
67 #elif BOOST_PP_ITERATION_DEPTH() == 1
68 #define I BOOST_PP_ITERATION()
69 // ...
70 </pre></div>
71 <div>
72 Fortunately, the library offers a mechanism to do just that:&nbsp; evaluated slots.&nbsp;
73 The following code uses this mechanism to "fix" the example above...
74 </div>
75 <div class="code"><pre>
76 // ...
77 #elif BOOST_PP_ITERATION_DEPTH() == 1
78 #define BOOST_PP_VALUE BOOST_PP_ITERATION()
79 #include BOOST_PP_ASSIGN_SLOT(1)
80 #define I BOOST_PP_SLOT(1)
81 // ...
82 </pre></div>
83 <div>
84 There are two steps to the assignment of an evaluated slot.&nbsp;
85 First, the user must define the <i>named external argument</i> <b>BOOST_PP_VALUE</b>.&nbsp;
86 This value must be an integral constant expression.&nbsp;
87 Second, the user must <i>include</i> <b>BOOST_PP_ASSIGN_SLOT</b>(<i>x</i>), where <i>x</i> is the particular slot to be assigned to (<i>1</i> to <b>BOOST_PP_LIMIT_SLOT_COUNT</b>).&nbsp;
88 This will evaluate <b>BOOST_PP_VALUE</b> and assign the result to the slot at index <i>x</i>.
89 </div>
90 <div>
91 To retrieve a slot's value, the user must use <b>BOOST_PP_SLOT</b>(<i>x</i>).
92 </div>
93 <div>
94 In the case above, <i>I</i> is <i>still</i> lazily evaluated.&nbsp;
95 However, it now evaluates to <b>BOOST_PP_SLOT</b>(<i>1</i>).&nbsp;
96 This value <i>will not change</i> unless there is a subsequent call to <b>BOOST_PP_ASSIGN_SLOT</b>(<i>1</i>).
97 </div>
98 <h4>Advanced Techniques</h4>
99 <div>
100 The slot mechanism can also be used to perform calculations:
101 </div>
102 <div class="code"><pre>
103 #include &lt;iostream&gt;
104
105 #include &lt;boost/preprocessor/slot/slot.hpp&gt;
106 #include &lt;boost/preprocessor/stringize.hpp&gt;
107
108 #define X() 4
109
110 #define BOOST_PP_VALUE 1 + 2 + 3 + X()
111 #include BOOST_PP_ASSIGN_SLOT(1)
112
113 #undef X
114
115 int main(void) {
116 std::cout
117 &lt;&lt; BOOST_PP_STRINGIZE(BOOST_PP_SLOT(1))
118 &lt;&lt; &amp;std::endl;
119 return 0;
120 }
121 </pre></div>
122 <div>
123 In essence, anything that can be evaluated in an #if (or #elif) preprocessor directive is available <i>except</i> the <i>defined</i> operator.
124 </div>
125 <div>
126 It is even possible to use a particular slot itself while reassigning it:
127 </div>
128 <div class="code"><pre>
129 #define BOOST_PP_VALUE 20
130 #include BOOST_PP_ASSIGN_SLOT(1)
131
132 #define BOOST_PP_VALUE 2 * BOOST_PP_SLOT(1)
133 #include BOOST_PP_ASSIGN_SLOT(1)
134
135 BOOST_PP_SLOT(1) // 40
136 </pre></div>
137 <h4>See Also</h4>
138 <ul>
139 <li><a href="../ref/assign_slot.html">BOOST_PP_ASSIGN_SLOT</a></li>
140 <li><a href="../ref/limit_slot_count.html">BOOST_PP_LIMIT_SLOT_COUNT</a></li>
141 <li><a href="../ref/slot.html">BOOST_PP_SLOT</a></li>
142 <li><a href="../ref/value.html">BOOST_PP_VALUE</a></li>
143 </ul>
144 <div class="sig">- Paul Mensonides</div>
145 <hr size="1">
146 <div style="margin-left: 0px;">
147 <i>© Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i>
148 </br><i>© Copyright Paul Mensonides 2002</i>
149 </div>
150 <div style="margin-left: 0px;">
151 <p><small>Distributed under the Boost Software License, Version 1.0. (See
152 accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
153 copy at <a href=
154 "http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
155 </div>
156 </body>
157 </html>