evaluated_slots.html 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. #include &lt;boost/preprocessor/iteration/iterate.hpp&gt;
  32. #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 9, "file.hpp"))
  33. #include BOOST_PP_ITERATE()
  34. #endif // FILE_HPP_
  35. #elif BOOST_PP_ITERATION_DEPTH() == 1
  36. #define I BOOST_PP_ITERATION()
  37. #define BOOST_PP_ITERATION_PARAMS_2 (3, (0, I, "file.hpp"))
  38. #include BOOST_PP_ITERATE()
  39. #undef I
  40. #elif BOOST_PP_ITERATION_DEPTH() == 2
  41. #define J BOOST_PP_ITERATION()
  42. // use I and J
  43. #undef J
  44. #endif
  45. </pre></div>
  46. <div>
  47. There is a problem with the code above.&nbsp;
  48. The writer expected <i>I</i> to refer the previous iteration frame.&nbsp;
  49. However, that is not the case.&nbsp;
  50. When the user refers to <i>I</i>, he is actually referring to <b>BOOST_PP_ITERATION</b>(),
  51. not the value of <b>BOOST_PP_ITERATION</b>() at the point of definition.&nbsp;
  52. Instead, it refers to exactly the same value to which <i>J</i> refers.
  53. </div>
  54. <div>
  55. The problem is that the preprocessor always evaluates everything with lazy evaluation.&nbsp;
  56. To solve the problem, we need <i>I</i> to be <i>evaluated</i> here:
  57. </div>
  58. <div class="code"><pre>
  59. // ...
  60. #elif BOOST_PP_ITERATION_DEPTH() == 1
  61. #define I BOOST_PP_ITERATION()
  62. // ...
  63. </pre></div>
  64. <div>
  65. Fortunately, the library offers a mechanism to do just that:&nbsp; evaluated slots.&nbsp;
  66. The following code uses this mechanism to "fix" the example above...
  67. </div>
  68. <div class="code"><pre>
  69. // ...
  70. #elif BOOST_PP_ITERATION_DEPTH() == 1
  71. #define BOOST_PP_VALUE BOOST_PP_ITERATION()
  72. #include BOOST_PP_ASSIGN_SLOT(1)
  73. #define I BOOST_PP_SLOT(1)
  74. // ...
  75. </pre></div>
  76. <div>
  77. There are two steps to the assignment of an evaluated slot.&nbsp;
  78. First, the user must define the <i>named external argument</i> <b>BOOST_PP_VALUE</b>.&nbsp;
  79. This value must be an integral constant expression.&nbsp;
  80. 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;
  81. This will evaluate <b>BOOST_PP_VALUE</b> and assign the result to the slot at index <i>x</i>.
  82. </div>
  83. <div>
  84. To retrieve a slot's value, the user must use <b>BOOST_PP_SLOT</b>(<i>x</i>).
  85. </div>
  86. <div>
  87. In the case above, <i>I</i> is <i>still</i> lazily evaluated.&nbsp;
  88. However, it now evaluates to <b>BOOST_PP_SLOT</b>(<i>1</i>).&nbsp;
  89. This value <i>will not change</i> unless there is a subsequent call to <b>BOOST_PP_ASSIGN_SLOT</b>(<i>1</i>).
  90. </div>
  91. <h4>Advanced Techniques</h4>
  92. <div>
  93. The slot mechanism can also be used to perform calculations:
  94. </div>
  95. <div class="code"><pre>
  96. #include &lt;iostream&gt;
  97. #include &lt;boost/preprocessor/slot/slot.hpp&gt;
  98. #include &lt;boost/preprocessor/stringize.hpp&gt;
  99. #define X() 4
  100. #define BOOST_PP_VALUE 1 + 2 + 3 + X()
  101. #include BOOST_PP_ASSIGN_SLOT(1)
  102. #undef X
  103. int main(void) {
  104. std::cout
  105. &lt;&lt; BOOST_PP_STRINGIZE(BOOST_PP_SLOT(1))
  106. &lt;&lt; &amp;std::endl;
  107. return 0;
  108. }
  109. </pre></div>
  110. <div>
  111. In essence, anything that can be evaluated in an #if (or #elif) preprocessor directive is available <i>except</i> the <i>defined</i> operator.
  112. </div>
  113. <div>
  114. It is even possible to use a particular slot itself while reassigning it:
  115. </div>
  116. <div class="code"><pre>
  117. #define BOOST_PP_VALUE 20
  118. #include BOOST_PP_ASSIGN_SLOT(1)
  119. #define BOOST_PP_VALUE 2 * BOOST_PP_SLOT(1)
  120. #include BOOST_PP_ASSIGN_SLOT(1)
  121. BOOST_PP_SLOT(1) // 40
  122. </pre></div>
  123. <h4>See Also</h4>
  124. <ul>
  125. <li><a href="../ref/assign_slot.html">BOOST_PP_ASSIGN_SLOT</a></li>
  126. <li><a href="../ref/limit_slot_count.html">BOOST_PP_LIMIT_SLOT_COUNT</a></li>
  127. <li><a href="../ref/slot.html">BOOST_PP_SLOT</a></li>
  128. <li><a href="../ref/value.html">BOOST_PP_VALUE</a></li>
  129. </ul>
  130. <div class="sig">- Paul Mensonides</div>
  131. <hr size="1">
  132. <div style="margin-left: 0px;">
  133. <i>© Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i>
  134. </br><i>© Copyright Paul Mensonides 2002</i>
  135. </div>
  136. <div style="margin-left: 0px;">
  137. <p><small>Distributed under the Boost Software License, Version 1.0. (See
  138. accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
  139. copy at <a href=
  140. "http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
  141. </div>
  142. </body>
  143. </html>