summaryrefslogtreecommitdiff
path: root/libs/predef/doc/html/predef/adding_new_predefs.html
blob: 091b7b7f3e319f0c3a66808968414f02e2fbc656 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Adding new predefs</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="Predef 1.1">
<link rel="up" href="../index.html" title="Predef 1.1">
<link rel="prev" href="using_the_predefs.html" title="Using the predefs">
<link rel="next" href="reference.html" title="Reference">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="spirit-nav">
<a accesskey="p" href="using_the_predefs.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="predef.adding_new_predefs"></a><a class="link" href="adding_new_predefs.html" title="Adding new predefs">Adding new predefs</a>
</h2></div></div></div>
<p>
      We know that a library like this one will be an eternal work-in-progress. And
      as such we expect, and look forward to, others contributing corrections and
      additions to the predefs. With that in mind we need to keep a consistent way
      of defining the new predefs. Hence all current, and future, predefs follow
      the same structure and requirements.
    </p>
<h4>
<a name="predef.adding_new_predefs.h0"></a>
      <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
      of the header</a>
    </h4>
<p>
      All predefs need to follow a set of requirements:
    </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
          The headers must use the Boost Software License.
        </li>
<li class="listitem">
          The predef must, by default, be defined as <code class="computeroutput"><span class="identifier">BOOST_VERSION_NUMBER_NOT_AVAILABLE</span></code>.
        </li>
<li class="listitem">
          The predef must be redefined to a non-zero value once detected.
        </li>
<li class="listitem">
          The predef must, by default, be defined to <code class="computeroutput"><span class="identifier">BOOST_VERSION_NUMBER_AVAILABLE</span></code>
          when the predef is detected.
        </li>
<li class="listitem">
          If possible, the predef will be defined as the version number detected.
        </li>
<li class="listitem">
          The predef must define <code class="computeroutput"><span class="special">*</span><span class="identifier">_AVAILABLE</span></code>
          macros as needed.
        </li>
<li class="listitem">
          The predef must define a symbolic constant string name macro.
        </li>
<li class="listitem">
          The predef must declare itself, after being defined, for the testing system.
        </li>
<li class="listitem">
          The predef must guarantee that it is the only one defined as detected per
          category.
        </li>
<li class="listitem">
          But a predef can define <code class="computeroutput"><span class="special">*</span><span class="identifier">_EMULATED</span></code> macros to indicate that it
          was previously detected by another header and is being "emulated"
          by the system. Note that the <code class="computeroutput"><span class="special">*</span><span class="identifier">_AVAILABLE</span></code> macros must still be defined
          in this situation.
        </li>
</ul></div>
<p>
      And there are some extra guidelines that predef headers should follow:
    </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
          The detection should avoid including extra headers that might otherwise
          not be included by default.
        </li>
<li class="listitem">
          If the detection must include a header, prefer guarding it within the detection
          if possible.
        </li>
<li class="listitem">
          If the detection must include headers unconditionally, and has a choice
          of headers to include, prefer the ones with the least impact. I.e. include
          the one with the minimal set of definitions and other dependencies.
        </li>
</ul></div>
<h4>
<a name="predef.adding_new_predefs.h1"></a>
      <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
      of the header</a>
    </h4>
<p>
      For general consistency it's suggested that new predef headers follow the structure
      below, as current predef headers do. First we have the copyright and license
      statement, followed by the include guard:
    </p>
<pre class="programlisting"><span class="comment">/*
Copyright Jane Doe YYYY
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/</span>

<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_PREDEF_category_tag_H</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_PREDEF_category_tag_H</span>
</pre>
<p>
      If the detection depends on the detection of another predef you should include
      those headers here.
    </p>
<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>
</pre>
<p>
      Depending on how you are defining the predef you will at minimum have to include
      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
      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
      utility macros:
    </p>
<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>
<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>
</pre>
<p>
      The Predef library uses Quickbook for documentation and for the individual
      predefs to appear in the reference section we add in-code documentation followed
      by the zero-value default definition of the predef macro. We strongly recommend
      this particular placement of the documentation and default definition because
      some development environments automatically interpret this and provide in-line
      help for the macro. In particular this works for the popular Eclipse IDE:
    </p>
<pre class="programlisting"><span class="comment">/*`
[heading `BOOST_category_tag`]

Documentation about what is detected.
*/</span>

<span class="preprocessor">#define</span> <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER_NOT_AVAILABLE</span>
</pre>
<p>
      Next is the detection and definition of the particular predef. The structure
      for this is to do a single overall check (<code class="computeroutput"><span class="identifier">condition_a</span></code>)
      and place further version detection inside this. The first action inside the
      overall check is to "<code class="computeroutput"><span class="preprocessor">#undef</span>
      <span class="identifier">BOOST_category_tag</span></code>" which undefines
      the zero-value default. The rest is up to the you how to do the checks for
      defining the version. But at minimum it must "<code class="computeroutput"><span class="preprocessor">#define</span>
      <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER_AVAILABLE</span></code>"
      as the fallback to minimally indicate that the predef was detected:
    </p>
<pre class="programlisting"><span class="preprocessor">#if</span> <span class="special">(</span><span class="identifier">condition_a</span><span class="special">)</span>
<span class="preprocessor">#   undef</span> <span class="identifier">BOOST_category_tag</span>
<span class="preprocessor">#   if</span> <span class="special">(</span><span class="identifier">condition_b</span><span class="special">)</span>
<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>
<span class="preprocessor">#    else</span>
<span class="preprocessor">#        define</span> <span class="identifier">BOOST_category_tag</span> <span class="identifier">BOOST_VERSION_NUMBER_AVAILABLE</span>
<span class="preprocessor">#    endif</span>
<span class="preprocessor">#endif</span>
</pre>
<p>
      We also need to provide the <code class="computeroutput"><span class="special">*</span><span class="identifier">_AVAILABLE</span></code> versions of the predef.
    </p>
