forked from boostorg/endian
303 lines
15 KiB
HTML
303 lines
15 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=windows-1252">
|
|
|
|
<title>Boost Endian Conversion Functions</title>
|
|
<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="933">
|
|
<tr>
|
|
<td width="277">
|
|
<a href="../../../index.html">
|
|
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" border="0"></a></td>
|
|
<td width="636" align="middle">
|
|
<font size="7">Endian Conversion Functions</font></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="integers.html">Integer Types</a> Tutorial</b></td>
|
|
</tr>
|
|
</table>
|
|
<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="#Functions">Functions</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="../../../boost/endian/conversion.hpp"><boost/endian/conversion.hpp></a><br>
|
|
<a href="../../../boost/endian/integers.hpp"><boost/endian/integers.hpp></a></td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h2><a name="Introduction">Introduction</a></h2>
|
|
|
|
<p>Header <a href="../../../boost/endian/conversion.hpp">boost/endian/conversion.hpp</a>
|
|
provides byte reverse and conversion functions that convert built-in
|
|
integers, <code>float</code>, and <code>double</code> between native byte ordering and <a href="index.html#definition">big or little endian</a> byte
|
|
ordering. User defined types are also supported.</p>
|
|
|
|
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
|
<tr>
|
|
<td bgcolor="#FFFFCC">Caution: Only big and little endianness are supported;
|
|
middle endianness is not supported.</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h2><a name="FAQ">FAQ</a></h2>
|
|
|
|
<p><b>Why are <code>reverse()</code> and <code>reverse_value()</code> templates
|
|
in a detail namespace?</b> They are unsafe for general use. Consider reversing
|
|
the bytes of a <b><code>std::pair</code></b> - the bytes from <b><code>first</code></b>
|
|
would end up in <b><code>second</code></b> and visa versa, and this is totally
|
|
wrong!</p>
|
|
|
|
<h2><a name="Reference">Reference</a></h2>
|
|
|
|
<p><code>noexcept</code> is not present for compilers that do not support it.
|
|
Boost scoped enum emulation is used for compilers that do not support scoped
|
|
enums. Actual functions are <code>inline</code> if appropriate.</p>
|
|
|
|
<h3>
|
|
<a name="Synopsis">Synopsis</a></h3>
|
|
|
|
<pre>namespace boost
|
|
{
|
|
namespace endian
|
|
{
|
|
enum class order {big, little, native};
|
|
|
|
// reverse byte order (i.e. endianness)
|
|
int16_t reverse_value(int16_t x) noexcept;
|
|
int32_t reverse_value(int32_t x) noexcept;
|
|
int64_t reverse_value(int64_t x) noexcept;
|
|
uint16_t reverse_value(uint16_t x) noexcept;
|
|
uint32_t reverse_value(uint32_t x) noexcept;
|
|
uint64_t reverse_value(uint64_t x) noexcept;
|
|
float reverse_value(float x) noexcept;
|
|
double reverse_value(double x) noexcept;
|
|
|
|
void reverse(int16_t& x) noexcept;
|
|
void reverse(int32_t& x) noexcept;
|
|
void reverse(int64_t& x) noexcept;
|
|
void reverse(uint16_t& x) noexcept;
|
|
void reverse(uint32_t& x) noexcept;
|
|
void reverse(uint64_t& x) noexcept;
|
|
void reverse(float& x) noexcept;
|
|
void reverse(double& x) noexcept;
|
|
|
|
// reverse byte order unless native endianness is big
|
|
template <class ReversibleValue >
|
|
ReversibleValue big_endian_value(ReversibleValue x) noexcept;
|
|
template <class Reversible>
|
|
void big_endian(Reversible& x) noexcept;
|
|
|
|
// reverse byte order unless native endianness is little
|
|
template <class ReversibleValue >
|
|
ReversibleValue little_endian_value(ReversibleValue x) noexcept;
|
|
template <class Reversible>
|
|
void little_endian(Reversible& x) noexcept;
|
|
|
|
// synonyms, based on names popularized by BSD (e.g. OS X, Linux)
|
|
// "h" for "host" (i.e. native), "be" for "big endian",
|
|
// "le" for "little endian", "m" for "modify" in place
|
|
template <class T> T bswap(T x) noexcept {return reverse_value(x);}
|
|
template <class T> T htobe(T host) noexcept {return big_endian_value(host);}
|
|
template <class T> T htole(T host) noexcept {return little_endian_value(host);}
|
|
template <class T> T betoh(T big) noexcept {return big_endian_value(big);}
|
|
template <class T> T letoh(T little) noexcept {return little_endian_value(little);}
|
|
|
|
template <class T> void bswapm(T& x) noexcept {reverse(x);}
|
|
template <class T> void htobem(T& host) noexcept {big_endian(host);}
|
|
template <class T> void htole(mT& host noexcept) {little_endian(host);}
|
|
template <class T> void betohm(T& big) noexcept {big_endian(big);}
|
|
template <class T> void letohm(T& little) noexcept {little_endian(little);}
|
|
|
|
// compile-time generic byte order conversion
|
|
template <order From, order To, class ReversibleValue>
|
|
ReversibleValue convert_value(ReversibleValue from) noexcept;
|
|
template <order From, order To, class Reversible>
|
|
void convert(Reversible& x) noexcept;
|
|
|
|
// runtime effective byte order determination
|
|
order effective_order(order x) noexcept;
|
|
|
|
// runtime byte-order conversion
|
|
template <class ReversibleValue>
|
|
ReversibleValue convert_value(ReversibleValue from,
|
|
order from_order, order to_order) noexcept;
|
|
template <class Reversible>
|
|
void convert(Reversible& x,
|
|
order from_order, order to_order) noexcept;
|
|
|
|
} // namespace endian
|
|
} // namespace boost</pre>
|
|
<h3><a name="Requirements">Requirements</a></h3>
|
|
<p>The template definitions in this library refer to various named
|
|
requirements whose details are set out in this section. </p>
|
|
<h4><a name="ReversibleValue">ReversibleValue</a> requirements</h4>
|
|
<p><code>ReversibleValue</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>ReversibleValue</code>.</p>
|
|
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
|
<tr>
|
|
<td width="160"><b>Expression</b></td>
|
|
<td width="150"><b>Return type</b></td>
|
|
<td width="347"><b>Requirement</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top">
|
|
<p><code>reverse_value(x)</code></td>
|
|
<td valign="top">
|
|
<p><a name="ReversibleValue"><code>ReversibleValue</code></a></td>
|
|
<td>
|
|
<p>The returned value is the value of <code>x</code> with the
|
|
order of its constituent bytes reversed.</td>
|
|
</tr>
|
|
</table>
|
|
<h4><a name="Reversible">Reversible</a> requirements</h4>
|
|
<p><code>Reversible</code> is an object or reference type to be
|
|
supplied by a C++ program instantiating a template; <code>x</code> is a
|
|
modifiable lvalue of type <code>Reversible</code>.</p>
|
|
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
|
<tr>
|
|
<td width="160"><b>Expression</b></td>
|
|
<td width="347"><b>Post-condition</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top">
|
|
<p><code>reverse(x)</code></td>
|
|
<td>
|
|
<p>The order of the constituent bytes of <code>x</code> are
|
|
reversed.</td>
|
|
</tr>
|
|
</table>
|
|
<h3><a name="Functions">Functions</a></h3>
|
|
<pre>int16_t reverse_value(int16_t x) noexcept;
|
|
int32_t reverse_value(int32_t x) noexcept;
|
|
int64_t reverse_value(int64_t x) noexcept;
|
|
uint16_t reverse_value(uint16_t x) noexcept;
|
|
uint32_t reverse_value(uint32_t x) noexcept;
|
|
uint64_t reverse_value(uint64_t x) noexcept;
|
|
float reverse_value(float x) noexcept;
|
|
double reverse_value(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>void reverse(int16_t& x) noexcept;
|
|
void reverse(int32_t& x) noexcept;
|
|
void reverse(int64_t& x) noexcept;
|
|
void reverse(uint16_t& x) noexcept;
|
|
void reverse(uint32_t& x) noexcept;
|
|
void reverse(uint64_t& x) noexcept;
|
|
void reverse(float& x) noexcept;
|
|
void reverse(double& x) noexcept;</pre>
|
|
<blockquote>
|
|
<p><i>Postconditions:</i> The order of the constituent bytes of
|
|
<code>x</code> are reversed.</p>
|
|
</blockquote>
|
|
<pre>template <class ReversibleValue >
|
|
ReversibleValue big_endian_value(ReversibleValue x) noexcept;
|
|
template <class Reversible>
|
|
void big_endian(Reversible& x) noexcept;</pre>
|
|
<blockquote>
|
|
<p dir="ltr"><i>Returns (first form)</i>: <code>x</code> if the native byte order is big
|
|
endian, otherwise <code>reverse_value(x)</code>.</p>
|
|
<p dir="ltr"><i>Effects (second form):</i> None if the native byte order is big
|
|
endian, otherwise <code>reverse(x)</code>.</p>
|
|
<p dir="ltr"><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 dir="ltr">template <class ReversibleValue >
|
|
ReversibleValue little_endian_value(ReversibleValue x) noexcept;
|
|
template <class Reversible>
|
|
void little_endian(Reversible& x) noexcept;</pre>
|
|
<blockquote>
|
|
<p dir="ltr"><i>Returns (first form)</i>: <code>x</code> if the native byte order is little
|
|
endian, otherwise <code>reverse_value(x)</code>.</p>
|
|
<p dir="ltr"><i>Effects (second form):</i> None if the native byte order is little
|
|
endian, otherwise <code>reverse(x)</code>.</p>
|
|
<p dir="ltr"><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 dir="ltr">template <order From, order To, class ReversibleValue>
|
|
ReversibleValue convert_value(ReversibleValue from) noexcept;
|
|
template <order From, order To, class Reversible>
|
|
void convert(Reversible& x) noexcept;
|
|
</pre>
|
|
<blockquote>
|
|
<p dir="ltr">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 dir="ltr"><i>Returns (first form)</i>: <code>from</code> if <code>From</code>
|
|
and <code>To</code> have the same effective order, otherwise <code>
|
|
reverse_value(from)</code>.</p>
|
|
<p dir="ltr"><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 dir="ltr"><i>Example:</i></p>
|
|
<blockquote>
|
|
<pre>int32_t x;
|
|
<i>... read an external big-endian value into x</i>
|
|
convert<order::big, order::native>(x); // more generic equivalent of big_endian(x);</pre>
|
|
</blockquote>
|
|
</blockquote>
|
|
<pre>order effective_order(order x) noexcept;<blockquote><p dir="ltr"><i>Returns:</i> <code>x</code> if <code>x != order::native</code>, otherwise the <code>order</code> constant for the actual native byte order.</p><p dir="ltr"><i>Example:</i></p><blockquote><pre dir="ltr">effective_order(order::big); // returns order::big
|
|
effective_order(order::little); // returns order::little
|
|
effective_order(order::native); // returns order::big if the native order
|
|
// is big-endian, otherwise order::little</pre></blockquote></blockquote><pre dir="ltr">template <class ReversibleValue>
|
|
ReversibleValue convert_value(ReversibleValue from,
|
|
order from_order, order to_order) noexcept;
|
|
template <class Reversible>
|
|
void convert(Reversible& x,
|
|
order from_order, order to_order) noexcept;</pre><blockquote><p dir="ltr"><i>Returns (first form)</i>: <code>from</code> if <code>effect_order(from_order) == effective_order(to_order)</code>, otherwise <code>reverse_value(from)</code>.</p>
|
|
<p dir="ltr"><i>Effects (second form):</i> None if <code>effect_order(from_order) == effective_order(to_order)</code>, otherwise <code>reverse(x)</code>.</p>
|
|
<p dir="ltr"><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="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>.</p>
|
|
<hr>
|
|
<p>Last revised: <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->18 May, 2013<!--webbot bot="Timestamp" endspan i-checksum="13991" --></p>
|
|
<p>© Copyright Beman Dawes, 2011</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> |