Files
boost_endian/doc/conversion.html
T

340 lines
16 KiB
HTML

<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Endian Conversion Functions</title>
<link href="styles.css" rel="stylesheet">
</head>
<body>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr>
<td>
<a href="../../../index.html">
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" border="0" width="277" height="86" ></a></td>
<td align="middle">
<b>
<font size="6">Endian Conversion Functions</font></b></td>
</tr>
</table>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
<tr>
<td><b><a href="../../../index.htm">Boost Home</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="index.html">Endian Home</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="conversion.html">Conversion Functions</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="arithmetic.html">Arithmetic Types</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="buffers.html">Buffer Types</a></b></td>
</tr>
</table>
<p></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right">
<tr>
<td width="100%" bgcolor="#D7EEFF" align="center">
<i><b>Contents</b></i></td>
</tr>
<tr>
<td width="100%" bgcolor="#E8F5FF">
<a href="#Introduction">Introduction</a><br>
<a href="#Reference">Reference</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Synopsis">Synopsis</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Requirements">Requirements</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code><a href="#Reversible">Reversible</a></code><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#Customization-points">Customization for
UDTs</a><br>
<a href="#Functions">Functions</a><br>
<a href="#FAQ">FAQ</a><br>
<a href="#Acknowledgements">Acknowledgements</a></td>
</tr>
<tr>
<td width="100%" bgcolor="#D7EEFF" align="center">
<b><i>Headers</i></b></td>
</tr>
<tr>
<td width="100%" bgcolor="#E8F5FF">
<a href="../include/boost/endian/conversion.hpp">&lt;boost/endian/conversion.hpp&gt;</a><br>
<a href="../include/boost/endian/buffers.hpp">&lt;boost/endian/buffers.hpp&gt;</a><br>
<a href="../include/boost/endian/arithmetic.hpp">&lt;boost/endian/arithmetic.hpp&gt;</a></td>
</tr>
</table>
<h2><a name="Introduction">Introduction</a></h2>
<p>Header <a href="../include/boost/endian/conversion.hpp">boost/endian/conversion.hpp</a>
provides byte order reversal and conversion functions that convert objects of
the built-in
integer types, and also types <code>float</code> and <code>double,</code>
between native, big, or little endian byte
ordering. User defined types are also supported.</p>
<h2><a name="Reference">Reference</a></h2>
<p>Functions are implemented <code>inline</code> if appropriate.<code> noexcept</code> is
elided for compilers that do not support it.
Boost scoped enum emulation is used so that the library still works for compilers that do not support scoped enums. </p>
<h3>
Header <code>&lt;boost/endian/conversion.hpp&gt;</code>
<a name="Synopsis">Synopsis</a></h3>
<pre>#define BOOST_ENDIAN_INTRINSIC_MSG &quot;<b><font face="Arial"><i>message describing presence or absence of intrinsics</i></font></b>&quot;
namespace boost
{
namespace endian
{
enum class <a name="order">order</a>
{
big, // big-endian
little, // little-endian
native = <b><i>implementation-defined</i></b> // same as order::big or order::little<b><i>
</i></b>};
// reverse byte order (i.e. endianness)
int8_t <a href="#reverse_endianness">reverse_endianness</a>(int8_t x) noexcept;
int16_t <a href="#reverse_endianness">reverse_endianness</a>(int16_t x) noexcept;
int32_t <a href="#reverse_endianness">reverse_endianness</a>(int32_t x) noexcept;
int64_t <a href="#reverse_endianness">reverse_endianness</a>(int64_t x) noexcept;
uint8_t <a href="#reverse_endianness">reverse_endianness</a>(uint8_t x) noexcept;
uint16_t <a href="#reverse_endianness">reverse_endianness</a>(uint16_t x) noexcept;
uint32_t <a href="#reverse_endianness">reverse_endianness</a>(uint32_t x) noexcept;
uint64_t <a href="#reverse_endianness">reverse_endianness</a>(uint64_t x) noexcept;
float <a href="#reverse_endianness">reverse_endianness</a>(float x) noexcept;
double <a href="#reverse_endianness">reverse_endianness</a>(double x) noexcept;
template &lt;class Value&gt;
void <a href="#reverse">reverse</a>(Value&amp; x) noexcept;
// reverse byte order unless native endianness is big
template &lt;class ReversibleValue &gt;
ReversibleValue <a href="#big_endian_value">big_endian_value</a>(ReversibleValue x) noexcept;
template &lt;class Reversible&gt;
void <a href="#big_endian">big_endian</a>(Reversible&amp; x) noexcept;
// reverse byte order unless native endianness is little
template &lt;class ReversibleValue &gt;
ReversibleValue <a href="#little_endian_value">little_endian_value</a>(ReversibleValue x) noexcept;
template &lt;class Reversible&gt;
void <a href="#little_endian">little_endian</a>(Reversible&amp; x) noexcept;
// generic byte order conversion
template &lt;order From, order To, class ReversibleValue&gt;
ReversibleValue <a href="#convert_value_generic">convert_value</a>(ReversibleValue from) noexcept;
template &lt;order From, order To, class Reversible&gt;
void <a href="#convert_generic">convert</a>(Reversible&amp; x) noexcept;
// runtime byte-order conversion
template &lt;class ReversibleValue&gt;
ReversibleValue <a href="#convert_value_runtime">convert_value</a>(ReversibleValue from,
order from_order, order to_order) noexcept;
template &lt;class Reversible&gt;
void <a href="#convert_runtime">convert</a>(Reversible&amp; x,
order from_order, order to_order) noexcept;
} // namespace endian
} // namespace boost</pre>
<p dir="ltr">The implementation is required to define the <code>enum class order</code>
constant <code>native</code> as
<code>big</code> on big endian platforms and <code>little</code> on little
endian platforms.</p>
<h3><a name="Requirements">Requirements</a></h3>
<h4>Template argument <code><a name="Reversible">Reversible</a></code> requirements</h4>
<p>This subsection describes names that are used to specify constraints on
template arguments.</p>
<p>User-defined types may be used in the function templates in this header only
if they meet these requirements.</p>
<p><code>Reversible</code> is an object type to be supplied by a C++ program
instantiating a template.</p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr>
<td width="160"><b>Expression</b></td>
<td width="160"><b>Meaning of x</b></td>
<td width="347"><b>Requirements</b></td>
</tr>
<tr>
<td valign="top">
<p><code>reverse_endianness(x)</code></td>
<td valign="top">
<code>x</code> is a value of a possibly <code>const</code> type convertible
to <code>Reversible</code>.</td>
<td>
<p>The value of <code>x</code> with the
order of its constituent bytes reversed is returned.</td>
</tr>
<tr>
<td valign="top">
<code>reverse_endianness_in_place(x)</code></td>
<td valign="top">
<code>x</code> is a
modifiable lvalue of type <code>Reversible</code>.</td>
<td>
The order of the constituent bytes of <code>x</code> are
reversed.</td>
</tr>
</table>
<blockquote>
<p> [<i>Note:</i> A user-defined type meets these requirements by defining a
non-member function in the same namespace as the UDT itself so that the function
can be found by argument dependent lookup (ADL). <i>&mdash;end note</i>]</p>
</blockquote>
<h4> <a name="Customization-points">Customization points</a> for user-defined types (<a name="UDT">UDT</a>s)</h4>
<p> This subsection describes requirements on the endian library&#39;s own
implementation.</p>
<p> The endianness conversion function templates that return values are
required to perform reversal of endianness if needed by making an unqualified
call to <code>reverse_endianness(<i>argument</i>)</code>, as described in the
preceding table.</p>
<p> The endianness conversion function templates that modify their argument in
place are required to perform reversal of endianness if needed by making an
unqualified call to <code>reverse_endianness_in_place(<i>argument</i>)</code>,
as described in the preceding table.</p>
<p> See <a href="../example/udt_conversion_example.cpp">
udt_conversion_example.cpp</a> for an example user-defined type.</p>
<h3><a name="Functions">Functions</a></h3>
<pre><a name="reverse_endianness"></a>int8_t reverse_endianness(int8_t x) noexcept;
int16_t reverse_endianness(int16_t x) noexcept;
int32_t reverse_endianness(int32_t x) noexcept;
int64_t reverse_endianness(int64_t x) noexcept;
uint8_t reverse_endianness(uint8_t x) noexcept;
uint16_t reverse_endianness(uint16_t x) noexcept;
uint32_t reverse_endianness(uint32_t x) noexcept;
uint64_t reverse_endianness(uint64_t x) noexcept;
float reverse_endianness(float x) noexcept;
double reverse_endianness(double x) noexcept;</pre>
<blockquote>
<p><i>Returns:</i> <i><code>x</code></i>, with the order of its
constituent bytes reversed.</p>
</blockquote>
<pre><a name="reverse"></a>template &lt;class Value&gt;
void reverse(Value&amp; x) noexcept;</pre>
<blockquote>
<p><i>Postconditions:</i> The order of the constituent bytes of
<code>x</code> are reversed.</p>
</blockquote>
<pre><a name="big_endian_value"></a>template &lt;class ReversibleValue &gt;
ReversibleValue big_endian_value(ReversibleValue x) noexcept;
<a name="big_endian"></a>template &lt;class Reversible&gt;
void big_endian(Reversible&amp; x) noexcept;</pre>
<blockquote>
<p><i>Returns (first form)</i>: <code>x</code> if the native byte order is big
endian, otherwise <code>reverse_endianness(x)</code>.</p>
<p><i>Effects (second form):</i> None if the native byte order is big
endian, otherwise <code>reverse(x)</code>.</p>
<p><i>Example:</i></p>
<blockquote>
<pre>int32_t x = <b><i>some-value</i></b>;
big_endian(x); // reverses the byte order of x, unless
// the native byte order is big-endian</pre>
</blockquote>
</blockquote>
<pre><a name="little_endian_value"></a>template &lt;class ReversibleValue &gt;
ReversibleValue little_endian_value(ReversibleValue x) noexcept;
<a name="little_endian"></a>template &lt;class Reversible&gt;
void little_endian(Reversible&amp; x) noexcept;</pre>
<blockquote>
<p><i>Returns (first form)</i>: <code>x</code> if the native byte order is little
endian, otherwise <code>reverse_endianness(x)</code>.</p>
<p><i>Effects (second form):</i> None if the native byte order is little
endian, otherwise <code>reverse(x)</code>.</p>
<p><i>Example:</i></p>
<blockquote>
<pre>int32_t x = <b><i>some-value</i></b>;
int32_t y(little_endian(x));
// y has been set to x; the byte order is reversed unless
// the native byte order is little-endian.</pre>
</blockquote>
</blockquote>
<pre><a name="convert_value_generic"></a>template &lt;order From, order To, class ReversibleValue&gt;
ReversibleValue convert_value(ReversibleValue from) noexcept;
<a name="convert_generic"></a>template &lt;order From, order To, class Reversible&gt;
void convert(Reversible&amp; x) noexcept;
</pre>
<blockquote>
<p>The <b><i>effective order</i></b> of an order template parameter
is the same as the order template parameter if the parameter is not <code>
order::native</code>, otherwise it is the constant <code>order::big</code> or
<code>order::little</code> that represents the actual native byte order.</p>
<p><i>Returns (first form)</i>: <code>from</code> if <code>From</code>
and <code>To</code> have the same effective order, otherwise <code>
reverse_endianness(from)</code>.</p>
<p><i>Effects (second form):</i> None if <code>From</code> and <code>
To</code> have the same effective order, otherwise <code>reverse(x)</code>.</p>
<p><i>Example:</i></p>
<blockquote>
<pre>int32_t x;
<i>... read an external big-endian value into x</i>
convert&lt;order::big, order::native&gt;(x); // more generic equivalent of big_endian(x);</pre>
</blockquote>
</blockquote>
<pre><a name="convert_value_runtime"></a>template &lt;class ReversibleValue&gt;
ReversibleValue convert_value(ReversibleValue from,
order from_order, order to_order) noexcept;
<a name="convert_runtime"></a>template &lt;class Reversible&gt;
void convert(Reversible&amp; x,
order from_order, order to_order) noexcept;</pre><blockquote><p><i>Returns (first form)</i>: <code>from</code> if <code>effect_order(from_order) == effective_order(to_order)</code>, otherwise <code>reverse_endianness(from)</code>.</p>
<p><i>Effects (second form):</i> None if <code>effect_order(from_order) == effective_order(to_order)</code>, otherwise <code>reverse(x)</code>.</p>
<p><i>Example:</i></p>
<blockquote>
<pre>int32_t x;
<i>... read an external value of an endianness know only at runtime into x</i>
convert(x, some_order, order::native); // convert to native byte order if needed</pre>
</blockquote>
</blockquote>
<h2> <a name="FAQ">FAQ</a></h2>
<p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide
FAQ.</p>
<p><b>Why are the template versions of <code>reverse()</code> and <code>reverse_endianness()</code>
in a detail namespace?</b></p>
<blockquote>
<p>They are unsafe for general use. Consider reversing
the bytes of a <code>std::pair</code> as a whole - the bytes from <code>first</code>
would end up in <code>second</code> and visa versa, and this is totally
wrong!</p>
</blockquote>
<p><b>Why are both value returning and modify-in-place functions provided?</b></p>
<blockquote>
<p>Returning the result by value is the standard C and C++ idiom for functions that compute a
value from an argument. Modify-in-place functions allow cleaner code in many real-world
endian use cases and are more efficient for user defined types that have
members such as string data that do not need to be reversed. Thus both forms are
provided.</p>
</blockquote>
<h2><a name="Acknowledgements">Acknowledgements</a></h2><p>Tomas Puverle was instrumental in identifying and articulating the need to
support endian conversion as separate from endian integer types. Phil Endecott suggested the form of the value returning signatures. Vicente Botet and other reviewers suggested supporting floating point types and user defined types. General reverse template implementation approach using std::reverse suggested by Mathias Gaunard. Portable implementation approach for 16, 32, and 64-bit integers suggested by tymofey, with avoidance of undefined behavior as suggested by Giovanni Piero Deretta, and a further refinement suggested by Pyry Jahkola. Intrinsic builtins implementation approach for 16, 32, and 64-bit integers suggested by several reviewers, and by David Stone, who provided his Boost licensed macro implementation that became the starting point for <a href="../include/boost/endian/detail/intrinsic.hpp">boost/endian/detail/intrinsic.hpp</a>.
Pierre Talbot provided the <code>int8_t reverse_endianness()</code> and templated
<code>reverse()</code> implementations.</p>
<hr>
<p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->07 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38646" --></p>
<p>© Copyright Beman Dawes, 2011, 2013</p>
<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>
</body>
</html>