]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns="http://www.w3.org/TR/REC-html40"> |
2 | ||
3 | <head> | |
4 | <meta name="GENERATOR" content="Microsoft FrontPage 5.0"> | |
5 | <meta name="ProgId" content="FrontPage.Editor.Document"> | |
6 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
7 | ||
8 | <title>Endian Library</title> | |
9 | <link href="styles.css" rel="stylesheet"> | |
10 | </head> | |
11 | ||
12 | <body> | |
13 | ||
14 | <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> | |
15 | <tr> | |
16 | <td width="339"> | |
17 | <a href="../../../index.html"> | |
18 | <img src="../../../boost.png" alt="Boost logo" align="middle" border="0" width="277" height="86"></a></td> | |
19 | <td align="middle" width="1253"> | |
20 | <b> | |
21 | <font size="6">Endian Library</font></b></td> | |
22 | </tr> | |
23 | </table> | |
24 | ||
25 | <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" | |
26 | bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> | |
27 | <tr> | |
28 | <td><b> | |
29 | <a href="index.html">Endian Home</a> | |
30 | <a href="conversion.html">Conversion Functions</a> | |
31 | <a href="arithmetic.html">Arithmetic Types</a> | |
32 | <a href="buffers.html">Buffer Types</a> | |
33 | <a href="choosing_approach.html">Choosing Approach</a></b></td> | |
34 | </tr> | |
35 | </table> | |
36 | <p></p> | |
37 | ||
38 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> | |
39 | <tr> | |
40 | <td width="100%" bgcolor="#D7EEFF" align="center"> | |
41 | <i><b>Contents</b></i></td> | |
42 | </tr> | |
43 | <tr> | |
44 | <td width="100%" bgcolor="#E8F5FF"> | |
45 | <a href="#Abstract">Abstract</a><br> | |
46 | <a href="#Introduction-to-endianness">Introduction to endianness</a><br> | |
47 | <a href="#Introduction">Introduction to the Boost.Endian library</a><br> | |
48 | <a href="#Choosing">Choosing between conversion functions,</a><br> | |
49 | <a href="#Choosing">buffer types, and arithmetic types</a><br> | |
50 | <a href="#Intrinsic">Built-in support for Intrinsics</a><br> | |
51 | <a href="#Performance">Performance</a><br> | |
52 | <a href="#Timings">Timings</a><br> | |
53 | <a href="#FAQ">Overall FAQ</a><br> | |
54 | <a href="#Release-history">Release history</a><br> | |
55 | <a href="#Changes-requested-by-formal-review">Changes | |
56 | requested by formal review</a><br> | |
57 | <a href="#Other-changes-since-formal-review">Other changes since | |
58 | formal review</a><br> | |
59 | <a href="#Compatibility">Compatibility with interim releases</a><br> | |
60 | <a href="#C++03-support">C++03 support for C++11 features</a><br> | |
61 | <a href="#Future-directions">Future directions</a><br> | |
62 | <a href="#Acknowledgements">Acknowledgements</a><br> | |
63 | </td> | |
64 | </tr> | |
65 | </table> | |
66 | ||
67 | <h2><a name="Abstract">Abstract</a></h2> | |
68 | ||
69 | <p>Boost.Endian provides facilities to manipulate the | |
70 | <a href="#Introduction-to-endianness">endianness</a> of integers and user-defined types.</p> | |
71 | <ul> | |
72 | <li>Three approaches to endianness are supported. Each has a | |
73 | long history of successful use, and each approach has use cases where it is | |
74 | preferred over the other approaches.<br> | |
75 | </li> | |
76 | <li>Primary uses:<br> | |
77 | <ul> | |
78 | <li>Data portability. The Endian library supports binary data exchange, via either external media or network transmission, | |
79 | regardless of platform endianness.<br> | |
80 | </li> | |
81 | <li>Program portability. POSIX-based and | |
82 | Windows-based operating systems traditionally supply libraries with | |
83 | non-portable functions to perform endian conversion. There are at least four | |
84 | incompatible sets of functions in common use. The Endian library is | |
85 | portable across all C++ platforms.<br> | |
86 | </li> | |
87 | </ul> | |
88 | ||
89 | </li> | |
90 | <li>Secondary use: Minimizing data size via sizes and/or alignments not supported by the | |
91 | standard C++ integer types.</li> | |
92 | </ul> | |
93 | ||
94 | <h2><a name="Introduction-to-endianness">Introduction to endianness</a></h2> | |
95 | ||
96 | <p>Consider the following code:</p> | |
97 | ||
98 | <blockquote> | |
99 | <pre>int16_t i = 0x0102; | |
100 | FILE * file = fopen("test.bin", "wb"); // binary file! | |
101 | fwrite(&i, sizeof(int16_t), 1, file); | |
102 | fclose(file);</pre> | |
103 | </blockquote> | |
104 | <p>On OS X, Linux, or Windows systems with an Intel CPU, a hex dump | |
105 | of the "test.bin" output file produces:</p> | |
106 | <blockquote> | |
107 | <p><code>0201</code></p> | |
108 | </blockquote> | |
109 | <p>On OS X systems with a PowerPC CPU, or Solaris systems with a SPARC CPU, a hex dump of the "test.bin" | |
110 | output file produces:</p> | |
111 | <blockquote> | |
112 | <p><code>0102</code></p> | |
113 | </blockquote> | |
114 | <p>What's happening here is that Intel CPUs order the bytes of an integer with | |
115 | the least-significant byte first, while SPARC CPUs place the most-significant | |
116 | byte first. Some CPUs, such as the PowerPC, allow the operating system to | |
117 | choose which ordering applies.</p> | |
118 | <p><a name="definition"></a>Most-significant-byte-first ordering is traditionally called "big endian" | |
119 | ordering and least-significant-byte-first is traditionally called | |
120 | "little-endian" ordering. The names are derived from | |
121 | <a href="http://en.wikipedia.org/wiki/Jonathan_Swift" title="Jonathan Swift"> | |
122 | Jonathan Swift</a>'s satirical novel <i> | |
123 | <a href="http://en.wikipedia.org/wiki/Gulliver's_Travels" title="Gulliver's Travels"> | |
124 | Gulliver’s Travels</a></i>, where rival kingdoms opened their soft-boiled eggs | |
125 | at different ends.</p> | |
126 | <p>See Wikipedia's | |
127 | <a href="http://en.wikipedia.org/wiki/Endianness">Endianness</a> article for an | |
128 | extensive discussion of endianness.</p> | |
129 | <p>Programmers can usually ignore endianness, except when reading a core | |
130 | dump on little-endian systems. But programmers have to deal with endianness when exchanging binary integers and binary floating point | |
131 | values between computer systems with differing endianness, whether by physical file transfer or over a network. | |
132 | And programmers may also want to use the library when minimizing either internal or | |
133 | external data sizes is advantageous.</p> | |
134 | <h2><a name="Introduction">Introduction</a> to the Boost.Endian library</h2> | |
135 | ||
136 | <p>Boost.Endian provides three different approaches to dealing with | |
137 | ||
138 | endianness. All three approaches support integers and user-define types (UDTs).</p> | |
139 | ||
140 | <p>Each approach has a long history of successful use, and each approach has use | |
141 | cases where it is preferred to the other approaches.</p> | |
142 | ||
143 | <blockquote> | |
144 | ||
145 | <p><b><a href="conversion.html">Endian conversion functions</a> -</b> The | |
146 | application uses the built-in integer types to hold values, and calls the | |
147 | provided conversion functions to convert byte ordering as needed. Both mutating | |
148 | and non-mutating conversions are supplied, and each comes in unconditional and | |
149 | conditional variants.</p> | |
150 | ||
151 | <p><b><a href="buffers.html">Endian buffer types</a> -</b> The application uses the provided endian | |
152 | buffer types | |
153 | to hold values, and explicitly converts to and from the built-in integer types. Buffer sizes of 8, 16, 24, 32, 40, 48, 56, and 64 bits (i.e. | |
154 | 1, 2, 3, 4, 5, 6, 7, and 8 bytes) are provided. Unaligned integer buffer types | |
155 | are provided for all sizes, and aligned buffer types are provided for 16, 32, and | |
156 | 64-bit sizes. The provided specific types are typedefs for a generic class | |
157 | template that may be used directly for less common use cases.</p> | |
158 | ||
159 | <p><b><a href="arithmetic.html">Endian arithmetic types</a> -</b> The | |
160 | application uses the provided endian arithmetic types, which supply the same | |
161 | operations as the built-in C++ arithmetic types. All conversions are implicit. | |
162 | Arithmetic sizes of 8, 16, 24, 32, 40, 48, 56, and 64 bits (i.e. 1, 2, 3, 4, 5, | |
163 | 6, 7, and 8 bytes) are provided. Unaligned integer types are provided for all | |
164 | sizes and aligned | |
165 | arithmetic types are provided for 16, 32, and 64-bit sizes. The provided | |
166 | specific types are typedefs for a generic class template that may be used | |
167 | directly in generic code of for less common use cases.</p> | |
168 | ||
169 | </blockquote> | |
170 | ||
171 | <p>Boost Endian is a header-only library. C++11 features | |
172 | affecting interfaces, such as <code>noexcept</code>, are used only if available. | |
173 | See <a href="#C++03-support">C++03 support for C++11 features</a> for details.</p> | |
174 | ||
175 | <h2><a name="Choosing">Choosing</a> between conversion functions, buffer types, | |
176 | and arithmetic types</h2> | |
177 | ||
178 | <p>This section has been moved to its own <a href="choosing_approach.html"> | |
179 | Choosing the Approach</a> page. </p> | |
180 | ||
181 | <h2>Built-in support for <a name="Intrinsic">Intrinsic</a>s</h2> | |
182 | <p>Most compilers, including GCC, Clang, and Visual C++, supply built-in support for byte swapping intrinsics. | |
183 | The Endian library uses these intrinsics when available since they may result in smaller and faster generated code, particularly for | |
184 | optimized | |
185 | builds.</p> | |
186 | <p>Defining the macro <code>BOOST_ENDIAN_NO_INTRINSICS</code> will suppress use | |
187 | of the intrinsics. This is useful when a compiler has no intrinsic support or | |
188 | fails to locate the appropriate header, perhaps because it | |
189 | is an older release or has very limited supporting libraries.</p> | |
190 | <p>The macro <code>BOOST_ENDIAN_INTRINSIC_MSG</code> is defined as | |
191 | either <code>"no byte swap intrinsics"</code> or a string describing the | |
192 | particular set of intrinsics being used. This is useful for eliminating missing | |
193 | intrinsics as a source of performance issues.</p> | |
194 | ||
195 | <h2><a name="Performance">Performance</a></h2> | |
196 | ||
197 | <p>Consider this problem:</p> | |
198 | ||
199 | <div align="center"> | |
200 | <center> | |
201 | ||
202 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> | |
203 | <tr> | |
204 | <td colspan="2"> | |
205 | <p align="center"><i><b><a name="Example-1">Example 1</a></b></i></td> | |
206 | </tr> | |
207 | <tr> | |
208 | <td colspan="2"><b><i>Add 100 to a big endian value in a file, then write the | |
209 | result to a file</i> </b> </td> | |
210 | </tr> | |
211 | <tr> | |
212 | <td><i><b>Endian arithmetic type approach</b></i></td> | |
213 | <td><i><b>Endian conversion function approach</b></i></td> | |
214 | </tr> | |
215 | <tr> | |
216 | <td valign="top"> | |
217 | <pre>big_int32_at x; | |
218 | ||
219 | ... read into x from a file ... | |
220 | ||
221 | x += 100; | |
222 | ||
223 | ... write x to a file ... | |
224 | </pre> | |
225 | </td> | |
226 | <td> | |
227 | <pre> | |
228 | int32_t x; | |
229 | ||
230 | ... read into x from a file ... | |
231 | ||
232 | big_to_native_inplace(x); | |
233 | x += 100; | |
234 | native_to_big_inplace(x); | |
235 | ||
236 | ... write x to a file ... | |
237 | </pre> | |
238 | </td> | |
239 | </tr> | |
240 | </table> | |
241 | ||
242 | </center> | |
243 | </div> | |
244 | ||
245 | <p><b>There will be no performance difference between the two approaches in | |
246 | optimized builds, | |
247 | regardless of the native endianness of the machine.</b> That's because optimizing compilers will generate exactly the same code for each. That conclusion was confirmed by | |
248 | studying the generated assembly code for GCC and Visual C++. Furthermore, time | |
249 | spent doing I/O will determine the speed of this application.</p> | |
250 | ||
251 | <p>Now consider a slightly different problem: </p> | |
252 | ||
253 | <div align="center"> | |
254 | <center> | |
255 | ||
256 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> | |
257 | <tr> | |
258 | <td colspan="2"> | |
259 | <p align="center"><b><i><a name="Example-2">Example 2</a></i></b></td> | |
260 | </tr> | |
261 | <tr> | |
262 | <td colspan="2"><i><b>Add a million values to a big endian value in a file, then write the | |
263 | result to a file </b></i> </td> | |
264 | </tr> | |
265 | <tr> | |
266 | <td><i><b>Endian arithmetic type approach</b></i></td> | |
267 | <td><i><b>Endian conversion function approach</b></i></td> | |
268 | </tr> | |
269 | <tr> | |
270 | <td valign="top"> | |
271 | <pre>big_int32_at x; | |
272 | ||
273 | ... read into x from a file ... | |
274 | ||
275 | for (int32_t i = 0; i < 1000000; ++i) | |
276 | x += i; | |
277 | ||
278 | ... write x to a file ... | |
279 | </pre> | |
280 | </td> | |
281 | <td> | |
282 | <pre>int32_t x; | |
283 | ||
284 | ... read into x from a file ... | |
285 | ||
286 | big_to_native_inplace(x); | |
287 | ||
288 | for (int32_t i = 0; i < 1000000; ++i) | |
289 | x += i; | |
290 | ||
291 | native_to_big_inplace(x); | |
292 | ||
293 | ... write x to a file ... | |
294 | </pre> | |
295 | </td> | |
296 | </tr> | |
297 | </table> | |
298 | ||
299 | </center> | |
300 | </div> | |
301 | ||
302 | <p>With the Endian arithmetic approach, on little endian platforms an implicit conversion from and then back to | |
303 | big endian is done inside the loop. With the Endian conversion function | |
304 | approach, the user has ensured the conversions are done outside the loop, so the | |
305 | code may run more quickly on little endian platforms.</p> | |
306 | ||
307 | <h3><a name="Timings">Timings</a></h3> | |
308 | <p>These tests were run against release builds on a circa 2012 4-core little endian X64 Intel Core i5-3570K | |
309 | CPU @ 3.40GHz under Windows 7.</p> | |
310 | ||
311 | <p><b>Caveat emptor: The Windows CPU timer has very high granularity. Repeated | |
312 | runs of the same tests often yield considerably different results.</b></p> | |
313 | ||
314 | <p>See <b>test/loop_time_test.cpp</b> for the actual code and <b>benchmark/Jamfile.v2</b> for the build | |
315 | setup.</p> | |
316 | ||
317 | ||
318 | <div align="center"> | |
319 | <center> | |
320 | <table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111"> | |
321 | <tr><td colspan="6" align="center"><b>GNU C++ version 4.8.2 on Linux virtual | |
322 | machine</b></td></tr> | |
323 | <tr><td colspan="6" align="center"><b> Iterations: 10'000'000'000, Intrinsics: __builtin_bswap16, etc.</b></td></tr> | |
324 | <tr><td><b>Test Case</b></td> | |
325 | <td align="center"><b>Endian<br>arithmetic<br>type</b></td> | |
326 | <td align="center"><b>Endian<br>conversion<br>function</b></td> | |
327 | </tr> | |
328 | <tr><td>16-bit aligned big endian</td><td align="right">8.46 s</td><td align="right">5.28 s</td></tr> | |
329 | <tr><td>16-bit aligned little endian</td><td align="right">5.28 s</td><td align="right">5.22 s</td></tr> | |
330 | <tr><td>32-bit aligned big endian</td><td align="right">8.40 s</td><td align="right">2.11 s</td></tr> | |
331 | <tr><td>32-bit aligned little endian</td><td align="right">2.11 s</td><td align="right">2.10 s</td></tr> | |
332 | <tr><td>64-bit aligned big endian</td><td align="right">14.02 s</td><td align="right">3.10 s</td></tr> | |
333 | <tr><td>64-bit aligned little endian</td><td align="right">3.00 s</td><td align="right">3.03 s</td></tr> | |
334 | ||
335 | </table> | |
336 | </center> | |
337 | </div> | |
338 | <p></p> | |
339 | ||
340 | <div align="center"> <center> | |
341 | <table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111"> | |
342 | <tr><td colspan="6" align="center"><b>Microsoft Visual C++ version 14.0</b></td></tr> | |
343 | <tr><td colspan="6" align="center"><b> Iterations: 10'000'000'000, Intrinsics: cstdlib _byteswap_ushort, etc.</b></td></tr> | |
344 | <tr><td><b>Test Case</b></td> | |
345 | <td align="center"><b>Endian<br>arithmetic<br>type</b></td> | |
346 | <td align="center"><b>Endian<br>conversion<br>function</b></td> | |
347 | </tr> | |
348 | <tr><td>16-bit aligned big endian</td><td align="right">8.27 s</td><td align="right">5.26 s</td></tr> | |
349 | <tr><td>16-bit aligned little endian</td><td align="right">5.29 s</td><td align="right">5.32 s</td></tr> | |
350 | <tr><td>32-bit aligned big endian</td><td align="right">8.36 s</td><td align="right">5.24 s</td></tr> | |
351 | <tr><td>32-bit aligned little endian</td><td align="right">5.24 s</td><td align="right">5.24 s</td></tr> | |
352 | <tr><td>64-bit aligned big endian</td><td align="right">13.65 s</td><td align="right">3.34 s</td></tr> | |
353 | <tr><td>64-bit aligned little endian</td><td align="right">3.35 s</td><td align="right">2.73 s</td></tr> | |
354 | </table> | |
355 | </center></div> | |
356 | ||
357 | ||
358 | <h2>Overall <a name="FAQ">FAQ</a></h2> | |
359 | ||
360 | <p><b>Is the implementation header only?</b></p> | |
361 | ||
362 | <blockquote> | |
363 | ||
364 | <p>Yes.</p> | |
365 | ||
366 | </blockquote> | |
367 | ||
368 | <p><b>Are C++03 compilers supported?</b></p> | |
369 | ||
370 | <blockquote> | |
371 | ||
372 | <p>Yes.</p> | |
373 | ||
374 | </blockquote> | |
375 | ||
376 | <p><b>Does the implementation use compiler intrinsic built-in byte swapping?</b></p> | |
377 | ||
378 | <blockquote> | |
379 | ||
380 | <p>Yes, if available. See <a href="#Intrinsic">Intrinsic built-in support</a>.</p> | |
381 | ||
382 | </blockquote> | |
383 | ||
384 | <p><b>Why bother with endianness?</b></p> | |
385 | <blockquote> | |
386 | <p>Binary data portability is the primary use case.</p> | |
387 | </blockquote> | |
388 | <p><b>Does endianness have any uses outside of portable binary file or network | |
389 | I/O formats?</b> </p> | |
390 | <blockquote> | |
391 | <p>Using the unaligned integer types with a size tailored to the application's | |
392 | needs is a minor secondary use that saves internal or external memory space. For | |
393 | example, using <code>big_int40_buf_t</code> or <code>big_int40_t</code> in a | |
394 | large array saves a lot of space compared to one of the 64-bit types.</p> | |
395 | </blockquote> | |
396 | <p><b>Why bother with binary I/O? Why not just use C++ Standard Library stream | |
397 | inserters and extractors?</b></p> | |
398 | <blockquote> | |
399 | <p>Data interchange formats often specify binary integer data.</p> | |
400 | <p>Binary integer data is smaller and therefore I/O is faster and file sizes | |
401 | are smaller. Transfer between systems is less expensive.</p> | |
402 | <p >Furthermore, binary integer data is of fixed size, and so fixed-size disk | |
403 | records are possible without padding, easing sorting and allowing random access.</p> | |
404 | <p >Disadvantages, such as the inability to use text utilities on the | |
405 | resulting files, limit usefulness to applications where the binary I/O | |
406 | advantages are paramount.</p> | |
407 | </blockquote> | |
408 | ||
409 | <p><b>Which is better, big-endian or little-endian?</b></p> | |
410 | <blockquote> | |
411 | <p>Big-endian tends to be preferred in a networking environment and is a bit | |
412 | more of an industry standard, but little-endian may be preferred for | |
413 | applications that run primarily on x86, x86-64, and other little-endian | |
414 | CPU's. The <a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> article | |
415 | gives more pros and cons.</p> | |
416 | </blockquote> | |
417 | ||
418 | <p><b>Why are only big and little native endianness supported?</b></p> | |
419 | <blockquote> | |
420 | <p>These are the only endian schemes that have any practical value today. PDP-11 | |
421 | and the other middle endian approaches are interesting curiosities | |
422 | but have no relevance for today's C++ developers. The same is true for | |
423 | architectures that allow runtime endianness switching. The | |
424 | <a href="conversion.html#native-order-specification">specification for native | |
425 | ordering</a> has been carefully crafted to allow support for such orderings in | |
426 | the future, should the need arise. Thanks to Howard Hinnant for suggesting this. </p> | |
427 | </blockquote> | |
428 | ||
429 | <p><b>Why do both the buffer and arithmetic types exist?</b></p> | |
430 | <blockquote> | |
431 | <p>Conversions in the buffer types are explicit. Conversions in the arithmetic | |
432 | types are implicit. This fundamental difference is a deliberate design feature | |
433 | that would be lost if the inheritance hierarchy were collapsed.</p> | |
434 | <p>The original design provided only arithmetic types. Buffer types were | |
435 | requested during formal review by those wishing total control over when | |
436 | conversion occurs. They also felt that buffer types would be less likely to be | |
437 | misused by maintenance programmers not familiar with the implications of | |
438 | performing a lot of integer operations on the endian arithmetic integer types.</p> | |
439 | </blockquote> | |
440 | <p><b>What is gained by using the buffer types rather than always just using the | |
441 | arithmetic types?</b></p> | |
442 | <blockquote> | |
443 | <p>Assurance that hidden conversions are not performed. This is of overriding | |
444 | importance to users concerned about achieving the ultimate in terms of speed. </p> | |
445 | <p>"Always just using the arithmetic types" is fine for other users. When the | |
446 | ultimate in speed needs to be ensured, the arithmetic types can be used in the | |
447 | same design patterns or idioms that would be used for buffer types, resulting in | |
448 | the same code being generated for either types.</p> | |
449 | </blockquote> | |
450 | ||
451 | <p><b>What are the limitations of integer support?</b></p> | |
452 | ||
453 | <blockquote> | |
454 | ||
455 | <p>Tests have only been | |
456 | performed on machines that use two's complement arithmetic. The Endian | |
457 | conversion functions only support 16, 32, and 64-bit aligned integers. The | |
458 | endian types only support 8, 16, 24, 32, 40, 48, 56, and 64-bit unaligned integers, | |
459 | and 8, 16, 32, and 64-bit aligned integers.</p> | |
460 | ||
461 | </blockquote> | |
462 | ||
463 | <p><b>Why is there no floating point support?</b></p> | |
464 | ||
465 | <blockquote> | |
466 | ||
467 | <p>An attempt was made to support four-byte <code>float</code>s and eight-byte | |
468 | <code>double</code>s, limited to | |
469 | <a href="http://en.wikipedia.org/wiki/IEEE_floating_point">IEEE 754</a> (also | |
470 | know as ISO/IEC/IEEE 60559) floating point and further limited to systems where | |
471 | floating point endianness does not differ from integer | |
472 | endianness.</p> | |
473 | ||
474 | <p>Even with those limitations, support for floating point types was not | |
475 | reliable and was removed. For example, simply reversing the endianness of a | |
476 | floating point number can result in a signaling-NAN. For all practical purposes, | |
477 | binary serialization and endianness for integers are one and the same problem. | |
478 | That is not true for floating point numbers, so binary serialization interfaces | |
479 | and formats for floating point does not fit well in an endian-based library.</p> | |
480 | ||
481 | </blockquote> | |
482 | ||
483 | <h2><a name="Release-history">Release history</a></h2> | |
484 | <h3><a name="Changes-requested-by-formal-review">Changes requested by formal review</a></h3> | |
485 | <p>The library was reworked from top to bottom to accommodate changes requested | |
486 | during the formal review. See <a href="mini_review_topics.html">Mini-Review</a> | |
487 | page for details.</p> | |
488 | <h3><a name="Other-changes-since-formal-review">Other changes since formal | |
489 | review</a></h3> | |
490 | <ul> | |
491 | <li>Header <code>boost/endian/endian.hpp</code> has been renamed to <code> | |
492 | boost/endian/arithmetic.hpp</code>. Headers | |
493 | <code>boost/endian/conversion.hpp</code> and <code>boost/endian/buffers.hpp</code> have been | |
494 | added. | |
495 | Infrastructure file names were changed accordingly.</li> | |
496 | <li>The endian arithmetic type aliases have been renamed, | |
497 | using a naming pattern that is consistent for both integer and floating point, | |
498 | and a consistent set of aliases supplied for the endian buffer types.</li> | |
499 | <li>The unaligned-type alias names still have the <code>_t</code> suffix, but | |
500 | the aligned-type alias names now have an <code>_at</code> suffix..</li> | |
501 | <li><code>endian_reverse()</code> overloads for <code>int8_t</code> and <code> | |
502 | uint8_t</code> have been added for improved generality. (Pierre Talbot)</li> | |
503 | <li>Overloads of <code>endian_reverse_inplace()</code> have been replaced with a single <code> | |
504 | endian_reverse_inplace()</code> template. (Pierre Talbot)</li> | |
505 | <li>For X86 and X64 architectures, which permit unaligned loads and stores, | |
506 | unaligned little endian buffer and arithmetic types use regular loads and | |
507 | stores when the size is exact. This makes unaligned little endian buffer and | |
508 | arithmetic types significantly more efficient on these architectures. (Jeremy | |
509 | Maitin-Shepard)</li> | |
510 | <li>C++11 features affecting interfaces, such as <code>noexcept</code>, are now used. | |
511 | C++03 compilers are still | |
512 | supported.</li> | |
513 | <li>Acknowledgements have been updated.</li> | |
514 | </ul> | |
515 | ||
516 | <h2><a name="Compatibility">Compatibility</a> with interim releases</h2> | |
517 | ||
518 | <p>Prior to the official Boost release, class template <code> | |
519 | endian_arithmetic</code> has been used for a decade or more with the same | |
520 | functionality but under the name <code>endian</code>. Other names also changed | |
521 | in the official release. If the macro <code>BOOST_ENDIAN_DEPRECATED_NAMES</code> | |
522 | is defined, those old now deprecated names are still supported. However, the | |
523 | class template <code>endian</code> name is only provided for compilers | |
524 | supporting C++11 template aliases. For C++03 compilers, the name will have to be | |
525 | changed to <code>endian_arithmetic</code>.</p> | |
526 | ||
527 | <p>To support backward header compatibility, deprecated header <code>boost/endian/endian.hpp</code> | |
528 | forwards to <code>boost/endian/arithmetic.hpp</code>. It requires <code> | |
529 | BOOST_ENDIAN_DEPRECATED_NAMES</code> be defined. It should only be used while | |
530 | transitioning to the official Boost release of the library as it will be removed | |
531 | in some future release.</p> | |
532 | ||
533 | <h2><a name="C++03-support">C++03 support</a> for C++11 features</h2> | |
534 | ||
535 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> | |
536 | <tr> | |
537 | <td><b>C++11 Feature</b></td> | |
538 | <td><b>Action with C++03 Compilers </b></td> | |
539 | </tr> | |
540 | <tr> | |
541 | <td>Scoped enums </td> | |
542 | <td>Uses header <code class="computeroutput"> | |
543 | <a href="http://www.boost.org/libs/core/doc/html/core/scoped_enum.html"> | |
544 | <span class="identifier">boost</span><span class="special">/</span><span class="identifier">core</span><span class="special">/</span><span class="identifier">scoped_enum</span><span class="special">.</span><span class="identifier">hpp</span></a></code><span class="identifier"> | |
545 | to emulate C++11 scoped enums.</span></td> | |
546 | </tr> | |
547 | <tr> | |
548 | <td><code>noexcept</code></td> | |
549 | <td><span class="identifier">Uses BOOST_NOEXCEPT macro, which is defined as | |
550 | null for compilers not supporting this C++11 feature.</span></td> | |
551 | </tr> | |
552 | <tr> | |
553 | <td>C++11 PODs (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm">N2342</a>)</td> | |
554 | <td><span class="identifier">Takes advantage of C++03 compilers that | |
555 | relax C++03 POD rules, but see Limitations | |
556 | <a href="buffers.html#Limitations">here</a> and | |
557 | <a href="arithmetic.html#Limitations">here</a>. Also see macros for explicit | |
558 | POD control <a href="buffers.html#Compilation">here</a> and | |
559 | <a href="arithmetic.html#Compilation">here</a>.</span></td> | |
560 | </tr> | |
561 | </table> | |
562 | ||
563 | <h2><a name="Future-directions">Future directions</a></h2> | |
564 | ||
565 | <p><b>Standardization.</b> The plan is to submit Boost.Endian to the C++ | |
566 | standards committee for possible inclusion in a Technical Specification or the | |
567 | C++ standard itself.</p> | |
568 | ||
569 | <p><b>Specializations for <code>numeric_limits</code>.</b> Roger Leigh | |
570 | requested that all <code>boost::endian</code> types provide <code>numeric_limits</code> | |
571 | specializations. See <a href="https://github.com/boostorg/endian/issues/4"> | |
572 | GitHub issue 4</a>.</p> | |
573 | ||
574 | <p><b>Character buffer support.</b> Peter Dimov pointed out during the | |
575 | mini-review that getting and setting basic arithmetic types (or <code><cstdint></code> | |
576 | equivalents) from/to an offset into an array of unsigned char is a common need. | |
577 | See <a href="http://lists.boost.org/Archives/boost/2015/01/219574.php"> | |
578 | Boost.Endian mini-review posting</a>.</p> | |
579 | ||
580 | <p><b>Out-of-range detection.</b> Peter Dimov pointed suggested during the | |
581 | mini-review that throwing an exception on buffer values being out-of-range might | |
582 | be desirable. See the end of | |
583 | <a href="http://lists.boost.org/Archives/boost/2015/01/219659.php">this posting</a> | |
584 | and subsequent replies.</p> | |
585 | ||
586 | <h2><a name="Acknowledgements">Acknowledgements</a></h2> | |
587 | <p>Comments and suggestions were received from Adder, Benaka Moorthi, | |
588 | Christopher Kohlhoff, Cliff Green, Daniel James, Dave Handley, Gennaro Proto, Giovanni Piero | |
589 | Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Howard Hinnant, Jason Newton, Jeff Flinn, Jeremy Maitin-Shepard, John Filo, John | |
590 | Maddock, Kim Barrett, Marsh Ray, Martin Bonner, Mathias Gaunard, Matias | |
591 | Capeletto, Neil Mayhew, Nevin Liber, | |
592 | Olaf van der Spek, Paul Bristow, Peter Dimov, Pierre Talbot, Phil Endecott, | |
593 | Philip Bennefall, Pyry Jahkola, | |
594 | Rene Rivera, Robert Stewart, Roger Leigh, Roland Schwarz, Scott McMurray, Sebastian Redl, Tim | |
595 | Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and | |
596 | Vitaly Budovsk. Apologies if anyone has been missed.</p> | |
597 | <hr> | |
598 | <p>Last revised: | |
599 | <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 April, 2016<!--webbot bot="Timestamp" endspan i-checksum="29990" --></p> | |
600 | <p>© Copyright Beman Dawes, 2011, 2013</p> | |
601 | <p>Distributed under the Boost Software License, Version 1.0. See | |
602 | <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> | |
603 | ||
604 | </body> | |
605 | ||
606 | </html> |