]>
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 Conversion Functions</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> | |
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"> | |
20 | <b> | |
21 | <font size="6">Endian Conversion Functions</font></b></td> | |
22 | </tr> | |
23 | </table> | |
24 | ||
25 | <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> | |
26 | <tr> | |
27 | <td><b> | |
28 | <a href="index.html">Endian Home</a> | |
29 | <a href="conversion.html">Conversion Functions</a> | |
30 | <a href="arithmetic.html">Arithmetic Types</a> | |
31 | <a href="buffers.html">Buffer Types</a> | |
32 | <a href="choosing_approach.html">Choosing Approach</a></b></td> | |
33 | </tr> | |
34 | </table> | |
35 | ||
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="#Introduction">Introduction</a><br> | |
46 | <a href="#Reference">Reference</a><br> | |
47 | <a href="#Synopsis">Synopsis</a><br> | |
48 | <a href="#Requirements">Requirements</a><br> | |
49 | <code><a href="#EndianReversible">EndianReversible</a></code><br> | |
50 | <a href="#Customization-points">Customization for | |
51 | UDTs</a><br> | |
52 | <a href="#Functions">Functions</a><br> | |
53 | <a href="#FAQ">FAQ</a><br> | |
54 | <a href="#Acknowledgements">Acknowledgements</a></td> | |
55 | </tr> | |
56 | </table> | |
57 | ||
58 | <h2><a name="Introduction">Introduction</a></h2> | |
59 | ||
60 | <p>Header <a href="../include/boost/endian/conversion.hpp">boost/endian/conversion.hpp</a> | |
61 | provides byte order reversal and conversion functions that convert objects of | |
62 | the built-in | |
63 | integer types | |
64 | between native, big, or little endian byte | |
65 | ordering. User defined types are also supported.</p> | |
66 | ||
67 | <h2><a name="Reference">Reference</a></h2> | |
68 | ||
69 | <p>Functions are implemented <code>inline</code> if appropriate.<code> </code> | |
70 | For C++03 compilers, <code> noexcept</code> is | |
71 | elided. | |
72 | Boost scoped enum emulation is used so that the library still works for compilers that do not support scoped enums.</p> | |
73 | ||
74 | <h3><a name="Definitions">Definitions</a></h3> | |
75 | <p><b><i>Endianness</i></b> refers to the ordering of bytes within internal or | |
76 | external integers and other arithmetic data. Most-significant byte first is | |
77 | called <b><i>big endian</i></b> ordering. Least-significant byte first is called | |
78 | <b><i>little endian</i></b> ordering. Other orderings are possible and some CPU | |
79 | architectures support both big and little ordering.</p> | |
80 | <blockquote> | |
81 | <p>[<i>Note:</i> The names are derived from | |
82 | <a href="http://en.wikipedia.org/wiki/Jonathan_Swift" title="Jonathan Swift"> | |
83 | Jonathan Swift</a>'s satirical novel <i> | |
84 | <a href="http://en.wikipedia.org/wiki/Gulliver's_Travels" title="Gulliver's Travels"> | |
85 | Gulliver’s Travels</a></i>, where rival kingdoms opened their soft-boiled eggs | |
86 | at different ends. Wikipedia has an extensive description of | |
87 | <a href="https://en.wikipedia.org/wiki/Endianness">Endianness</a>. <i>—end note</i>]</p> | |
88 | </blockquote> | |
89 | <p>The standard integral types (C++std 3.9.1) except <code>bool</code> | |
90 | are collectively called the <b> <i>endian types</i></b>.</p> | |
91 | ||
92 | <h3> | |
93 | Header <code><boost/endian/conversion.hpp></code> | |
94 | <a name="Synopsis">Synopsis</a></h3> | |
95 | ||
96 | <pre>#define BOOST_ENDIAN_INTRINSIC_MSG \ | |
97 | "<b><font face="Arial"><i>message describing presence or absence of intrinsics</i></font></b>" | |
98 | ||
99 | namespace boost | |
100 | { | |
101 | namespace endian | |
102 | { | |
103 | enum class <a name="order">order</a> | |
104 | { | |
105 | native = <b><i>see below, | |
106 | </i></b> big = <b><i>see below</i></b>, | |
107 | little = <b><i>see below</i></b>, | |
108 | <b><i> </i></b>}; | |
109 | ||
110 | int8_t <a href="#endian_reverse">endian_reverse</a>(int8_t x) noexcept; | |
111 | int16_t <a href="#endian_reverse">endian_reverse</a>(int16_t x) noexcept; | |
112 | int32_t <a href="#endian_reverse">endian_reverse</a>(int32_t x) noexcept; | |
113 | int64_t <a href="#endian_reverse">endian_reverse</a>(int64_t x) noexcept; | |
114 | uint8_t <a href="#endian_reverse">endian_reverse</a>(uint8_t x) noexcept; | |
115 | uint16_t <a href="#endian_reverse">endian_reverse</a>(uint16_t x) noexcept; | |
116 | uint32_t <a href="#endian_reverse">endian_reverse</a>(uint32_t x) noexcept; | |
117 | uint64_t <a href="#endian_reverse">endian_reverse</a>(uint64_t x) noexcept; | |
118 | ||
119 | template <class EndianReversible> | |
120 | EndianReversible big_to_native(EndianReversible x) noexcept; | |
121 | template <class EndianReversible> | |
122 | EndianReversible native_to_big(EndianReversible x) noexcept; | |
123 | template <class EndianReversible> | |
124 | EndianReversible little_to_native(EndianReversible x) noexcept; | |
125 | template <class EndianReversible> | |
126 | EndianReversible native_to_little(EndianReversible x) noexcept; | |
127 | template <order O1, order O2, class EndianReversible> | |
128 | EndianReversible conditional_reverse(EndianReversible x) noexcept; | |
129 | template <class EndianReversible> | |
130 | EndianReversible conditional_reverse(EndianReversible x, | |
131 | order order1, order order2) noexcept; | |
132 | ||
133 | template <class EndianReversible> | |
134 | void endian_reverse_inplace(EndianReversible& x) noexcept; | |
135 | ||
136 | template <class EndianReversibleInplace> | |
137 | void big_to_native_inplace(EndianReversibleInplace& x) noexcept; | |
138 | template <class EndianReversibleInplace> | |
139 | void native_to_big_inplace(EndianReversibleInplace& x) noexcept; | |
140 | template <class EndianReversibleInplace> | |
141 | void little_to_native_inplace(EndianReversibleInplace& x) noexcept; | |
142 | template <class EndianReversibleInplace> | |
143 | void native_to_little_inplace(EndianReversibleInplace& x) noexcept; | |
144 | template <order O1, order O2, class EndianReversibleInplace> | |
145 | void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept; | |
146 | template <class EndianReversibleInplace> | |
147 | void conditional_reverse_inplace(EndianReversibleInplace& x, | |
148 | order order1, order order2) noexcept; | |
149 | ||
150 | } // namespace endian | |
151 | } // namespace boost</pre> | |
152 | <p>The values of <code>order::little</code> and <code>order::big</code> shall | |
153 | not be equal to one another. </p> | |
154 | <p><a name="native-order-specification"></a>The value of <code>order::native</code> | |
155 | shall be:</p> | |
156 | <ul> | |
157 | <li>equal to <code>order::big</code> if the execution environment is big | |
158 | endian, otherwise</li> | |
159 | <li>equal to <code>order::little</code> if the execution environment is little | |
160 | endian, otherwise</li> | |
161 | <li>unequal to both <code>order::little</code> and <code>order::big</code>.</li> | |
162 | </ul> | |
163 | <h3><a name="Requirements">Requirements</a></h3> | |
164 | <h4><a name="Template-argument-requirements">Template argument requirements</a></h4> | |
165 | <p>The template definitions in the <code>boost/endian/conversion.hpp</code> | |
166 | header refer to various named requirements whose details are set out in the | |
167 | tables in this subsection. In these tables, <code>T</code> is an object or | |
168 | reference type to be supplied by a C++ program instantiating a template; <code>x</code> | |
169 | is a value of type (possibly <code>const</code>) <code>T</code>; <code>mlx</code> is a | |
170 | modifiable lvalue of type <code>T</code>.</p> | |
171 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> | |
172 | <tr> | |
173 | <td colspan="3" align="center"><b><code><a name="EndianReversible">EndianReversible</a></code></b> | |
174 | requirements (in addition to <b><code>CopyConstructible</code></b>)</td> | |
175 | </tr> | |
176 | <tr> | |
177 | <td><b>Expression</b></td> | |
178 | <td><b>Return<br> | |
179 | type</b></td> | |
180 | <td><b>Requirements</b></td> | |
181 | </tr> | |
182 | <tr> | |
183 | <td valign="top"><code>endian_reverse(x)</code></td> | |
184 | <td align="center" valign="top"><code>T</code></td> | |
185 | <td> <code>T</code> is an endian type or a class type.<p>If <code>T</code> is | |
186 | an endian type, returns the value of <code>x</code> with the order of bytes | |
187 | reversed.</p> | |
188 | <p>If <code>T</code> is a class type, the function:</p> | |
189 | <ul> | |
190 | <li>Returns the value of <code>x</code> | |
191 | with the order of bytes reversed for all data members of types or arrays of | |
192 | types that meet the <code>EndianReversible</code> requirements, and;</li> | |
193 | <li>Is a non-member function in the same namespace as <code>T</code> that | |
194 | can be found by argument dependent lookup (ADL). </li> | |
195 | </ul> | |
196 | </td> | |
197 | </tr> | |
198 | </table> | |
199 | <p> </p> | |
200 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> | |
201 | <tr> | |
202 | <td colspan="2" align="center"><b><code><a name="EndianReversibleInplace">EndianReversibleInplace</a></code></b> | |
203 | requirements (in addition to <b><code>CopyConstructible</code></b>)</td> | |
204 | </tr> | |
205 | <tr> | |
206 | <td><b>Expression</b></td> | |
207 | <td><b>Requirements</b></td> | |
208 | </tr> | |
209 | <tr> | |
210 | <td valign="top"><code>endian_reverse_inplace(mlx)</code></td> | |
211 | <td> <code>T</code> is an endian type or a class type.<p>If <code>T</code> is | |
212 | an endian type, reverses the order of bytes in <code>mlx</code>.</p> | |
213 | <p>If <code>T</code> is a class type, the function:</p> | |
214 | <ul> | |
215 | <li>Reverses the order of bytes of all data members of <code>mlx</code> | |
216 | that have types or arrays of | |
217 | types that meet the <code>EndianReversible</code> or <code>EndianReversibleInplace</code> | |
218 | requirements, and;</li> | |
219 | <li>Is a non-member function in the same namespace as <code>T</code> that | |
220 | can be found by argument dependent lookup (ADL). </li> | |
221 | </ul> | |
222 | </td> | |
223 | </tr> | |
224 | </table> | |
225 | ||
226 | <p> [<i>Note:</i> Because there is a function template for <code>endian_reverse_inplace</code> | |
227 | that calls <code>endian_reverse</code>, only <code>endian_reverse</code> | |
228 | is required for a user-defined type to meet the <code>EndianReversibleInplace</code> | |
229 | requirements. Although User-defined types are not required to supply an <code>endian_reverse_inplace</code> | |
230 | function, doing so may improve efficiency. <i> —end note</i>]</p> | |
231 | ||
232 | <h4> <a name="Customization-points">Customization points</a> for user-defined types (<a name="UDT">UDT</a>s)</h4> | |
233 | ||
234 | <p> This subsection describes requirements on the Endian library's implementation.</p> | |
235 | ||
236 | <p> The library's function templates requiring <code> | |
237 | <a href="#EndianReversible">EndianReversible</a></code> are | |
238 | required to perform reversal of endianness if needed by making an unqualified | |
239 | call to <code>endian_reverse()</code>.</p> | |
240 | ||
241 | <p> The library's function templates requiring <code> | |
242 | <a href="#EndianReversibleInplace">EndianReversibleInplace</a></code> are required to perform reversal of endianness if needed by making an | |
243 | unqualified call to <code>endian_reverse_inplace()</code>.</p> | |
244 | ||
245 | <p> See <b><code>example/udt_conversion_example.cpp</code></b> for an example user-defined type.</p> | |
246 | ||
247 | <h3><a name="Functions">Functions</a></h3> | |
248 | <pre><a name="endian_reverse"></a>int8_t endian_reverse(int8_t x) noexcept; | |
249 | int16_t endian_reverse(int16_t x) noexcept; | |
250 | int32_t endian_reverse(int32_t x) noexcept; | |
251 | int64_t endian_reverse(int64_t x) noexcept; | |
252 | uint8_t endian_reverse(uint8_t x) noexcept; | |
253 | uint16_t endian_reverse(uint16_t x) noexcept; | |
254 | uint32_t endian_reverse(uint32_t x) noexcept; | |
255 | uint64_t endian_reverse(uint64_t x) noexcept;</pre> | |
256 | <blockquote> | |
257 | <p><i>Returns:</i> <i><code>x</code></i>, with the order of its | |
258 | constituent bytes reversed.</p> | |
259 | <p><i>Remarks:</i> The type of <i><code>x</code></i> meets the <code>EndianReversible</code> requirements.</p> | |
260 | <p>[<i>Note:</i> The Boost.Endian library does not provide overloads for the C++ standard library | |
261 | supplied types. <i>—end note</i>]</p> | |
262 | </blockquote> | |
263 | ||
264 | <pre>template <class EndianReversible> | |
265 | EndianReversible big_to_native(EndianReversible x) noexcept;</pre> | |
266 | <blockquote> | |
267 | <p> | |
268 | <i>Returns:</i> <code>conditional_reverse<order::big, order::native>(x)</code>.</p> | |
269 | </blockquote> | |
270 | <pre>template <class EndianReversible> | |
271 | EndianReversible native_to_big(EndianReversible x) noexcept; </pre> | |
272 | <blockquote> | |
273 | <p><i>Returns:</i> <code>conditional_reverse<order::native, order::big>(x)</code>.</p> | |
274 | </blockquote> | |
275 | <pre>template <class EndianReversible> | |
276 | EndianReversible little_to_native(EndianReversible x) noexcept; </pre> | |
277 | <blockquote> | |
278 | <p><i>Returns:</i> <code>conditional_reverse<order::little, order::native>(x)</code>.</p> | |
279 | </blockquote> | |
280 | <pre>template <class EndianReversible> | |
281 | EndianReversible native_to_little(EndianReversible x) noexcept; </pre> | |
282 | <blockquote> | |
283 | <p><i>Returns:</i> <code>conditional_reverse<order::native, order::little>(x)</code>.</p> | |
284 | </blockquote> | |
285 | <pre>template <order O1, order O2, class EndianReversible> | |
286 | EndianReversible conditional_reverse(EndianReversible x) noexcept; </pre> | |
287 | <blockquote> | |
288 | <p><i>Returns:</i> <code>x</code> if <code>O1 == O2,</code> otherwise <code>endian_reverse(x)</code>.</p> | |
289 | <p><i>Remarks: </i>Whether <code>x</code> or <code>endian_reverse(x)</code> is to be returned shall be determined at compile time.</p> | |
290 | </blockquote> | |
291 | <pre>template <class EndianReversible> | |
292 | EndianReversible conditional_reverse(EndianReversible x, | |
293 | order order1, order order2) noexcept; </pre> | |
294 | <blockquote> | |
295 | <p><i>Returns:</i> <code>order1 == order2 ? x : endian_reverse(x)</code>.</p> | |
296 | </blockquote> | |
297 | ||
298 | <pre>template <class EndianReversible> | |
299 | void endian_reverse_inplace(EndianReversible& x) noexcept; </pre> | |
300 | ||
301 | <blockquote> | |
302 | <p><i>Effects:</i> <code>x</code> <code>= endian_reverse(x)</code>.</p> | |
303 | </blockquote> | |
304 | ||
305 | <pre>template <class EndianReversibleInplace> | |
306 | void big_to_native_inplace(EndianReversibleInplace& x) noexcept; </pre> | |
307 | <blockquote> | |
308 | <p> | |
309 | <i>Effects:</i> <code>conditional_reverse_inplace<order::big, order::native>(x)</code>.</p> | |
310 | </blockquote> | |
311 | <pre>template <class EndianReversibleInplace> | |
312 | void native_to_big_inplace(EndianReversibleInplace& x) noexcept; </pre> | |
313 | <blockquote> | |
314 | <p> | |
315 | <i>Effects:</i> <code>conditional_reverse_inplace<order::native, order::big>(x)</code>.</p> | |
316 | </blockquote> | |
317 | <pre>template <class EndianReversibleInplace> | |
318 | void little_to_native_inplace(EndianReversibleInplace& x) noexcept; </pre> | |
319 | <blockquote> | |
320 | <p> | |
321 | <i>Effects:</i> <code>conditional_reverse_inplace<order::little, order::native>(x)</code>.</p> | |
322 | </blockquote> | |
323 | <pre>template <class EndianReversibleInplace> | |
324 | void native_to_little_inplace(EndianReversibleInplace& x) noexcept; </pre> | |
325 | <blockquote> | |
326 | <p> | |
327 | <i>Effects:</i> <code>conditional_reverse_inplace<order::native, order::little>(x)</code>.</p> | |
328 | </blockquote> | |
329 | <pre>template <order O1, order O2, class EndianReversibleInplace> | |
330 | void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept; </pre> | |
331 | <blockquote> | |
332 | <p><i>Effects:</i> None if <code>O1 == O2,</code> otherwise <code>endian_reverse_inplace(x)</code>.</p> | |
333 | <p><i>Remarks: </i>Which effect applies shall be determined at compile time.</p> | |
334 | </blockquote> | |
335 | <pre>template <class EndianReversibleInplace> | |
336 | void conditional_reverse_inplace(EndianReversibleInplace& x, | |
337 | order order1, order order2) noexcept; </pre> | |
338 | ||
339 | ||
340 | <blockquote> | |
341 | <p><i>Effects: </i>If <code>order1 == order2</code> then <code>endian_reverse_inplace(x)</code>.</p> | |
342 | </blockquote> | |
343 | ||
344 | ||
345 | <h2> <a name="FAQ">FAQ</a></h2> | |
346 | ||
347 | <p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide | |
348 | FAQ.</p> | |
349 | ||
350 | <p><b>Why are both value returning and modify-in-place functions provided?</b></p> | |
351 | ||
352 | <blockquote> | |
353 | ||
354 | <p>Returning the result by value is the standard C and C++ idiom for functions that compute a | |
355 | value from an argument. Modify-in-place functions allow cleaner code in many real-world | |
356 | endian use cases and are more efficient for user-defined types that have | |
357 | members such as string data that do not need to be reversed. Thus both forms are | |
358 | provided.</p> | |
359 | ||
360 | </blockquote> | |
361 | ||
362 | <p><b>Why are exact-length 8, 16, 32, and 64-bit integers supported rather than the built-in | |
363 | char, short, int, long, long long, etc?</b></p> | |
364 | ||
365 | <blockquote> | |
366 | ||
367 | <p>The primary use case, portable file or network data, needs these de facto | |
368 | standard sizes. Using types that vary with the platform would greatly limit | |
369 | portability for both programs and data.</p> | |
370 | ||
371 | </blockquote> | |
372 | ||
373 | <p><b>Why not use the Linux names (htobe16, htole16, be16toh, le16toh, etc.) ?</b></p> | |
374 | ||
375 | <blockquote> | |
376 | ||
377 | <p>Those names are non-standard and vary even between POSIX-like operating | |
378 | systems. A C++ library TS was going to use those names, but found they were | |
379 | sometimes implemented as macros. Since macros do not respect scoping and | |
380 | namespace rules, to use them would be very error prone.</p> | |
381 | ||
382 | </blockquote> | |
383 | ||
384 | <h2><a name="Acknowledgements">Acknowledgements</a></h2><p>Tomas Puverle was instrumental | |
385 | in identifying and articulating the need to support endian conversion as separate from | |
386 | endian integer types. Phil Endecott suggested the form of the value returning signatures. | |
387 | Vicente Botet and other reviewers suggested supporting user defined types. | |
388 | General reverse template implementation approach using std::reverse suggested by Mathias Gaunard. | |
389 | Portable implementation approach for 16, 32, and 64-bit integers suggested by tymofey, | |
390 | with avoidance of undefined behavior as suggested by Giovanni Piero Deretta, | |
391 | and a further refinement suggested by Pyry Jahkola. | |
392 | Intrinsic builtins implementation approach for 16, 32, and 64-bit integers suggested by | |
393 | several reviewers, and by David Stone, who provided his Boost licensed macro implementation | |
394 | that became the starting point for <b><code>boost/endian/detail/intrinsic.hpp</code></b>. | |
395 | Pierre Talbot provided the <code>int8_t endian_reverse()</code> and templated | |
396 | <code>endian_reverse_inplace()</code> implementations.</p> | |
397 | <hr> | |
398 | <p>Last revised: | |
399 | <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->14 October, 2015<!--webbot bot="Timestamp" endspan i-checksum="38874" --></p> | |
400 | <p>© Copyright Beman Dawes, 2011, 2013</p> | |
401 | <p>Distributed under the Boost Software License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> | |
402 | ||
403 | </body> | |
404 | ||
405 | </html> |