vmd_identifier_subtype.html 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Identifier subtypes</title>
  5. <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;The Variadic Macro Data Library 1.9">
  8. <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;The Variadic Macro Data Library 1.9">
  9. <link rel="prev" href="vmd_modifiers/vmd_modifiers_single.html" title="Modifiers and the single-element sequence">
  10. <link rel="next" href="vmd_useful.html" title="Useful variadic macros not in Boost PP">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="vmd_modifiers/vmd_modifiers_single.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_useful.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h2 class="title" style="clear: both">
  27. <a name="variadic_macro_data.vmd_identifier_subtype"></a><a class="link" href="vmd_identifier_subtype.html" title="Identifier subtypes">Identifier
  28. subtypes</a>
  29. </h2></div></div></div>
  30. <p>
  31. Identifiers are the low-level data types which macro programmers use to pass
  32. preprocessing data most often. As we have seen VMD has a system for registering
  33. and detecting identifiers so that they can be parsed as part of preprocessor
  34. data. This system also includes comparing identifiers for equality or inequality
  35. using BOOST_VMD_EQUAL/BOOST_VMD_NOT_EQUAL and matching identifiers using identifier
  36. modifiers in BOOST_VMD_IS_IDENTIFIER and BOOST_VMD_ELEM. Together these facilities
  37. provide a rich set of functionality for handling identifiers in macros.
  38. </p>
  39. <p>
  40. Both numbers and v-types are subtypes of identifiers, and can both be individually
  41. recognized as data types of their own or worked with as identifiers using the
  42. identifier facilities already mentioned. Numbers, in particular, also have
  43. a rich set of functionality within the Boost PP library. As subtypes numbers
  44. and v-types can be used as filter modifiers and can be returned as specific
  45. types either when invoking BOOST_VMD_GET_TYPE or when using return type modifiers.
  46. Furthermore VMD recognizes their individual v-types, BOOST_VMD_TYPE_NUMBER
  47. and BOOST_VMD_TYPE_TYPE, as VMD data when parsing sequences.
  48. </p>
  49. <p>
  50. It is possible for the end-user to define his own identifier subtype. This
  51. is called a "user-defined subtype". Once a user-define subtype is
  52. created all the generic type facilities of VMD which subtypes such as a number
  53. or a v-type possess is automatically available for that user-defined subtype.
  54. </p>
  55. <h4>
  56. <a name="variadic_macro_data.vmd_identifier_subtype.h0"></a>
  57. <span class="phrase"><a name="variadic_macro_data.vmd_identifier_subtype.defining_a_subtype"></a></span><a class="link" href="vmd_identifier_subtype.html#variadic_macro_data.vmd_identifier_subtype.defining_a_subtype">Defining
  58. a subtype</a>
  59. </h4>
  60. <p>
  61. In order to define a user-defined subtype a number of steps need to be followed.
  62. These steps will be explained in detail further below:
  63. </p>
  64. <div class="orderedlist"><ol class="orderedlist" type="1">
  65. <li class="listitem">
  66. Register and pre-detect all identifiers of that subtype.
  67. </li>
  68. <li class="listitem">
  69. Register and pre-detect a v-type name for that subtype.
  70. </li>
  71. <li class="listitem">
  72. Subset register all identifiers of the subtype.
  73. </li>
  74. <li class="listitem">
  75. Subset register the v-type name for the subtype.
  76. </li>
  77. </ol></div>
  78. <p>
  79. When we do the above, it is best to put all the macros in a single header file
  80. and always include that header file when we work generically with our user-defined
  81. subtype.
  82. </p>
  83. <h4>
  84. <a name="variadic_macro_data.vmd_identifier_subtype.h1"></a>
  85. <span class="phrase"><a name="variadic_macro_data.vmd_identifier_subtype.register_and_pre_detect_all_iden"></a></span><a class="link" href="vmd_identifier_subtype.html#variadic_macro_data.vmd_identifier_subtype.register_and_pre_detect_all_iden">Register
  86. and pre-detect all identifiers of that subtype</a>
  87. </h4>
  88. <p>
  89. Registering and pre-detecting all of the identifiers of that subtype is exactly
  90. the same as registering and pre-detecting any identifier.
  91. </p>
  92. <p>
  93. Let's create some identifiers based for use in the mythical "udef"
  94. library. We will put all our macros in the header file udef_vmd_macros.hpp.
  95. </p>
  96. <p>
  97. We will need distinct names for the identifiers in our library, so we will
  98. append UDEF_ to our identifier names to make them unique. Our udef library
  99. deals in geometrical shapes so we will create a user-defined subtype which
  100. consists of identifiers for the various shapes our udef library can manipulate
  101. in their macros. So our identifier registrations and pre-detections placed
  102. in our header file will be:
  103. </p>
  104. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_UDEF_CIRCLE</span> <span class="special">(</span><span class="identifier">UDEF_CIRCLE</span><span class="special">)</span>
  105. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_UDEF_SQUARE</span> <span class="special">(</span><span class="identifier">UDEF_SQUARE</span><span class="special">)</span>
  106. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_UDEF_TRIANGLE</span> <span class="special">(</span><span class="identifier">UDEF_TRIANGLE</span><span class="special">)</span>
  107. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_UDEF_HEXAGON</span> <span class="special">(</span><span class="identifier">UDEF_HEXAGON</span><span class="special">)</span>
  108. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_UDEF_CIRCLE_UDEF_CIRCLE</span>
  109. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_UDEF_SQUARE_UDEF_SQUARE</span>
  110. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_UDEF_TRIANGLE_UDEF_TRIANGLE</span>
  111. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_UDEF_HEXAGON_UDEF_HEXAGON</span>
  112. </pre>
  113. <h4>
  114. <a name="variadic_macro_data.vmd_identifier_subtype.h2"></a>
  115. <span class="phrase"><a name="variadic_macro_data.vmd_identifier_subtype.register_and_pre_detect_a_v_type"></a></span><a class="link" href="vmd_identifier_subtype.html#variadic_macro_data.vmd_identifier_subtype.register_and_pre_detect_a_v_type">Register
  116. and pre-detect a v-type name for that subtype</a>
  117. </h4>
  118. <p>
  119. We need to create a unique v-type name for our user-defined subtype. The name
  120. does not have to begin with BOOST_VMD_TYPE_ but it should be unique. Since
  121. BOOST_VMD_TYPE_ is the common beginning of all v-types we will use it for consistency
  122. but will append to it UDEF_SHAPES to give it a uniqueness which should not
  123. be duplicated:
  124. </p>
  125. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_REGISTER_BOOST_VMD_TYPE_UDEF_SHAPES</span> <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_UDEF_SHAPES</span><span class="special">)</span>
  126. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_DETECT_BOOST_VMD_TYPE_UDEF_SHAPES_BOOST_VMD_TYPE_UDEF_SHAPES</span>
  127. </pre>
  128. <h4>
  129. <a name="variadic_macro_data.vmd_identifier_subtype.h3"></a>
  130. <span class="phrase"><a name="variadic_macro_data.vmd_identifier_subtype.subtype_register_all_identifiers"></a></span><a class="link" href="vmd_identifier_subtype.html#variadic_macro_data.vmd_identifier_subtype.subtype_register_all_identifiers">Subtype
  131. register all identifiers of the subtype</a>
  132. </h4>
  133. <p>
  134. The macro to register an identifier subset starts with BOOST_VMD_SUBTYPE_REGISTER_
  135. and you append to it each identifier in the subset. This is very much like
  136. the way you use the BOOST_VMD_REGISTER_ macro. The difference is that unlike
  137. the BOOST_VMD_REGISTER_ macro, which expands to a tuple whose single element
  138. is the identifier, the BOOST_VMD_SUBTYPE_REGISTER_ expands to a tuple of two
  139. elements where the first element is the subtype v-type and the second element
  140. is the identifier.
  141. </p>
  142. <p>
  143. For our udef user-defined subtype this would be:
  144. </p>
  145. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SUBTYPE_REGISTER_UDEF_CIRCLE</span> <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_UDEF_SHAPES</span><span class="special">,</span><span class="identifier">UDEF_CIRCLE</span><span class="special">)</span>
  146. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SUBTYPE_REGISTER_UDEF_SQUARE</span> <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_UDEF_SHAPES</span><span class="special">,</span><span class="identifier">UDEF_SQUARE</span><span class="special">)</span>
  147. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SUBTYPE_REGISTER_UDEF_TRIANGLE</span> <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_UDEF_SHAPES</span><span class="special">,</span><span class="identifier">UDEF_TRIANGLE</span><span class="special">)</span>
  148. <span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SUBTYPE_REGISTER_UDEF_HEXAGON</span> <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_UDEF_SHAPES</span><span class="special">,</span><span class="identifier">UDEF_HEXAGON</span><span class="special">)</span>
  149. </pre>
  150. <h4>
  151. <a name="variadic_macro_data.vmd_identifier_subtype.h4"></a>
  152. <span class="phrase"><a name="variadic_macro_data.vmd_identifier_subtype.subtype_register_the_v_type_name"></a></span><a class="link" href="vmd_identifier_subtype.html#variadic_macro_data.vmd_identifier_subtype.subtype_register_the_v_type_name">Subtype
  153. register the v-type name for the subtype</a>
  154. </h4>
  155. <p>
  156. Doing a subset register of the actual udef v-type is fairly easy once we understand
  157. how to register an identifier subset. The only particular thing to realize
  158. is that the type of any v-type is the v-type BOOST_VMD_TYPE_TYPE. So our subset
  159. register of our new v-type BOOST_VMD_TYPE_UDEF_SHAPES is:
  160. </p>
  161. <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_VMD_SUBTYPE_REGISTER_BOOST_VMD_TYPE_UDEF_SHAPES</span> <span class="special">(</span><span class="identifier">BOOST_VMD_TYPE_TYPE</span><span class="special">,</span><span class="identifier">BOOST_VMD_TYPE_UDEF_SHAPES</span><span class="special">)</span>
  162. </pre>
  163. <h4>
  164. <a name="variadic_macro_data.vmd_identifier_subtype.h5"></a>
  165. <span class="phrase"><a name="variadic_macro_data.vmd_identifier_subtype.using_our_identifier_subset"></a></span><a class="link" href="vmd_identifier_subtype.html#variadic_macro_data.vmd_identifier_subtype.using_our_identifier_subset">Using
  166. our identifier subset</a>
  167. </h4>
  168. <p>
  169. Once we have added all of the above object-like macros for defining our user-defined
  170. subtype to the udef_vmd_macros.hpp header file we have a new data type which
  171. we can use generically just like we can use numbers or v-types generically.
  172. It is important to include the header udef_vmd_macros.hpp in some translation
  173. unit whenever we need the VMD functionality for our new data type. So in our
  174. examples we will assume that an '#include udef_vmd_macros.hpp' precedes each
  175. example.
  176. </p>
  177. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">get_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  178. <span class="preprocessor">#define</span> <span class="identifier">A_SEQUENCE</span> <span class="identifier">UDEF_SQUARE</span>
  179. <span class="preprocessor">#define</span> <span class="identifier">A_SEQUENCE2</span> <span class="number">217</span>
  180. <span class="preprocessor">#define</span> <span class="identifier">A_SEQUENCE3</span> <span class="identifier">BOOST_VMD_TYPE_UDEF_SHAPES</span>
  181. <span class="preprocessor">#define</span> <span class="identifier">A_SEQUENCE4</span> <span class="identifier">BOOST_VMD_TYPE_NUMBER</span>
  182. <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">A_SEQUENCE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'BOOST_VMD_TYPE_UDEF_SHAPES'</span>
  183. <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">A_SEQUENCE2</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'BOOST_VMD_TYPE_NUMBER'</span>
  184. <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">A_SEQUENCE3</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'BOOST_VMD_TYPE_TYPE'</span>
  185. <span class="identifier">BOOST_VMD_GET_TYPE</span><span class="special">(</span><span class="identifier">A_SEQUENCE4</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'BOOST_VMD_TYPE_TYPE'</span>
  186. </pre>
  187. <p>
  188. Here we see that when we use our BOOST_VMD_GET_TYPE macro on a single-element
  189. sequence which is one of our user-defined subtype values we correctly get back
  190. our user-defined subtype's v-type, just like we do when we ask for the type
  191. of a number. Also when we use our BOOST_VMD_GET_TYPE macro on our user-defined
  192. subtype's v-type itself we correctly get back the type of all v-types, which
  193. is BOOST_VMD_TYPE_TYPE, just like we do when we ask for the type of the v-type
  194. of a number.
  195. </p>
  196. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">elem</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  197. <span class="preprocessor">#define</span> <span class="identifier">A_SEQUENCE5</span> <span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">)</span> <span class="identifier">UDEF_TRIANGLE</span>
  198. <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="identifier">A_SEQUENCE5</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_UDEF_SHAPES,UDEF_TRIANGLE)'</span>
  199. <span class="identifier">BOOST_VMD_ELEM</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="identifier">A_SEQUENCE5</span><span class="special">,</span><span class="identifier">BOOST_VMD_RETURN_TYPE</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'(BOOST_VMD_TYPE_TUPLE,(1,2))'</span>
  200. </pre>
  201. <p>
  202. Here we see that we can use the return type modifier to get back both the type
  203. and the value in a two-element tuple for our user-defined subtype just as we
  204. so for any other type.
  205. </p>
  206. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">vmd</span><span class="special">/</span><span class="identifier">equal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  207. <span class="preprocessor">#define</span> <span class="identifier">A_SEQUENCE6</span> <span class="identifier">UDEF_CIRCLE</span>
  208. <span class="preprocessor">#define</span> <span class="identifier">A_SEQUENCE7</span> <span class="number">168</span>
  209. <span class="identifier">BOOST_VMD_EQUAL</span><span class="special">(</span><span class="identifier">A_SEQUENCE6</span><span class="special">,</span><span class="identifier">UDEF_CIRCLE</span><span class="special">,</span><span class="identifier">BOOST_VMD_TYPE_UDEF_SHAPES</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'1'</span>
  210. <span class="identifier">BOOST_VMD_EQUAL</span><span class="special">(</span><span class="identifier">A_SEQUENCE6</span><span class="special">,</span><span class="identifier">UDEF_CIRCLE</span><span class="special">,</span><span class="identifier">BOOST_VMD_TYPE_LIST</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'0'</span>
  211. <span class="identifier">BOOST_VMD_EQUAL</span><span class="special">(</span><span class="identifier">A_SEQUENCE7</span><span class="special">,</span><span class="number">168</span><span class="special">,</span><span class="identifier">BOOST_VMD_TYPE_NUMBER</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'1'</span>
  212. <span class="identifier">BOOST_VMD_EQUAL</span><span class="special">(</span><span class="identifier">A_SEQUENCE7</span><span class="special">,</span><span class="number">168</span><span class="special">,</span><span class="identifier">BOOST_VMD_TYPE_SEQ</span><span class="special">)</span> <span class="identifier">will</span> <span class="keyword">return</span> <span class="char">'0'</span>
  213. </pre>
  214. <p>
  215. Here we can see that we can use the filter modifier with our user-defined subtype's
  216. v-type just as we can do with any other v-type, such as the number v-type.
  217. </p>
  218. <p>
  219. In all respects once we define our subtype and provide those definitions in
  220. a header file, our user-defined subtype acts like any other v-type in our system.
  221. Since VMD functionality is largely based on being able to recognize the type
  222. of data in macro input being able to define another 'type', as an identifier
  223. subtype, which VMD understands has value for the macro programmer.
  224. </p>
  225. <h4>
  226. <a name="variadic_macro_data.vmd_identifier_subtype.h6"></a>
  227. <span class="phrase"><a name="variadic_macro_data.vmd_identifier_subtype.uniqueness_of_identifier_subtype"></a></span><a class="link" href="vmd_identifier_subtype.html#variadic_macro_data.vmd_identifier_subtype.uniqueness_of_identifier_subtype">Uniqueness
  228. of identifier subtype values and v-type</a>
  229. </h4>
  230. <p>
  231. When we define a new identifier subtype we need to be careful that the values
  232. of that subtype and its actual v-type are unique identifiers within any translation
  233. unit. This is the main difference between just defining identifiers and defining
  234. an identifier subtype.
  235. </p>
  236. <p>
  237. Recall that when we just register and pre-detect identifiers we will have no
  238. problems if the same identifiers already have been registered and pre-detected
  239. within the same translation unit. This is because we are just redefining the
  240. exact same macro if this is the case.
  241. </p>
  242. <p>
  243. But with identifier subtypes, when we use the BOOST_VMD_SUBTYPE_REGISTER_ macro
  244. to associate our subtype's v-type with our subtype identifiers, we will have
  245. problems if someone else has also defined an identifier subtype using the same
  246. identifiers as we use since we will be redefining the same object-like macro
  247. name with a different expansion. Even if someone else has registered/pre-detected
  248. an identifier we are using for out subtype without defining a subtype based
  249. on that identifier we will be causing a problem defining our subtype because
  250. VMD macros which generically return the type of a sequence or sequence element
  251. will return our subtype as the type rather than just BOOST_VMD_TYPE_IDENTIFIER
  252. which some programmer might expect.
  253. </p>
  254. <p>
  255. The gist of this is that if we define a user-defined subtype its identifiers
  256. need to be unique within a given translation unit, and yet unique names make
  257. it harder for an end-user to use macros more naturally. In our given example
  258. with the mythical udef library we used identifiers such as 'UDEF_CIRCLE' etc.
  259. instead of the more natural sounding CIRCLE. So with user-defined identifier
  260. subtypes we have a tradeoff; we need unique identifier names both for our subtype
  261. identifiers and the v-type for our subtype identifiers so as not to conflict
  262. with others who might be using identifier subtypes, but those unique names
  263. might make using macros less "natural" On the other hand, just registering/pre-detecting
  264. identifiers has no such problem. This is an issue of which any user, looking
  265. to create his own data type using VMD by defining user-defined subtypes, should
  266. be aware.
  267. </p>
  268. </div>
  269. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  270. <td align="left"></td>
  271. <td align="right"><div class="copyright-footer">Copyright &#169; 2010-2017 Tropic Software
  272. East Inc</div></td>
  273. </tr></table>
  274. <hr>
  275. <div class="spirit-nav">
  276. <a accesskey="p" href="vmd_modifiers/vmd_modifiers_single.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="vmd_useful.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  277. </div>
  278. </body>
  279. </html>