blob: d811e07dd60b13edfeb86eec2b67f6b590b7ce50 [file] [log] [blame]
<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 logo" 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.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>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="choosing_approach.html">Choosing Approach</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="#EndianReversible">EndianReversible</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>
</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
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> </code>
For C++03 compilers, <code> noexcept</code> is
elided .
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-as-big-or-little
</i></b>};
int8_t <a href="#endian_reverse">endian_reverse</a>(int8_t x) noexcept;
int16_t <a href="#endian_reverse">endian_reverse</a>(int16_t x) noexcept;
int32_t <a href="#endian_reverse">endian_reverse</a>(int32_t x) noexcept;
int64_t <a href="#endian_reverse">endian_reverse</a>(int64_t x) noexcept;
uint8_t <a href="#endian_reverse">endian_reverse</a>(uint8_t x) noexcept;
uint16_t <a href="#endian_reverse">endian_reverse</a>(uint16_t x) noexcept;
uint32_t <a href="#endian_reverse">endian_reverse</a>(uint32_t x) noexcept;
uint64_t <a href="#endian_reverse">endian_reverse</a>(uint64_t x) noexcept;
template &lt;class EndianReversible&gt;
EndianReversible big_to_native(EndianReversible x) noexcept;
template &lt;class EndianReversible&gt;
EndianReversible native_to_big(EndianReversible x) noexcept;
template &lt;class EndianReversible&gt;
EndianReversible little_to_native(EndianReversible x) noexcept;
template &lt;class EndianReversible&gt;
EndianReversible native_to_little(EndianReversible x) noexcept;
template &lt;order O1, order O2, class EndianReversible&gt;
EndianReversible conditional_reverse(EndianReversible x) noexcept;
template &lt;class EndianReversible&gt;
EndianReversible conditional_reverse(EndianReversible x,
order order1, order order2) noexcept;
template &lt;class EndianReversible&gt;
void endian_reverse_inplace(EndianReversible&amp; x) noexcept;
template &lt;class EndianReversibleInplace&gt;
void big_to_native_inplace(EndianReversibleInplace&amp; x) noexcept;
template &lt;class EndianReversibleInplace&gt;
void native_to_big_inplace(EndianReversibleInplace&amp; x) noexcept;
template &lt;class EndianReversibleInplace&gt;
void little_to_native_inplace(EndianReversibleInplace&amp; x) noexcept;
template &lt;class EndianReversibleInplace&gt;
void native_to_little_inplace(EndianReversibleInplace&amp; x) noexcept;
template &lt;order O1, order O2, class EndianReversibleInplace&gt;
void conditional_reverse_inplace(EndianReversibleInplace&amp; x) noexcept;
template &lt;class EndianReversibleInplace&gt;
void conditional_reverse_inplace(EndianReversibleInplace&amp; x,
order order1, order order2) 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 dir="ltr"><a name="Definitions">Definitions</a></h3>
<p dir="ltr">The standard integral types (C++std 3.9.1) except <code>bool</code>,
are collectively called the <i>endian types</i>.</p>
<h3><a name="Requirements">Requirements</a></h3>
<h4><a name="Template-argument-requirements">Template argument requirements</a></h4>
<p dir="ltr">The template definitions in the <code>boost/endian/conversion.hpp</code>
header refer to various named requirements whose details are set out in the
tables in this subsection. In these tables, <code>T</code> is an object or
reference type to be supplied by a C++ program instantiating a template; <code>x</code>
is a value of type (possibly <code>const</code>) <code>T</code>; <code>mlx</code> is a
modifiable lvalue of type <code>T</code>.</p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr>
<td colspan="3" align="center"><b><code><a name="EndianReversible">EndianReversible</a></code></b>
requirements (in addition to <b><code>CopyConstructible</code></b>)</td>
</tr>
<tr>
<td><b>Expression</b></td>
<td><b>Return<br>
type</b></td>
<td><b>Requirements</b></td>
</tr>
<tr>
<td valign="top"><code>endian_reverse(x)</code></td>
<td align="center" valign="top"><code>T</code></td>
<td> <code>T</code> is an endian type or a class type.<p>If <code>T</code> is
an endian type, returns the value of <code>x</code> with the order of bytes
reversed.</p>
<p>If <code>T</code> is a class type, the function:</p>
<ul>
<li>Returns the value of <code>x</code>
with the order of bytes reversed for all data members of types or arrays of
types that meet the <code>EndianReversible</code> requirements, and;</li>
<li>Is a non-member function in the same namespace as <code>T</code> that
can be found by argument dependent lookup (ADL). </li>
</ul>
</td>
</tr>
</table>
<p>&nbsp;</p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr>
<td colspan="2" align="center"><b><code><a name="EndianReversibleInplace">EndianReversibleInplace</a></code></b>
requirements (in addition to <b><code>CopyConstructible</code></b>)</td>
</tr>
<tr>
<td><b>Expression</b></td>
<td><b>Requirements</b></td>
</tr>
<tr>
<td valign="top"><code>endian_reverse_inplace(mlx)</code></td>
<td> <code>T</code> is an endian type or a class type.<p>If <code>T</code> is
an endian type, reverses the order of bytes in <code>mlx</code>.</p>
<p>If <code>T</code> is a class type, the function:</p>
<ul>
<li>Reverses the order of bytes of all data members of <code>mlx</code>
that have types or arrays of
types that meet the <code>EndianReversible</code> or <code>EndianReversibleInplace</code>
requirements, and;</li>
<li>Is a non-member function in the same namespace as <code>T</code> that
can be found by argument dependent lookup (ADL).&nbsp; </li>
</ul>
</td>
</tr>
</table>
<p> [<i>Note:</i> Because there is a function template for <code>endian_reverse_inplace</code>
that calls <code>endian_reverse</code>, only <code>endian_reverse</code>
is required for a user-defined type to meet the <code>EndianReversibleInplace</code>
requirements. Although User-defined types are not required to supply an <code>endian_reverse_inplace</code>
function, doing so may improve efficiency. <i>&nbsp;&mdash;end note</i>]</p>
<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 implementation.</p>
<p> The library&#39;s function templates requiring <code>
<a href="#EndianReversible">EndianReversible</a></code> are
required to perform reversal of endianness if needed by making an unqualified
call to <code>endian_reverse()</code>.</p>
<p> The library&#39;s function templates requiring <code>
<a href="#EndianReversibleInplace">EndianReversibleInplace</a></code> are required to perform reversal of endianness if needed by making an
unqualified call to <code>endian_reverse_inplace()</code>.</p>
<p> See <b><code>example/udt_conversion_example.cpp</code></b> for an example user-defined type.</p>
<h3><a name="Functions">Functions</a></h3>
<pre><a name="endian_reverse"></a>int8_t endian_reverse(int8_t x) noexcept;
int16_t endian_reverse(int16_t x) noexcept;
int32_t endian_reverse(int32_t x) noexcept;
int64_t endian_reverse(int64_t x) noexcept;
uint8_t endian_reverse(uint8_t x) noexcept;
uint16_t endian_reverse(uint16_t x) noexcept;
uint32_t endian_reverse(uint32_t x) noexcept;
uint64_t endian_reverse(uint64_t x) noexcept;</pre>
<blockquote>
<p dir="ltr"><i>Returns:</i> <i><code>x</code></i>, with the order of its
constituent bytes reversed.</p>
<p><i>Remarks:</i> The type of <i><code>x</code></i> meets the <code>EndianReversible</code> requirements.</p>
<p>[<i>Note:</i> The Boost.Endian library does not provide overloads for the C++ standard library
supplied types. <i>&mdash;end note</i>]</p>
</blockquote>
<pre>template &lt;class EndianReversible&gt;
EndianReversible big_to_native(EndianReversible x) noexcept;</pre>
<blockquote>
<p>
<i>Returns:</i> <code>conditional_reverse&lt;order::big, order::native&gt;(x)</code>.</p>
</blockquote>
<pre>template &lt;class EndianReversible&gt;
EndianReversible native_to_big(EndianReversible x) noexcept; </pre>
<blockquote>
<p><i>Returns:</i> <code>conditional_reverse&lt;order::native, order::big&gt;(x)</code>.</p>
</blockquote>
<pre>template &lt;class EndianReversible&gt;
EndianReversible little_to_native(EndianReversible x) noexcept; </pre>
<blockquote>
<p><i>Returns:</i> <code>conditional_reverse&lt;order::little, order::native&gt;(x)</code>.</p>
</blockquote>
<pre>template &lt;class EndianReversible&gt;
EndianReversible native_to_little(EndianReversible x) noexcept; </pre>
<blockquote>
<p><i>Returns:</i> <code>conditional_reverse&lt;order::native, order::little&gt;(x)</code>.</p>
</blockquote>
<pre>template &lt;order O1, order O2, class EndianReversible&gt;
EndianReversible conditional_reverse(EndianReversible x) noexcept; </pre>
<blockquote>
<p><i>Returns:</i> <code>x</code> if <code>O1 == O2,</code> otherwise <code>endian_reverse(x)</code>.</p>
<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>
</blockquote>
<pre>template &lt;class EndianReversible&gt;
EndianReversible conditional_reverse(EndianReversible x,
order order1, order order2) noexcept; </pre>
<blockquote>
<p><i>Returns:</i> <code>order1 == order2 ? x : endian_reverse(x)</code>.</p>
</blockquote>
<pre>template &lt;class EndianReversible&gt;
void endian_reverse_inplace(EndianReversible&amp; x) noexcept; </pre>
<blockquote>
<p><i>Effects:</i> <code>x</code> <code>= endian_reverse(x)</code>.</p>
</blockquote>
<pre>template &lt;class EndianReversibleInplace&gt;
void big_to_native_inplace(EndianReversibleInplace&amp; x) noexcept; </pre>
<blockquote>
<p>
<i>Effects:</i> <code>conditional_reverse_inplace&lt;order::big, order::native&gt;(x)</code>.</p>
</blockquote>
<pre>template &lt;class EndianReversibleInplace&gt;
void native_to_big_inplace(EndianReversibleInplace&amp; x) noexcept; </pre>
<blockquote>
<p>
<i>Effects:</i> <code>conditional_reverse_inplace&lt;order::native, order::big&gt;(x)</code>.</p>
</blockquote>
<pre>template &lt;class EndianReversibleInplace&gt;
void little_to_native_inplace(EndianReversibleInplace&amp; x) noexcept; </pre>
<blockquote>
<p>
<i>Effects:</i> <code>conditional_reverse_inplace&lt;order::little, order::native&gt;(x)</code>.</p>
</blockquote>
<pre>template &lt;class EndianReversibleInplace&gt;
void native_to_little_inplace(EndianReversibleInplace&amp; x) noexcept; </pre>
<blockquote>
<p>
<i>Effects:</i> <code>conditional_reverse_inplace&lt;order::native, order::little&gt;(x)</code>.</p>
</blockquote>
<pre>template &lt;order O1, order O2, class EndianReversibleInplace&gt;
void conditional_reverse_inplace(EndianReversibleInplace&amp; x) noexcept; </pre>
<blockquote>
<p><i>Effects:</i> None if <code>O1 == O2,</code> otherwise <code>endian_reverse_inplace(x)</code>.</p>
<p><i>Remarks: </i>Which effect applies shall be determined at compile time.</p>
</blockquote>
<pre>template &lt;class EndianReversibleInplace&gt;
void conditional_reverse_inplace(EndianReversibleInplace&amp; x,
order order1, order order2) noexcept; </pre>
<blockquote>
<p><i>Effects: </i>If <code>order1 == order2</code> then <code>endian_reverse_inplace(x)</code>.</p>
</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 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>
<p><b>Why are exact-length 8, 16, 32, and 64-bit integers supported rather than the built-in
char, short, int, long, long long, etc?</b></p>
<blockquote>
<p>The primary use case, portable file or network data, needs these de facto
standard sizes. Using types that vary with the platform would greatly limit
portability for both programs and data.</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 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 <b><code>boost/endian/detail/intrinsic.hpp</code></b>.
Pierre Talbot provided the <code>int8_t endian_reverse()</code> and templated
<code>endian_reverse_inplace()</code> implementations.</p>
<hr>
<p>Last revised: <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->26 March, 2015<!--webbot bot="Timestamp" endspan i-checksum="28922" --></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>