<pre class="programlisting"><span class="preprocessor">#if</span> <span class="identifier">BOOST_category_tag</span>
<span class="preprocessor">#   define</span> <span class="identifier">BOOST_category_tag_AVAILABLE</span>
<span class="preprocessor">#endif</span>
</pre>
<p>
      And for convenience we also want to provide a <code class="computeroutput"><span class="special">*</span><span class="identifier">_NAME</span></code> macro:
    </p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_catagory_tag_NAME</span> <span class="string">"Name"</span>
</pre>
<p>
      The testing of the predef macros is automated to generate checks for all the
      defined predefs, whether detected or not. To do this we need to declare the
      predef to the test system. This declaration is empty for regular use. And during
      the test programs they expand out specially to create informational output:
    </p>
<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>
<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>
</pre>
<p>
      And, of course, we last need to close out the include guard:
    </p>
<pre class="programlisting"><span class="preprocessor">#endif</span>
</pre>
<h4>
<a name="predef.adding_new_predefs.h2"></a>
      <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
      exclusive predefs</a>
    </h4>
<p>
      For headers of predefs that need to be mutually exclusive in the detection
      we need to add checks and definitions to detect when the predef is detected
      by multiple headers.
    </p>
<p>
      Internally compiler, operating system, and platforms define <code class="computeroutput"><span class="identifier">BOOST_PREDEF_DETAIL_COMP_DETECTED</span></code>,
      <code class="computeroutput"><span class="identifier">BOOST_PREDEF_DEFAIL_OS_DETECTED</span></code>,
      and <code class="computeroutput"><span class="identifier">BOOST_PREDEF_DETAIL_PLAT_DETECTED</span></code>
      respectively when the predef is first detected. This is used to guard against
      multiple definition of the detection in later included headers. In those cases
      the detection would instead be written as:
    </p>
<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>
<span class="preprocessor">#   undef</span> <span class="identifier">BOOST_category_tag</span>
<span class="preprocessor">#   if</span> <span class="special">(</span><span class="identifier">condition_b</span><span class="special">)</span>
<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>
<span class="preprocessor">#    else</span>
<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>
<span class="preprocessor">#    endif</span>
<span class="preprocessor">#endif</span>
</pre>
<p>
      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:
    </p>
<pre class="programlisting"><span class="preprocessor">#if</span> <span class="identifier">BOOST_category_tag</span>
<span class="preprocessor">#   define</span> <span class="identifier">BOOST_category_tag_AVAILABLE</span>
<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>
<span class="preprocessor">#endif</span>
</pre>
<p>
      Everything else about the header is the same as the basic detection header.
    </p>
<h4>
<a name="predef.adding_new_predefs.h3"></a>
      <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
      an exclusive but emulated predef</a>
    </h4>
<p>
      Because compilers are frequently emulated by other compilers we both want to
      have exclusive detection of the compiler and also provide information that
      we detected the emulation of the compiler. To accomplish this we define a local
      <code class="computeroutput"><span class="special">*</span><span class="identifier">_DETECTION</span></code>
      macro for the compiler detection. And conditionally define either the base
      compiler predef <code class="computeroutput"><span class="identifier">BOOST_COMP_compiler</span></code>
      or the alternate <code class="computeroutput"><span class="identifier">BOOST_COMP_compiler_EMULATED</span></code>
      predef.
    </p>
<p>
      The initial detection would look like:
    </p>
<pre class="programlisting"><span class="preprocessor">#if</span> <span class="special">(</span><span class="identifier">condition_a</span><span class="special">)</span>
<span class="preprocessor">#   if</span> <span class="special">(</span><span class="identifier">condition_b</span><span class="special">)</span>
<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>
<span class="preprocessor">#    else</span>
<span class="preprocessor">#        define</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span> <span class="identifier">BOOST_VERSION_NUMBER_AVAILABLE</span>
<span class="preprocessor">#    endif</span>
<span class="preprocessor">#endif</span>
</pre>
<p>
      And then we can conditionally define the base or emulated predefs:
    </p>
<pre class="programlisting"><span class="preprocessor">#ifdef</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span>
<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>
<span class="preprocessor">#       define</span> <span class="identifier">BOOST_COMP_tag_EMULATED</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span>
<span class="preprocessor">#   else</span>
<span class="preprocessor">#       undef</span> <span class="identifier">BOOST_COMP_tag</span>
<span class="preprocessor">#       define</span> <span class="identifier">BOOST_COMP_tag</span> <span class="identifier">BOOST_COMP_tag_DETECTION</span>
<span class="preprocessor">#   endif</span>
<span class="preprocessor">#   define</span> <span class="identifier">BOOST_category_tag_AVAILABLE</span>
<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>
<span class="preprocessor">#endif</span>
</pre>
<h4>
<a name="predef.adding_new_predefs.h4"></a>
      <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
      pattern macros</a>
    </h4>
<p>
      By including:
    </p>
<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>
</pre>
<p>
      One will get a set of utility macros to decompose common version macros as
      defined by compilers. For example the EDG compiler uses a simple 3-digit version
      macro (M,N,P). It can be decomposed and defined as:
    </p>
<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">BOOST_CCOMP_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>
</pre>
<p>
      The decomposition macros are split into three types: decimal decomposition,
      hexadecimal decomposition, and date decomposition. They follow the format of
      using "N" for decimal, "F" for hexadecimal, and "Y",
      "M", "D" for dates.
    </p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2005, 2008-2014 Rene Rivera<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        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>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="using_the_predefs.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../images/next.png" alt="Next"></a>
</div>
</body>
</html>