forked from boostorg/endian
367 lines
16 KiB
HTML
367 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>
|
|
<a href="index.html">Endian Home</a>
|
|
<a href="conversion.html">Conversion Functions</a>
|
|
<a href="arithmetic.html">Arithmetic Types</a>
|
|
<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>
|
|
<a href="#Synopsis">Synopsis</a><br>
|
|
<a href="#Requirements">Requirements</a><br>
|
|
<code><a href="#Reversible">Reversible</a></code><br>
|
|
<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"><boost/endian/conversion.hpp></a><br>
|
|
<a href="../include/boost/endian/buffers.hpp"><boost/endian/buffers.hpp></a><br>
|
|
<a href="../include/boost/endian/arithmetic.hpp"><boost/endian/arithmetic.hpp></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 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><boost/endian/conversion.hpp></code>
|
|
<a name="Synopsis">Synopsis</a></h3>
|
|
|
|
<pre>#define BOOST_ENDIAN_INTRINSIC_MSG "<b><font face="Arial"><i>message describing presence or absence of intrinsics</i></font></b>"
|
|
|
|
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>};
|
|
|
|
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;
|
|
float <a href="#endian_reverse">endian_reverse</a>(float x) noexcept;
|
|
double <a href="#endian_reverse">endian_reverse</a>(double x) noexcept;
|
|
|
|
template <class Reversible>
|
|
Reversible big_to_native(Reversible x) noexcept;
|
|
template <class Reversible>
|
|
Reversible native_to_big(Reversible x) noexcept;
|
|
template <class Reversible>
|
|
Reversible little_to_native(Reversible x) noexcept;
|
|
template <class Reversible>
|
|
Reversible native_to_little(Reversible x) noexcept;
|
|
template <order O1, order O2, class Reversible>
|
|
Reversible conditional_reverse(Reversible x) noexcept;
|
|
template <class Reversible>
|
|
Reversible conditional_reverse(Reversible x,
|
|
order order1, order order2) noexcept;
|
|
|
|
template <class Reversible>
|
|
void endian_reverse_in_place(Reversible& x) noexcept;
|
|
|
|
template <class Reversible>
|
|
void big_to_native_in_place(Reversible& x) noexcept;
|
|
template <class Reversible>
|
|
void native_to_big_in_place(Reversible& x) noexcept;
|
|
template <class Reversible>
|
|
void little_to_native_in_place(Reversible& x) noexcept;
|
|
template <class Reversible>
|
|
void native_to_little_in_place(Reversible& x) noexcept;
|
|
template <order O1, order O2, class Reversible>
|
|
void conditional_reverse_in_place(Reversible& x) noexcept;
|
|
template <class Reversible>
|
|
void conditional_reverse_in_place(Reversible& 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><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>endian_reverse(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>Returns the value of <code>x</code> with the
|
|
order of its constituent bytes reversed.</td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top">
|
|
<code>endian_reverse_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>—end note</i>]</p>
|
|
|
|
<p> [<i>Note:</i> Because there is a function template for <code>endian_reverse_in_place</code>
|
|
that calls <code>endian_reverse</code>, only <code>endian_reverse</code>
|
|
is required for a user-defined type to meet the <code>Reversible</code>
|
|
requirements. User-defined types may provide <code>endian_reverse_in_place</code>
|
|
for improved efficiency. <i>—end note</i>]</p>
|
|
|
|
<p> <span style="background-color: #FFFF00">This still isn't right. There are
|
|
really separate Reversible and </span><span style="background-color: #FFFF00">
|
|
ReversibleHere</span><span style="background-color: #FFFF00"> requirements, and
|
|
the </span><span style="background-color: #FFFF00">endian_reverse_here</span><span style="background-color: #FFFF00">
|
|
template's type should be Reversible. See the udt_conversion_example for a type
|
|
that is ReversibleHere but not Reversible and works just fine.</span></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's own
|
|
implementation.</p>
|
|
|
|
<p> The endianness reversal function templates that return values are
|
|
required to perform reversal of endianness if needed by making an unqualified
|
|
call to <code>endian_reverse(<i>argument</i>)</code>, as described in the
|
|
preceding table.</p>
|
|
|
|
<p> The endianness reversal function templates that modify their argument in
|
|
place, except <code>endian_reverse_in_place</code> itself, are required to perform reversal of endianness if needed by making an
|
|
unqualified call to <code>endian_reverse_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="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;
|
|
float endian_reverse(float x) noexcept;
|
|
double endian_reverse(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>template <class Reversible>
|
|
Reversible big_to_native(Reversible x) noexcept;</pre>
|
|
<blockquote>
|
|
<p>
|
|
<i>Returns:</i> <code>conditional_reverse<order::big,
|
|
order::native>(x)</code>.</p>
|
|
</blockquote>
|
|
<pre>template <class Reversible>
|
|
Reversible native_to_big(Reversible x) noexcept; </pre>
|
|
<blockquote>
|
|
<p><i>Returns:</i> <code>conditional_reverse<order::native, order::big>(x)</code>.</p>
|
|
</blockquote>
|
|
<pre>template <class Reversible>
|
|
Reversible little_to_native(Reversible x) noexcept; </pre>
|
|
<blockquote>
|
|
<p><i>Returns:</i> <code>conditional_reverse<order::little, order::native>(x)</code>.</p>
|
|
</blockquote>
|
|
<pre>template <class Reversible>
|
|
Reversible native_to_little(Reversible x) noexcept; </pre>
|
|
<blockquote>
|
|
<p><i>Returns:</i> <code>conditional_reverse<order::native, order::little>(x)</code>.</p>
|
|
</blockquote>
|
|
<pre>template <order O1, order O2, class Reversible>
|
|
Reversible conditional_reverse(Reversible 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 <class Reversible>
|
|
Reversible conditional_reverse(Reversible x,
|
|
order order1, order order2) noexcept; </pre>
|
|
<blockquote>
|
|
<p><i>Returns:</i> <code>order1 == order2 ? x : endian_reverse(x)</code>.</p>
|
|
</blockquote>
|
|
|
|
<pre>template <class Reversible>
|
|
void endian_reverse_in_place(Reversible& x) noexcept; </pre>
|
|
|
|
<blockquote>
|
|
<p><i>Effects:</i> <code>x</code> <code>= endian_reverse(x)</code>.</p>
|
|
</blockquote>
|
|
|
|
<pre>template <class Reversible>
|
|
void big_to_native_in_place(Reversible& x) noexcept; </pre>
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> <code>conditional_reverse_in_place<order::big,
|
|
order::native>(x)</code>.</p>
|
|
</blockquote>
|
|
<pre>template <class Reversible>
|
|
void native_to_big_in_place(Reversible& x) noexcept; </pre>
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> <code>conditional_reverse_in_place<order::native,
|
|
order::big>(x)</code>.</p>
|
|
</blockquote>
|
|
<pre>template <class Reversible>
|
|
void little_to_native_in_place(Reversible& x) noexcept; </pre>
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> <code>conditional_reverse_in_place<order::little, order::native>(x)</code>.</p>
|
|
</blockquote>
|
|
<pre>template <class Reversible>
|
|
void native_to_little_in_place(Reversible& x) noexcept; </pre>
|
|
<blockquote>
|
|
<p>
|
|
<i>Effects:</i> <code>conditional_reverse_in_place<order::native,
|
|
order::little>(x)</code>.</p>
|
|
</blockquote>
|
|
<pre>template <order O1, order O2, class Reversible>
|
|
void conditional_reverse_in_place(Reversible& x) noexcept; </pre>
|
|
<blockquote>
|
|
<p><i>Effects:</i> None if <code>O1 == O2,</code> otherwise
|
|
<code>endian_reverse_in_place(x)</code>.</p>
|
|
<p><i>Remarks: </i>Which effect applies shall be determined at compile time.</p>
|
|
</blockquote>
|
|
<pre>template <class Reversible>
|
|
void conditional_reverse_in_place(Reversible& x,
|
|
order order1, order order2) noexcept; </pre>
|
|
|
|
|
|
<blockquote>
|
|
<p><i>Effects: </i>If <code>order1 == order2</code> then <code>endian_reverse_in_place(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 the template versions of <code>reverse()</code> and <code>endian_reverse()</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 endian_reverse()</code> and templated
|
|
<code>reverse()</code> implementations.</p>
|
|
<hr>
|
|
<p>Last revised:
|
|
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->10 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38633" --></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> |