]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <html> |
2 | ||
3 | <head> | |
4 | <meta http-equiv="Content-Language" content="en-us"> | |
5 | <meta name="GENERATOR" content="Microsoft FrontPage 5.0"> | |
6 | <meta name="ProgId" content="FrontPage.Editor.Document"> | |
7 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
8 | <title>Endian Arithmetic Types</title> | |
9 | <link href="styles.css" rel="stylesheet"> | |
10 | </style> | |
11 | </head> | |
12 | ||
13 | <body> | |
14 | ||
15 | ||
16 | <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> | |
17 | <tr> | |
18 | <td> | |
19 | <a href="../../../index.html"> | |
20 | <img src="../../../boost.png" alt="Boost logo" align="middle" border="0" width="277" height="86"></a></td> | |
21 | <td align="middle"> | |
22 | <b> | |
23 | <font size="6">Endian Arithmetic Types</font> </b> | |
24 | </td> | |
25 | </tr> | |
26 | </table> | |
27 | ||
28 | <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> | |
29 | <tr> | |
30 | <td><b> | |
31 | <a href="index.html">Endian Home</a> | |
32 | <a href="conversion.html">Conversion Functions</a> | |
33 | <a href="arithmetic.html">Arithmetic Types</a> | |
34 | <a href="buffers.html">Buffer Types</a> | |
35 | <a href="choosing_approach.html">Choosing Approach</a></b></td> | |
36 | </tr> | |
37 | </table> | |
38 | ||
39 | <p></p> | |
40 | ||
41 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> | |
42 | <tr> | |
43 | <td width="100%" bgcolor="#D7EEFF" align="center"> | |
44 | <i><b>Contents</b></i></td> | |
45 | </tr> | |
46 | <tr> | |
47 | <td width="100%" bgcolor="#E8F5FF"> | |
48 | <a href="#Introduction">Introduction</a><br> | |
49 | <a href="#Example">Example</a><br> | |
50 | <a href="#Limitations">Limitations</a><br> | |
51 | <a href="#Feature-set">Feature set</a><br> | |
52 | <a href="#Types">Enums and typedefs</a><br> | |
53 | <a href="#Class_template_endian">Class template <code>endian</code></a><br> | |
54 | | |
55 | <a href="#Synopsis">Synopsis</a><br> | |
56 | <a href="#Members">Members</a><br> | |
57 | <a href="#Stream-inserter">Stream inserter</a><br> | |
58 | <a href="#Stream-extractor">Stream extractor</a><br> | |
59 | <a href="#FAQ">FAQ</a><br> | |
60 | <a href="#Design">Design</a><br> | |
61 | <a href="#Experience">Experience</a><br> | |
62 | <a href="#Motivating-use-cases">Motivating use cases</a><br> | |
63 | <a href="#C++0x">C++11</a><br> | |
64 | <a href="#Compilation">Compilation</a><br> | |
65 | <a href="#Acknowledgements">Acknowledgements</a> | |
66 | </td> | |
67 | </tr> | |
68 | </table> | |
69 | <h2><a name="Introduction">Introduction</a></h2> | |
70 | <p>Header <a href="arithmetic.html">boost/endian/arithmetic.hpp</a> | |
71 | provides integer binary types with control over | |
72 | byte order, value type, size, and alignment. Typedefs provide easy-to-use names | |
73 | for common configurations.</p> | |
74 | <p>These types provide portable byte-holders for integer data, independent of | |
75 | particular computer architectures. Use cases almost always involve I/O, either via files or | |
76 | network connections. Although data portability is the primary motivation, these | |
77 | integer byte-holders may | |
78 | also be used to reduce memory use, file size, or network activity since they | |
79 | provide binary integer sizes not otherwise available.</p> | |
80 | <p>Such integer byte-holder types are traditionally called <b><i> | |
81 | endian</i></b> types. See the | |
82 | <a href="http://en.wikipedia.org/wiki/Endian" name="endianness">Wikipedia</a> for | |
83 | a full | |
84 | exploration of <b><i>endianness</i></b>, including definitions of <i><b>big | |
85 | endian</b></i> and <i><b>little endian</b></i>.</p> | |
86 | <p>Boost endian integers provide the same full set of C++ assignment, | |
87 | arithmetic, and relational operators as C++ standard integral types, with | |
88 | the standard semantics.</p> | |
89 | <p>Unary arithmetic operators are <b> <code><font face="Courier New">+</font></code></b>, | |
90 | <b> <code>-</code></b>, <b> <code>~</code></b>, <b> | |
91 | <code>!</code></b>, plus both prefix and postfix <b> <code>--</code></b> and <b> <code>++</code></b>. Binary | |
92 | arithmetic operators are <b> <code>+</code></b>, <b> <code>+=</code></b>, <b> <code>-</code></b>, | |
93 | <b> <code> | |
94 | -=</code></b>, <b> <code>*</code></b>, <b> <code>*=</code></b>, <b> <code>/</code></b>, | |
95 | <b> <code>/=</code></b>, <b> <code>&</code></b>, <b> <code>&=</code></b>, | |
96 | <b> <code>|</code></b>, <b> <code>|=</code></b>, <b> | |
97 | <code>^</code></b>, <b> <code>^=</code></b>, <b> <code><<</code></b>, <b> <code><<=</code></b>, <code> | |
98 | <b>>></b></code>, and <b> | |
99 | <code>>>=</code></b>. Binary relational operators are <b> <code>==</code></b>, | |
100 | <b> <code>!=</code></b>, <b> | |
101 | <code><</code></b>, <b> <code><=</code></b>, <b> <code>></code></b>, | |
102 | and <b> <code>>=</code></b>.</p> | |
103 | <p>Implicit conversion to the underlying value type is provided. An implicit | |
104 | constructor converting from the underlying value type is provided. </p> | |
105 | <h2><a name="Example">Example</a></h2> | |
106 | <p>The <a href="../example/endian_example.cpp">endian_example.cpp</a> program writes a | |
107 | binary file containing four-byte, big-endian and little-endian integers:</p> | |
108 | <blockquote> | |
109 | <pre>#include <iostream> | |
110 | #include <cstdio> | |
111 | #include <boost/endian/arithmetic.hpp> | |
112 | #include <boost/static_assert.hpp> | |
113 | ||
114 | using namespace boost::endian; | |
115 | ||
116 | namespace | |
117 | { | |
118 | // This is an extract from a very widely used GIS file format. | |
119 | // Why the designer decided to mix big and little endians in | |
120 | // the same file is not known. But this is a real-world format | |
121 | // and users wishing to write low level code manipulating these | |
122 | // files have to deal with the mixed endianness. | |
123 | ||
124 | struct header | |
125 | { | |
126 | big_int32_t file_code; | |
127 | big_int32_t file_length; | |
128 | little_int32_t version; | |
129 | little_int32_t shape_type; | |
130 | }; | |
131 | ||
132 | const char* filename = "test.dat"; | |
133 | } | |
134 | ||
135 | int main(int, char* []) | |
136 | { | |
137 | header h; | |
138 | ||
139 | BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check | |
140 | ||
141 | h.file_code = 0x01020304; | |
142 | h.file_length = sizeof(header); | |
143 | h.version = 1; | |
144 | h.shape_type = 0x01020304; | |
145 | ||
146 | // Low-level I/O such as POSIX read/write or <cstdio> | |
147 | // fread/fwrite is sometimes used for binary file operations | |
148 | // when ultimate efficiency is important. Such I/O is often | |
149 | // performed in some C++ wrapper class, but to drive home the | |
150 | // point that endian integers are often used in fairly | |
151 | // low-level code that does bulk I/O operations, <cstdio> | |
152 | // fopen/fwrite is used for I/O in this example. | |
153 | ||
154 | std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY | |
155 | ||
156 | if (!fi) | |
157 | { | |
158 | std::cout << "could not open " << filename << '\n'; | |
159 | return 1; | |
160 | } | |
161 | ||
162 | if (std::fwrite(&h, sizeof(header), 1, fi)!= 1) | |
163 | { | |
164 | std::cout << "write failure for " << filename << '\n'; | |
165 | return 1; | |
166 | } | |
167 | ||
168 | std::fclose(fi); | |
169 | ||
170 | std::cout << "created file " << filename << '\n'; | |
171 | ||
172 | return 0; | |
173 | } | |
174 | </pre> | |
175 | </blockquote> | |
176 | <p>After compiling and executing <a href="../example/endian_example.cpp">endian_example.cpp</a>, | |
177 | a hex dump of <code>test.dat</code> shows:</p> | |
178 | <blockquote> | |
179 | <pre>01020304 00000010 01000000 04030201</pre> | |
180 | </blockquote> | |
181 | <p>Notice that the first two 32-bit integers are big endian while the second two | |
182 | are little endian, even though the machine this was compiled and run on was | |
183 | little endian.</p> | |
184 | <h2><a name="Limitations">Limitations</a></h2> | |
185 | <p>Requires <code><climits></code> <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code> | |
186 | is some other value, compilation will result in an <code>#error</code>. This | |
187 | restriction is in place because the design, implementation, testing, and | |
188 | documentation has only considered issues related to 8-bit bytes, and there have | |
189 | been no real-world use cases presented for other sizes.</p> | |
190 | <p>In C++03, <code>endian_arithmetic</code> does not meet the requirements for POD types | |
191 | because it has constructors, private data members, and a base class. This means | |
192 | that common use cases are relying on unspecified behavior in that the C++ | |
193 | Standard does not guarantee memory layout for non-POD types. This has not been a | |
194 | problem in practice since all known C++ compilers lay out memory as if <code> | |
195 | endian</code> were a POD type. In C++11, it is possible to specify the | |
196 | default constructor as trivial, and private data members and base classes no longer disqualify a type from being a POD | |
197 | type. Thus under C++11, <code>endian_arithmetic</code> | |
198 | will no longer be relying on unspecified behavior.</p> | |
199 | <h2><a name="Feature-set">Feature set</a></h2> | |
200 | <ul> | |
201 | <li>Big endian| little endian | native endian byte ordering.</li> | |
202 | <li>Signed | unsigned</li> | |
203 | <li>Unaligned | aligned</li> | |
204 | <li>1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)</li> | |
205 | <li>Choice of value type</li> | |
206 | </ul> | |
207 | <h2>Enums and t<a name="Types">ypedefs</a></h2> | |
208 | <p>Two scoped enums are provided:</p> | |
209 | <blockquote> | |
210 | <pre>enum class order {big, little, native}; | |
211 | ||
212 | enum class align {no, yes}; </pre> | |
213 | </blockquote> | |
214 | <p>One class template is provided:</p> | |
215 | <blockquote> | |
216 | <pre>template <order Order, typename T, std::size_t n_bits, | |
217 | align Align = align::no> | |
218 | class endian_arithmetic; | |
219 | </pre> | |
220 | </blockquote> | |
221 | <p>Typedefs, such as <code>big_int32_t</code>, provide convenient naming | |
222 | conventions for common use cases:</p> | |
223 | <blockquote> | |
224 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="49%"> | |
225 | <tr> | |
226 | <td width="18%" align="center"><b><i>Name</i></b></td> | |
227 | <td width="49%" align="center"><b><i>Alignment</i></b></td> | |
228 | <td width="10%" align="center"><b><i>Endianness</i></b></td> | |
229 | <td width="10%" align="center"><b><i>Sign</i></b></td> | |
230 | <td width="15%" align="center"><b><i>Sizes in bits (n)</i></b></td> | |
231 | </tr> | |
232 | <tr> | |
233 | <td width="18%"><code>big_int</code><b><i>n</i></b><code>_t</code></td> | |
234 | <td width="49%" align="center"><code>no</code></td> | |
235 | <td width="10%" align="center"><code>big</code></td> | |
236 | <td width="10%" align="center">signed</td> | |
237 | <td width="15%">8,16,24,32,40,48,56,64</td> | |
238 | </tr> | |
239 | <tr> | |
240 | <td width="18%"><code>big_uint</code><i><b>n</b></i><code>_t</code></td> | |
241 | <td width="49%" align="center"><code>no</code></td> | |
242 | <td width="10%" align="center"><code>big</code></td> | |
243 | <td width="10%" align="center">unsigned</td> | |
244 | <td width="15%">8,16,24,32,40,48,56,64</td> | |
245 | </tr> | |
246 | <tr> | |
247 | <td width="18%"><code>little_int</code><i><b>n</b></i><code>_t</code></td> | |
248 | <td width="49%" align="center"><code>no</code></td> | |
249 | <td width="10%" align="center"><code>little</code></td> | |
250 | <td width="10%" align="center">signed</td> | |
251 | <td width="15%">8,16,24,32,40,48,56,64</td> | |
252 | </tr> | |
253 | <tr> | |
254 | <td width="18%"><code>little_uint</code><i><b>n</b></i><code>_t</code></td> | |
255 | <td width="49%" align="center"><code>no</code></td> | |
256 | <td width="10%" align="center"><code>little</code></td> | |
257 | <td width="10%" align="center">unsigned</td> | |
258 | <td width="15%">8,16,24,32,40,48,56,64</td> | |
259 | </tr> | |
260 | <tr> | |
261 | <td width="18%"><code>native_int</code><i><b>n</b></i><code>_t</code></td> | |
262 | <td width="49%" align="center"><code>no</code></td> | |
263 | <td width="10%" align="center"><code>native</code></td> | |
264 | <td width="10%" align="center">signed</td> | |
265 | <td width="15%">8,16,24,32,40,48,56,64</td> | |
266 | </tr> | |
267 | <tr> | |
268 | <td width="18%"><code>native_uint</code><i><b>n</b></i><code>_t</code></td> | |
269 | <td width="49%" align="center"><code>no</code></td> | |
270 | <td width="10%" align="center"><code>native</code></td> | |
271 | <td width="10%" align="center">unsigned</td> | |
272 | <td width="15%">8,16,24,32,40,48,56,64</td> | |
273 | </tr> | |
274 | <tr> | |
275 | <td width="18%"><code>big_int</code><i><b>n</b></i><code>_at</code></td> | |
276 | <td width="49%" align="center"><code>yes</code></td> | |
277 | <td width="10%" align="center"><code>big</code></td> | |
278 | <td width="10%" align="center">signed</td> | |
279 | <td width="15%">8,16,32,64</td> | |
280 | </tr> | |
281 | <tr> | |
282 | <td width="18%"><code>big_uint</code><i><b>n</b></i><code>_at</code></td> | |
283 | <td width="49%" align="center"><code>yes</code></td> | |
284 | <td width="10%" align="center"><code>big</code></td> | |
285 | <td width="10%" align="center">unsigned</td> | |
286 | <td width="15%">8,16,32,64</td> | |
287 | </tr> | |
288 | <tr> | |
289 | <td width="18%" dir="ltr"><code>little_int</code><i><b>n</b></i><code>_at</code></td> | |
290 | <td width="49%" align="center" dir="ltr"><code>yes</code></td> | |
291 | <td width="10%" align="center" dir="ltr"><code>little</code></td> | |
292 | <td width="10%" align="center" dir="ltr">signed</td> | |
293 | <td width="15%" dir="ltr">8,16,32,64</td> | |
294 | </tr> | |
295 | <tr> | |
296 | <td width="18%" dir="ltr"><code>little_uint</code><i><b>n</b></i><code>_at</code></td> | |
297 | <td width="49%" align="center" dir="ltr"><code>yes</code></td> | |
298 | <td width="10%" align="center" dir="ltr"><code>little</code></td> | |
299 | <td width="10%" align="center" dir="ltr">unsigned</td> | |
300 | <td width="15%" dir="ltr">8,16,32,64</td> | |
301 | </tr> | |
302 | </table> | |
303 | </blockquote> | |
304 | <p>The unaligned types do not cause compilers to insert padding bytes in classes | |
305 | and structs. This is an important characteristic that can be exploited to minimize wasted space in | |
306 | memory, files, and network transmissions. </p> | |
307 | <p><font color="#FF0000"><b><i><span style="background-color: #FFFFFF">Warning:</span></i></b></font><span style="background-color: #FFFFFF"> | |
308 | Code that uses a</span>ligned types is possibly non-portable because alignment | |
309 | requirements vary between hardware architectures and because alignment may be | |
310 | affected by compiler switches or pragmas. For example, alignment of an 64-bit | |
311 | integer may be to a 32-bit boundary on a 32-bit machine. Furthermore, aligned types | |
312 | are only available on architectures with 8, 16, 32, and 64-bit integer types.</p> | |
313 | <p><i><b>Recommendation:</b></i> Prefer unaligned arithmetic types.</p> | |
314 | <p><i><b>Recommendation:</b></i> Protect yourself against alignment ills. For | |
315 | example:</p> | |
316 | <blockquote> | |
317 | <pre>static_assert(sizeof(containing_struct) == 12, "sizeof(containing_struct) is wrong"); </pre> | |
318 | </blockquote> | |
319 | <p><b><i>Note:</i></b> <b><i>Note:</i></b> One-byte arithmetic types | |
320 | have identical layout on all platforms, so they never actually reverse endianness. They are provided to enable generic code, and | |
321 | to improve code readability and searchability.</p> | |
322 | <h2><a name="Class_template_endian">Class template <code>endian</code></a><code>_arithmetic</code></h2> | |
323 | <p>An <code>endian_integer</code> is an integer byte-holder with user-specified <a href="#endianness"> | |
324 | endianness</a>, value type, size, and <a href="#alignment">alignment</a>. The | |
325 | usual operations on arithmetic types are supplied.</p> | |
326 | <h3><a name="Synopsis">Synopsis</a></h3> | |
327 | <pre>#include <boost/endian/conversion.hpp> | |
328 | #include <boost/endian/buffers.hpp> | |
329 | ||
330 | namespace boost | |
331 | { | |
332 | namespace endian | |
333 | { | |
334 | // C++11 features emulated if not available | |
335 | ||
336 | enum class <a name="alignment">align</a> {no, yes}; | |
337 | ||
338 | template <order Order, class T, std::size_t n_bits, | |
339 | align Align = align::no> | |
340 | class endian_arithmetic | |
341 | : public endian_buffer<Order, T, n_bits, Align> | |
342 | { | |
343 | public: | |
344 | typedef T value_type; | |
345 | ||
346 | // if BOOST_ENDIAN_FORCE_PODNESS is defined && C++11 PODs are not | |
347 | // available then these two constructors will not be present | |
348 | <a href="#endian">endian_arithmetic</a>() noexcept = default; | |
349 | <a href="#explicit-endian">endian_arithmetic</a>(T v) noexcept; | |
350 | ||
351 | endian_arithmetic& <a href="#operator-eq">operator=</a>(T v) noexcept; | |
352 | <a href="#operator-T">operator value_type</a>() const noexcept; | |
353 | value_type value() const noexcept; // for exposition; see endian_buffer | |
354 | const char* <a href="#data">data</a>() const noexcept; // for exposition; see endian_buffer | |
355 | ||
356 | // arithmetic operations | |
357 | // note that additional operations are provided by the value_type | |
358 | value_type operator+(const endian& x) noexcept; | |
359 | endian& operator+=(endian& x, value_type y) noexcept; | |
360 | endian& operator-=(endian& x, value_type y) noexcept; | |
361 | endian& operator*=(endian& x, value_type y) noexcept; | |
362 | endian& operator/=(endian& x, value_type y) noexcept; | |
363 | endian& operator%=(endian& x, value_type y) noexcept; | |
364 | endian& operator&=(endian& x, value_type y) noexcept; | |
365 | endian& operator|=(endian& x, value_type y) noexcept; | |
366 | endian& operator^=(endian& x, value_type y) noexcept; | |
367 | endian& operator<<=(endian& x, value_type y) noexcept; | |
368 | endian& operator>>=(endian& x, value_type y noexcept; | |
369 | value_type operator<<(const endian& x, value_type y) noexcept; | |
370 | value_type operator>>(const endian& x, value_type y) noexcept; | |
371 | endian& operator++(endian& x) noexcept; | |
372 | endian& operator--(endian& x) noexcept; | |
373 | endian operator++(endian& x, int) noexcept; | |
374 | endian operator--(endian& x, int) noexcept; | |
375 | ||
376 | // Stream inserter | |
377 | template <class charT, class traits> | |
378 | friend std::basic_ostream<charT, traits>& | |
379 | operator<<(std::basic_ostream<charT, traits>& os, const T& x); | |
380 | ||
381 | // Stream extractor | |
382 | template <class charT, class traits> | |
383 | friend std::basic_istream<charT, traits>& | |
384 | operator>>(std::basic_istream<charT, traits>& is, T& x); | |
385 | }; | |
386 | ||
387 | // typedefs | |
388 | ||
389 | // unaligned big endian signed integer types | |
390 | typedef endian<order::big, int_least8_t, 8> big_int8_t; | |
391 | typedef endian<order::big, int_least16_t, 16> big_int16_t; | |
392 | typedef endian<order::big, int_least32_t, 24> big_int24_t; | |
393 | typedef endian<order::big, int_least32_t, 32> big_int32_t; | |
394 | typedef endian<order::big, int_least64_t, 40> big_int40_t; | |
395 | typedef endian<order::big, int_least64_t, 48> big_int48_t; | |
396 | typedef endian<order::big, int_least64_t, 56> big_int56_t; | |
397 | typedef endian<order::big, int_least64_t, 64> big_int64_t; | |
398 | ||
399 | // unaligned big endian unsigned integer types | |
400 | typedef endian<order::big, uint_least8_t, 8> big_uint8_t; | |
401 | typedef endian<order::big, uint_least16_t, 16> big_uint16_t; | |
402 | typedef endian<order::big, uint_least32_t, 24> big_uint24_t; | |
403 | typedef endian<order::big, uint_least32_t, 32> big_uint32_t; | |
404 | typedef endian<order::big, uint_least64_t, 40> big_uint40_t; | |
405 | typedef endian<order::big, uint_least64_t, 48> big_uint48_t; | |
406 | typedef endian<order::big, uint_least64_t, 56> big_uint56_t; | |
407 | typedef endian<order::big, uint_least64_t, 64> big_uint64_t; | |
408 | ||
409 | // unaligned little endian signed integer types | |
410 | typedef endian<order::little, int_least8_t, 8> little_int8_t; | |
411 | typedef endian<order::little, int_least16_t, 16> little_int16_t; | |
412 | typedef endian<order::little, int_least32_t, 24> little_int24_t; | |
413 | typedef endian<order::little, int_least32_t, 32> little_int32_t; | |
414 | typedef endian<order::little, int_least64_t, 40> little_int40_t; | |
415 | typedef endian<order::little, int_least64_t, 48> little_int48_t; | |
416 | typedef endian<order::little, int_least64_t, 56> little_int56_t; | |
417 | typedef endian<order::little, int_least64_t, 64> little_int64_t; | |
418 | ||
419 | // unaligned little endian unsigned integer types | |
420 | typedef endian<order::little, uint_least8_t, 8> little_uint8_t; | |
421 | typedef endian<order::little, uint_least16_t, 16> little_uint16_t; | |
422 | typedef endian<order::little, uint_least32_t, 24> little_uint24_t; | |
423 | typedef endian<order::little, uint_least32_t, 32> little_uint32_t; | |
424 | typedef endian<order::little, uint_least64_t, 40> little_uint40_t; | |
425 | typedef endian<order::little, uint_least64_t, 48> little_uint48_t; | |
426 | typedef endian<order::little, uint_least64_t, 56> little_uint56_t; | |
427 | typedef endian<order::little, uint_least64_t, 64> little_uint64_t; | |
428 | ||
429 | // unaligned native endian signed integer types | |
430 | typedef <b><i>implementation-defined</i></b>_int8_t native_int8_t; | |
431 | typedef <b><i>implementation-defined</i></b>_int16_t native_int16_t; | |
432 | typedef <b><i>implementation-defined</i></b>_int24_t native_int24_t; | |
433 | typedef <b><i>implementation-defined</i></b>_int32_t native_int32_t; | |
434 | typedef <b><i>implementation-defined</i></b>_int40_t native_int40_t; | |
435 | typedef <b><i>implementation-defined</i></b>_int48_t native_int48_t; | |
436 | typedef <b><i>implementation-defined</i></b>_int56_t native_int56_t; | |
437 | typedef <b><i>implementation-defined</i></b>_int64_t native_int64_t; | |
438 | ||
439 | // unaligned native endian unsigned integer types | |
440 | typedef <b><i>implementation-defined</i></b>_uint8_t native_uint8_t; | |
441 | typedef <b><i>implementation-defined</i></b>_uint16_t native_uint16_t; | |
442 | typedef <b><i>implementation-defined</i></b>_uint24_t native_uint24_t; | |
443 | typedef <b><i>implementation-defined</i></b>_uint32_t native_uint32_t; | |
444 | typedef <b><i>implementation-defined</i></b>_uint40_t native_uint40_t; | |
445 | typedef <b><i>implementation-defined</i></b>_uint48_t native_uint48_t; | |
446 | typedef <b><i>implementation-defined</i></b>_uint56_t native_uint56_t; | |
447 | typedef <b><i>implementation-defined</i></b>_uint64_t native_uint64_t; | |
448 | ||
449 | // aligned big endian signed integer types | |
450 | typedef endian<order::big, int8_t, 8, align::yes> big_int8_at; | |
451 | typedef endian<order::big, int16_t, 16, align::yes> big_int16_at; | |
452 | typedef endian<order::big, int32_t, 32, align::yes> big_int32_at; | |
453 | typedef endian<order::big, int64_t, 64, align::yes> big_int64_at; | |
454 | ||
455 | // aligned big endian unsigned integer types | |
456 | typedef endian<order::big, uint8_t, 8, align::yes> big_uint8_at; | |
457 | typedef endian<order::big, uint16_t, 16, align::yes> big_uint16_at; | |
458 | typedef endian<order::big, uint32_t, 32, align::yes> big_uint32_at; | |
459 | typedef endian<order::big, uint64_t, 64, align::yes> big_uint64_at; | |
460 | ||
461 | // aligned little endian signed integer types | |
462 | typedef endian<order::little, int8_t, 8, align::yes> little_int8_at; | |
463 | typedef endian<order::little, int16_t, 16, align::yes> little_int16_at; | |
464 | typedef endian<order::little, int32_t, 32, align::yes> little_int32_at; | |
465 | typedef endian<order::little, int64_t, 64, align::yes> little_int64_at; | |
466 | ||
467 | // aligned little endian unsigned integer types | |
468 | typedef endian<order::little, uint8_t, 8, align::yes> little_uint8_at; | |
469 | typedef endian<order::little, uint16_t, 16, align::yes> little_uint16_at; | |
470 | typedef endian<order::little, uint32_t, 32, align::yes> little_uint32_at; | |
471 | typedef endian<order::little, uint64_t, 64, align::yes> little_uint64_at; | |
472 | ||
473 | // aligned native endian typedefs are not provided because | |
474 | // <cstdint> types are superior for that use case | |
475 | ||
476 | } // namespace endian | |
477 | } // namespace boost</pre> | |
478 | <p>The <i><b><code>implementation-defined</code></b></i> text above is either | |
479 | <code>big</code> or <code>little</code> according to the endianness of the | |
480 | platform.</p> | |
481 | <h3><a name="Members">Members</a></h3> | |
482 | <div dir="ltr"> | |
483 | <pre><code><a name="endian">endian</a>() = default; // C++03: endian(){}</code></pre> | |
484 | </div> | |
485 | <blockquote> | |
486 | <p><i>Effects:</i> Constructs an uninitialized object of type <code>endian_arithmetic<E, T, n_bits, A></code>.</p> | |
487 | </blockquote> | |
488 | <pre><code><a name="explicit-endian">endian</a>(T v);</code></pre> | |
489 | <blockquote> | |
490 | <p><i>Effects:</i> Constructs an object of type <code>endian_arithmetic<E, T, n_bits, A></code>.</p> | |
491 | <p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the | |
492 | constructed object.</p> | |
493 | </blockquote> | |
494 | <pre><code>endian& <a name="operator-eq">operator=</a>(T v);</code></pre> | |
495 | <blockquote> | |
496 | <p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the | |
497 | constructed object.</p> | |
498 | <p><i>Returns:</i> <code>*this</code>.</p> | |
499 | </blockquote> | |
500 | <pre><code><a name="operator-T">operator T</a>() const;</code></pre> | |
501 | <blockquote> | |
502 | <p><i>Returns:</i> The current value stored in <code>*this</code>, converted to | |
503 | <code>value_type</code>.</p> | |
504 | </blockquote> | |
505 | <pre><code>const char* <a name="data">data</a>() const;</code></pre> | |
506 | <blockquote> | |
507 | <p><i>Returns:</i> A pointer to the first byte of the endian binary value stored | |
508 | in <code>*this</code>.</p> | |
509 | </blockquote> | |
510 | <h3>Other operators</h3> | |
511 | <p>Other operators on endian objects are forwarded to the equivalent | |
512 | operator on <code>value_type</code>.</p> | |
513 | <h3><a name="Stream-inserter">Stream inserter</a></h3> | |
514 | <pre>template <class charT, class traits> | |
515 | friend std::basic_ostream<charT, traits>& | |
516 | operator<<(std::basic_ostream<charT, traits>& os, const T& x); | |
517 | </pre> | |
518 | <blockquote> | |
519 | <p><i>Returns:</i> <code>os << +x</code>.</p> | |
520 | </blockquote> | |
521 | <h3><a name="Stream-extractor">Stream extractor</a></h3> | |
522 | <pre>template <class charT, class traits> | |
523 | friend std::basic_istream<charT, traits>& | |
524 | operator>>(std::basic_istream<charT, traits>& is, T& x); | |
525 | </pre> | |
526 | <blockquote> | |
527 | <p><i>Effects: </i>As if:</p> | |
528 | <blockquote> | |
529 | <pre>T i; | |
530 | if (is >> i) | |
531 | x = i; | |
532 | </pre> | |
533 | </blockquote> | |
534 | <p><i>Returns: </i><code>is</code><i>.</i></p> | |
535 | </blockquote> | |
536 | <h2><a name="FAQ">FAQ</a></h2> | |
537 | ||
538 | <p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide | |
539 | FAQ.</p> | |
540 | ||
541 | <p><b>Why not just use Boost.Serialization?</b> Serialization involves a | |
542 | conversion for every object involved in I/O. Endian integers require no | |
543 | conversion or copying. They are already in the desired format for binary I/O. | |
544 | Thus they can be read or written in bulk.</p> | |
545 | <p><b>Are endian types PODs?</b> Yes for C++11. No for C++03, although several | |
546 | <a href="#Compilation">macros</a> are available to force PODness in all cases.</p> | |
547 | <p><b>What are the implications of endian integer types not being PODs with C++03 | |
548 | compilers?</b> They | |
549 | can't be used in unions. Also, compilers aren't required to align or lay | |
550 | out storage in portable ways, although this potential problem hasn't prevented | |
551 | use of Boost.Endian with | |
552 | real compilers.</p> | |
553 | <p><b>What good is <i>native </i>endianness?</b> It provides alignment and | |
554 | size guarantees not available from the built-in types. It eases generic | |
555 | programming.</p> | |
556 | <p><b>Why bother with the aligned endian types?</b> Aligned integer operations | |
557 | may be faster (as much as 10 to 20 times faster) if the endianness and alignment of | |
558 | the type matches the endianness and alignment requirements of the machine. The code, | |
559 | however, will be somewhat less portable than with the unaligned types.</p> | |
560 | <p><b>Why provide the arithmetic operations?</b> Providing a full set of operations reduces program | |
561 | clutter and makes code both easier to write and to read. Consider | |
562 | incrementing a variable in a record. It is very convenient to write:</p> | |
563 | <pre wrap> ++record.foo;</pre> | |
564 | <p wrap>Rather than:</p> | |
565 | <pre wrap> int temp(record.foo); | |
566 | ++temp; | |
567 | record.foo = temp;</pre> | |
568 | <h2><a name="Design">Design</a> considerations for Boost.Endian types</h2> | |
569 | <ul> | |
570 | <li>Must be suitable for I/O - in other words, must be memcpyable.</li> | |
571 | <li>Must provide exactly the size and internal byte ordering specified.</li> | |
572 | <li>Must work correctly when the internal integer representation has more bits | |
573 | that the sum of the bits in the external byte representation. Sign extension | |
574 | must work correctly when the internal integer representation type has more | |
575 | bits than the sum of the bits in the external bytes. For example, using | |
576 | a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for | |
577 | both positive and negative values.</li> | |
578 | <li>Must work correctly (including using the same defined external | |
579 | representation) regardless of whether a compiler treats char as signed or | |
580 | unsigned.</li> | |
581 | <li>Unaligned types must not cause compilers to insert padding bytes.</li> | |
582 | <li>The implementation should supply optimizations with great care. Experience has shown that optimizations of endian | |
583 | integers often become pessimizations when changing | |
584 | machines or compilers. Pessimizations can also happen when changing compiler switches, | |
585 | compiler versions, or CPU models of the same architecture.</li> | |
586 | </ul> | |
587 | <h2><a name="Experience">Experience</a></h2> | |
588 | <p>Classes with similar functionality have been independently developed by | |
589 | several Boost programmers and used very successful in high-value, high-use | |
590 | applications for many years. These independently developed endian libraries | |
591 | often evolved from C libraries that were also widely used. Endian types have proven widely useful across a wide | |
592 | range of computer architectures and applications.</p> | |
593 | <h2><a name="Motivating-use-cases">Motivating use cases</a></h2> | |
594 | <p>Neil Mayhew writes: "I can also provide a meaningful use-case for this | |
595 | library: reading TrueType font files from disk and processing the contents. The | |
596 | data format has fixed endianness (big) and has unaligned values in various | |
597 | places. Using Boost.Endian simplifies and cleans the code wonderfully."</p> | |
598 | <h2><a name="C++0x">C++11</a></h2> | |
599 | <p>The availability of the C++11 | |
600 | <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> | |
601 | Defaulted Functions</a> feature is detected automatically, and will be used if | |
602 | present to ensure that objects of <code>class endian_arithmetic</code> are trivial, and | |
603 | thus PODs.</p> | |
604 | <h2><a name="Compilation">Compilation</a></h2> | |
605 | <p>Boost.Endian is implemented entirely within headers, with no need to link to | |
606 | any Boost object libraries.</p> | |
607 | <p>Several macros allow user control over features:</p> | |
608 | <ul> | |
609 | <li>BOOST_ENDIAN_NO_CTORS causes <code>class endian_arithmetic</code> to have no | |
610 | constructors. The intended use is for compiling user code that must be | |
611 | portable between compilers regardless of C++11 | |
612 | <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> | |
613 | Defaulted Functions</a> support. Use of constructors will always fail, <br> | |
614 | </li> | |
615 | <li>BOOST_ENDIAN_FORCE_PODNESS causes BOOST_ENDIAN_NO_CTORS to be defined if | |
616 | the compiler does not support C++11 | |
617 | <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> | |
618 | Defaulted Functions</a>. This is ensures that objects of <code>class endian_arithmetic</code> | |
619 | are PODs, and so can be used in C++03 unions. | |
620 | In C++11, <code>class endian_arithmetic</code> objects are PODs, even though they have | |
621 | constructors, so can always be used in unions.</li> | |
622 | </ul> | |
623 | <h2><a name="Acknowledgements">Acknowledgements</a></h2> | |
624 | <p>Original design developed by Darin Adler based on classes developed by Mark | |
625 | Borgerding. Four original class templates combined into a single <code>endian_arithmetic</code> | |
626 | class template by Beman Dawes, who put the library together, provided | |
627 | documentation, added the typedefs, and also added the <code>unrolled_byte_loops</code> | |
628 | sign partial specialization to correctly extend the sign when cover integer size | |
629 | differs from endian representation size.</p> | |
630 | <hr> | |
631 | <p>Last revised: | |
632 | <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->14 October, 2015<!--webbot bot="Timestamp" endspan i-checksum="38874" --></p> | |
633 | <p>© Copyright Beman Dawes, 2006-2009, 2013</p> | |
634 | <p>Distributed under the Boost Software License, Version 1.0. See | |
635 | <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> | |
636 | ||
637 | </body> | |
638 | ||
639 | </html> |