1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2<html> 3<head> 4<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> 5<title>Adding new predefs</title> 6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> 7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> 9<link rel="up" href="../predef.html" title="Chapter 29. Boost.Predef 1.10"> 10<link rel="prev" href="using_the_predefs.html" title="Using the predefs"> 11<link rel="next" href="reference.html" title="Reference"> 12</head> 13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 14<table cellpadding="2" width="100%"><tr> 15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td> 16<td align="center"><a href="../../../index.html">Home</a></td> 17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> 18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 20<td align="center"><a href="../../../more/index.htm">More</a></td> 21</tr></table> 22<hr> 23<div class="spirit-nav"> 24<a accesskey="p" href="using_the_predefs.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../predef.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="reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> 25</div> 26<div class="section"> 27<div class="titlepage"><div><div><h2 class="title" style="clear: both"> 28<a name="predef.adding_new_predefs"></a><a class="link" href="adding_new_predefs.html" title="Adding new predefs">Adding new predefs</a> 29</h2></div></div></div> 30<p> 31 We know that a library like this one will be an eternal work-in-progress. And 32 as such we expect, and look forward to, others contributing corrections and 33 additions to the predefs. With that in mind we need to keep a consistent way 34 of defining the new predefs. Hence all current, and future, predefs follow 35 the same structure and requirements. 36 </p> 37<h4> 38<a name="predef.adding_new_predefs.h0"></a> 39 <span class="phrase"><a name="predef.adding_new_predefs.requirements_of_the_header"></a></span><a class="link" href="adding_new_predefs.html#predef.adding_new_predefs.requirements_of_the_header">Requirements 40 of the header</a> 41 </h4> 42<p> 43 All predefs need to follow a set of requirements: 44 </p> 45<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 46<li class="listitem"> 47 The headers must use the Boost Software License. 48 </li> 49<li class="listitem"> 50 The predef must, by default, be defined as <code class="computeroutput"><span class="identifier">BOOST_VERSION_NUMBER_NOT_AVAILABLE</span></code>. 51 </li> 52<li class="listitem"> 53 The predef must be redefined to a non-zero value once detected. 54 </li> 55<li class="listitem"> 56 The predef must, by default, be defined to <code class="computeroutput"><span class="identifier">BOOST_VERSION_NUMBER_AVAILABLE</span></code> 57 when the predef is detected. 58 </li> 59<li class="listitem"> 60 If possible, the predef will be defined as the version number detected. 61 </li> 62<li class="listitem"> 63 The predef must define <code class="computeroutput"><span class="special">*</span><span class="identifier">_AVAILABLE</span></code> 64 macros as needed. 65 </li> 66<li class="listitem"> 67 The predef must define a symbolic constant string name macro. 68 </li> 69<li class="listitem"> 70 The predef must declare itself, after being defined, for the testing system. 71 </li> 72<li class="listitem"> 73 The predef must guarantee that it is the only one defined as detected per 74 category. 75 </li> 76<li class="listitem"> 77 But a predef can define <code class="computeroutput"><span class="special">*</span><span class="identifier">_EMULATED</span></code> macros to indicate that it 78 was previously detected by another header and is being "emulated" 79 by the system. Note that the <code class="computeroutput"><span class="special">*</span><span class="identifier">_AVAILABLE</span></code> macros must still be defined 80 in this situation. 81 </li> 82</ul></div> 83<p> 84 And there are some extra guidelines that predef headers should follow: 85 </p> 86<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 87<li class="listitem"> 88 The detection should avoid including extra headers that might otherwise 89 not be included by default. 90 </li> 91<li class="listitem"> 92 If the detection must include a header, prefer guarding it within the detection 93 if possible. 94 </li> 95<li class="listitem"> 96 If the detection must include headers unconditionally, and has a choice 97 of headers to include, prefer the ones with the least impact. I.e. include 98 the one with the minimal set of definitions and other dependencies. 99 </li> 100</ul></div> 101<h4> 102<a name="predef.adding_new_predefs.h1"></a> 103 <span class="phrase"><a name="predef.adding_new_predefs.structure_of_the_header"></a></span><a class="link" href="adding_new_predefs.html#predef.adding_new_predefs.structure_of_the_header">Structure 104 of the header</a> 105 </h4> 106<p> 107 For general consistency it's suggested that new predef headers follow the structure 108 below, as current predef headers do. First we have the copyright and license 109 statement, followed by the include guard: 110 </p> 111<pre class="programlisting"><span class="comment">/* 112Copyright Jane Doe YYYY 113Distributed under the Boost Software License, Version 1.0. 114(See accompanying file LICENSE_1_0.txt or copy at 115http://www.boost.org/LICENSE_1_0.txt) 116*/</span> 117 118<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_PREDEF_category_tag_H</span> 119<span class="preprocessor">#define</span> <span class="identifier">BOOST_PREDEF_category_tag_H</span> 120</pre> 121<p> 122 If the detection depends on the detection of another predef you should include 123 those headers here. 124 </p> 125<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">predef</span><span class="special">/</span><span class="identifier">CATEGORY_TAG</span><span class="special">/</span><span class="identifier">DEPENDENCY</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span> 126</pre> 127<p> 128 Depending on how you are defining the predef you will at minimum have to include 129 the <code class="computeroutput"><span class="identifier">version_number</span><span class="special">.</span><span class="identifier">h</span></code> header. But you might also want to include 130 the <code class="computeroutput"><span class="identifier">make</span><span class="special">.</span><span class="identifier">h</span></code> header for the version number decomposing 131 utility macros: 132 </p> 133<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">predef</span><span class="special">/</span><span class="identifier">version_number</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span> 134<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">predef</span><span class="special">/</span><span class="identifier">make</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span> 135</pre> 136<p> 137 The Predef library uses Quickbook for documentation and for the individual 138 predefs to appear in the reference section we add in-code documentation followed 139 by the zero-value default definition of the predef macro. We strongly recommend 140 this particular placement of the documentation and default definition because 141 some development environments automatically interpret this and provide in-line 142 help for the macro. In particular this works for the popular Eclipse IDE: 143 </p> 144<pre class="programlisting"><span class="comment">/*` 145[heading `BOOST_category_tag`] 146 147Documentation about what is detected. 148*/</span> 149 150<span class="preprocessor">#define</span> <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER_NOT_AVAILABLE</span> 151</pre> 152<p> 153 Next is the detection and definition of the particular predef. The structure 154 for this is to do a single overall check (<code class="computeroutput"><span class="identifier">condition_a</span></code>) 155 and place further version detection inside this. The first action inside the 156 overall check is to "<code class="computeroutput"><span class="preprocessor">#undef</span> 157 <span class="identifier">BOOST_category_tag</span></code>" which undefines 158 the zero-value default. The rest is up to the you how to do the checks for 159 defining the version. But at minimum it must "<code class="computeroutput"><span class="preprocessor">#define</span> 160 <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER_AVAILABLE</span></code>" 161 as the fallback to minimally indicate that the predef was detected: 162 </p> 163<pre class="programlisting"><span class="preprocessor">#if</span> <span class="special">(</span><span class="identifier">condition_a</span><span class="special">)</span> 164<span class="preprocessor"># undef</span> <span class="identifier">BOOST_category_tag</span> 165<span class="preprocessor"># if</span> <span class="special">(</span><span class="identifier">condition_b</span><span class="special">)</span> 166<span class="preprocessor"># define</span> <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER</span><span class="special">(</span><span class="identifier">major</span><span class="special">,</span><span class="identifier">minor</span><span class="special">,</span><span class="identifier">patch</span><span class="special">)</span> 167<span class="preprocessor"># else</span> 168<span class="preprocessor"># define</span> <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER_AVAILABLE</span> 169<span class="preprocessor"># endif</span> 170<span class="preprocessor">#endif</span> 171</pre> 172<p> 173 We also need to provide the <code class="computeroutput"><span class="special">*</span><span class="identifier">_AVAILABLE</span></code> versions of the predef. 174 </p> 175<pre class="programlisting"><span class="preprocessor">#if</span> <span class="identifier">BOOST_category_tag</span> 176<span class="preprocessor"># define</span> <span class="identifier">BOOST_category_tag_AVAILABLE</span> 177<span class="preprocessor">#endif</span> 178</pre> 179<p> 180 And for convenience we also want to provide a <code class="computeroutput"><span class="special">*</span><span class="identifier">_NAME</span></code> macro: 181 </p> 182<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_category_tag_NAME</span> <span class="string">"Name"</span> 183</pre> 184<p> 185 The testing of the predef macros is automated to generate checks for all the 186 defined predefs, whether detected or not. To do this we need to declare the 187 predef to the test system. This declaration is empty for regular use. And during 188 the test programs they expand out specially to create informational output: 189 </p> 190<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">predef</span><span class="special">/</span><span class="identifier">detail</span><span class="special">/</span><span class="identifier">test</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span> 191<span class="identifier">BOOST_PREDEF_DECLARE_TEST</span><span class="special">(</span><span class="identifier">BOOST_category_tag</span><span class="special">,</span><span class="identifier">BOOST_category_tag_NAME</span><span class="special">)</span> 192</pre> 193<p> 194 And, of course, we last need to close out the include guard: 195 </p> 196<pre class="programlisting"><span class="preprocessor">#endif</span> 197</pre> 198<h4> 199<a name="predef.adding_new_predefs.h2"></a> 200 <span class="phrase"><a name="predef.adding_new_predefs.adding_exclusive_predefs"></a></span><a class="link" href="adding_new_predefs.html#predef.adding_new_predefs.adding_exclusive_predefs">Adding 201 exclusive predefs</a> 202 </h4> 203<p> 204 For headers of predefs that need to be mutually exclusive in the detection 205 we need to add checks and definitions to detect when the predef is detected 206 by multiple headers. 207 </p> 208<p> 209 Internally compiler, operating system, and platforms define <code class="computeroutput"><span class="identifier">BOOST_PREDEF_DETAIL_COMP_DETECTED</span></code>, 210 <code class="computeroutput"><span class="identifier">BOOST_PREDEF_DEFAIL_OS_DETECTED</span></code>, 211 and <code class="computeroutput"><span class="identifier">BOOST_PREDEF_DETAIL_PLAT_DETECTED</span></code> 212 respectively when the predef is first detected. This is used to guard against 213 multiple definition of the detection in later included headers. In those cases 214 the detection would instead be written as: 215 </p> 216<pre class="programlisting"><span class="preprocessor">#if</span> <span class="special">!</span><span class="identifier">BOOST_PREDEF_DETAIL_category_DETECTED</span> <span class="special">&&</span> <span class="special">(</span><span class="identifier">condition_a</span><span class="special">)</span> 217<span class="preprocessor"># undef</span> <span class="identifier">BOOST_category_tag</span> 218<span class="preprocessor"># if</span> <span class="special">(</span><span class="identifier">condition_b</span><span class="special">)</span> 219<span class="preprocessor"># define</span> <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER</span><span class="special">(</span><span class="identifier">major</span><span class="special">,</span><span class="identifier">minor</span><span class="special">,</span><span class="identifier">patch</span><span class="special">)</span> 220<span class="preprocessor"># else</span> 221<span class="preprocessor"># define</span> <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER</span><span class="special">(</span><span class="number">0</span><span class="special">,</span><span class="number">0</span><span class="special">,</span><span class="number">1</span><span class="special">)</span> 222<span class="preprocessor"># endif</span> 223<span class="preprocessor">#endif</span> 224</pre> 225<p> 226 And we also include a header that defines the <code class="computeroutput"><span class="special">*</span><span class="identifier">_DETECTED</span></code> macro when we have the detection: 227 </p> 228<pre class="programlisting"><span class="preprocessor">#if</span> <span class="identifier">BOOST_category_tag</span> 229<span class="preprocessor"># define</span> <span class="identifier">BOOST_category_tag_AVAILABLE</span> 230<span class="preprocessor"># include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">predef</span><span class="special">/</span><span class="identifier">detail</span><span class="special">/</span><span class="identifier">CATEGORY_detected</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span> 231<span class="preprocessor">#endif</span> 232</pre> 233<p> 234 Everything else about the header is the same as the basic detection header. 235 </p> 236<h4> 237<a name="predef.adding_new_predefs.h3"></a> 238 <span class="phrase"><a name="predef.adding_new_predefs.adding_an_exclusive_but_emulated"></a></span><a class="link" href="adding_new_predefs.html#predef.adding_new_predefs.adding_an_exclusive_but_emulated">Adding 239 an exclusive but emulated predef</a> 240 </h4> 241<p> 242 Because compilers are frequently emulated by other compilers we both want to 243 have exclusive detection of the compiler and also provide information that 244 we detected the emulation of the compiler. To accomplish this we define a local 245 <code class="computeroutput"><span class="special">*</span><span class="identifier">_DETECTION</span></code> 246 macro for the compiler detection. And conditionally define either the base 247 compiler predef <code class="computeroutput"><span class="identifier">BOOST_COMP_compiler</span></code> 248 or the alternate <code class="computeroutput"><span class="identifier">BOOST_COMP_compiler_EMULATED</span></code> 249 predef. 250 </p> 251<p> 252 The initial detection would look like: 253 </p> 254<pre class="programlisting"><span class="preprocessor">#if</span> <span class="special">(</span><span class="identifier">condition_a</span><span class="special">)</span> 255<span class="preprocessor"># if</span> <span class="special">(</span><span class="identifier">condition_b</span><span class="special">)</span> 256<span class="preprocessor"># define</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span> <span class="identifier">BOOST_VERSION_NUMBER</span><span class="special">(</span><span class="identifier">major</span><span class="special">,</span><span class="identifier">minor</span><span class="special">,</span><span class="identifier">patch</span><span class="special">)</span> 257<span class="preprocessor"># else</span> 258<span class="preprocessor"># define</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span> <span class="identifier">BOOST_VERSION_NUMBER_AVAILABLE</span> 259<span class="preprocessor"># endif</span> 260<span class="preprocessor">#endif</span> 261</pre> 262<p> 263 And then we can conditionally define the base or emulated predefs: 264 </p> 265<pre class="programlisting"><span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span> 266<span class="preprocessor"># if</span> <span class="identifier">defined</span><span class="special">(</span><span class="identifier">BOOST_PREDEF_DETAIL_COMP_DETECTED</span><span class="special">)</span> 267<span class="preprocessor"># define</span> <span class="identifier">BOOST_COMP_tag_EMULATED</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span> 268<span class="preprocessor"># else</span> 269<span class="preprocessor"># undef</span> <span class="identifier">BOOST_COMP_tag</span> 270<span class="preprocessor"># define</span> <span class="identifier">BOOST_COMP_tag</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span> 271<span class="preprocessor"># endif</span> 272<span class="preprocessor"># define</span> <span class="identifier">BOOST_category_tag_AVAILABLE</span> 273<span class="preprocessor"># include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">predef</span><span class="special">/</span><span class="identifier">detail</span><span class="special">/</span><span class="identifier">comp_detected</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span> 274<span class="preprocessor">#endif</span> 275</pre> 276<h4> 277<a name="predef.adding_new_predefs.h4"></a> 278 <span class="phrase"><a name="predef.adding_new_predefs.using_utility_pattern_macros"></a></span><a class="link" href="adding_new_predefs.html#predef.adding_new_predefs.using_utility_pattern_macros">Using utility 279 pattern macros</a> 280 </h4> 281<p> 282 By including: 283 </p> 284<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">predef</span><span class="special">/</span><span class="identifier">make</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span> 285</pre> 286<p> 287 One will get a set of utility macros to decompose common version macros as 288 defined by compilers. For example the EDG compiler uses a simple 3-digit version 289 macro (M,N,P). It can be decomposed and defined as: 290 </p> 291<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_COMP_EDG</span> <span class="identifier">BOOST_PREDEF_MAKE_N_N_N</span><span class="special">(</span><span class="identifier">__EDG_VERSION__</span><span class="special">)</span> 292</pre> 293<p> 294 The decomposition macros are split into three types: decimal decomposition, 295 hexadecimal decomposition, and date decomposition. They follow the format of 296 using "N" for decimal, "F" for hexadecimal, and "Y", 297 "M", "D" for dates. 298 </p> 299</div> 300<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 301<td align="left"></td> 302<td align="right"><div class="copyright-footer">Copyright © 2005-2019 Rene Rivera<br>Copyright © 2015 Charly Chevalier<br>Copyright © 2015 Joel Falcou<p> 303 Distributed under the Boost Software License, Version 1.0. (See accompanying 304 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) 305 </p> 306</div></td> 307</tr></table> 308<hr> 309<div class="spirit-nav"> 310<a accesskey="p" href="using_the_predefs.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../predef.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="reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> 311</div> 312</body> 313</html> 314