• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&#160;29.&#160;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">&lt;</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">&gt;</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">&lt;</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">&gt;</span>
134<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">&lt;</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">&gt;</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">&amp;&amp;</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">&lt;</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">&gt;</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">&lt;</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">&gt;</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">&lt;</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">&gt;</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 &#169; 2005-2019 Rene Rivera<br>Copyright &#169; 2015 Charly Chevalier<br>Copyright &#169; 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