Sync with develop

This commit is contained in:
Beman
2014-12-17 08:41:40 -05:00
parent 84ad1a041f
commit 3fafd83028
8 changed files with 1927 additions and 664 deletions

View File

@@ -5,25 +5,22 @@
<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>Boost Endian Integers</title>
<style type="text/css">
ins {background-color:#CCFFCC}
del {background-color:#FFCACA}
body { font-family: sans-serif; width:8.0in; }
pre { background-color:#D7EEFF }
<title>Endian Arithmetic Types</title>
<link href="styles.css" rel="stylesheet">
</style>
</head>
<body>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="710">
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr>
<td width="277">
<td>
<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="413" align="middle">
<font size="7">Endian Types</font>
<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 Arithmetic Types</font> </b>
</td>
</tr>
</table>
@@ -33,7 +30,8 @@
<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="types.html">Endian Types</a></b></td>
<a href="arithmetic.html">Arithmetic Types</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="buffers.html">Buffer Types</a></b></td>
</tr>
</table>
@@ -55,6 +53,8 @@
&nbsp;&nbsp;&nbsp;
<a href="#Synopsis">Synopsis</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Members">Members</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Stream-inserter">Stream inserter</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Stream-extractor">Stream extractor</a><br>
<a href="#FAQ">FAQ</a><br>
<a href="#Design">Design</a><br>
<a href="#Experience">Experience</a><br>
@@ -71,11 +71,12 @@
<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/types.hpp">&lt;boost/endian/types.hpp&gt;</a></td>
<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/types.hpp">boost/endian/types.hpp</a>
<p>Header <a href="arithmetic.html">boost/endian/arithmetic.hpp</a>
provides integer and floating point binary types with control over
byte order, value type, size, and alignment. Typedefs provide easy-to-use names
for common configurations.</p>
@@ -86,7 +87,8 @@ integer byte-holders may
also be used to reduce memory use, file size, or network activity since they
provide binary integer sizes not otherwise available.</p>
<p>Such integer byte-holder types are traditionally called <b><i>
endian</i></b> types. See the <a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> for
endian</i></b> types. See the
<a href="http://en.wikipedia.org/wiki/Endian" name="endianness">Wikipedia</a> for
a full
exploration of <b><i>endianness</i></b>, including definitions of <i><b>big
endian</b></i> and <i><b>little endian</b></i>.</p>
@@ -101,7 +103,7 @@ arithmetic operators are <code>+</code>, <code>+=</code>, <code>-</code>, <code>
<code>^</code>, <code>^=</code>, <code>&lt;&lt;</code>, <code>&lt;&lt;=</code>, <code>&gt;&gt;</code>,
<code>&gt;&gt;=</code>. Binary relational operators are <code>==</code>, <code>!=</code>,
<code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, <code>&gt;=</code>.</p>
<p>Automatic implicit conversion to the underlying value type is provided. An
<p>Automatic implicit conversion to the underlying value type is provided. A
conversion constructor from the underlying value type is provided. </p>
<h2><a name="Example">Example</a></h2>
<p>The <a href="../example/endian_example.cpp">endian_example.cpp</a> program writes a
@@ -109,17 +111,17 @@ binary file containing four byte big-endian and little-endian integers:</p>
<blockquote>
<pre>#include &lt;iostream&gt;
#include &lt;cstdio&gt;
#include &lt;boost/endian/types.hpp&gt;
#include &lt;boost/endian/arithmetic.hpp&gt;
#include &lt;boost/static_assert.hpp&gt;
using namespace boost::endian;
namespace
{
// This is an extract from a very widely used GIS file format. Who knows
// why a designer would mix big and little endians in the same file - but
// this is a real-world format and users wishing to write low level code
// manipulating these files have to deal with the mixed endianness.
// This is an extract from a very widely used GIS file format. It seems odd
// to mix big and little endians in the same file - but this is a real-world
// format and users wishing to write low level code manipulating these files
// must deal with the mixed endianness.
struct header
{
@@ -144,10 +146,10 @@ int main(int, char* [])
h.shape_type = 0x01020304;
// Low-level I/O such as POSIX read/write or &lt;cstdio&gt; fread/fwrite is sometimes
// used for binary file operations when ultimate efficiency is important.
// Such I/O is often performed in some C++ wrapper class, but to drive home the
// point that endian integers are often used in fairly low-level code that
// does bulk I/O operations, &lt;cstdio&gt; fopen/fwrite is used for I/O in this example.
// used for binary file operations when ultimate efficiency is important. Such
// I/O is often performed in some C++ wrapper class, but to drive home the
// point that endian integers are often used in fairly low-level code that does
// bulk I/O operations, &lt;cstdio&gt; fopen/fwrite is used for I/O in this example.
std::FILE* fi = std::fopen(filename, &quot;wb&quot;); // MUST BE BINARY
@@ -213,7 +215,7 @@ enum class align {no, yes}; </pre>
<p>One class template is provided:</p>
<blockquote>
<pre>template &lt;order Order, typename T, std::size_t n_bits, align A = align::no&gt;
class endian;
class endian_arithmetic;
</pre>
</blockquote>
<p>Typedefs, such as <code>big_int32_t</code>, provide convenient naming
@@ -223,108 +225,122 @@ conventions for common use cases:</p>
<tr>
<td width="18%" align="center"><b><i>Name</i></b></td>
<td width="10%" align="center"><b><i>Endianness</i></b></td>
<td width="49%" align="center"><b><i>Alignment</i></b></td>
<td width="10%" align="center"><b><i>Sign</i></b></td>
<td width="15%" align="center"><b><i>Sizes in bits (n)</i></b></td>
<td width="49%" align="center"><b><i>Alignment</i></b></td>
</tr>
<tr>
<td width="18%"><code>big_align_int</code><i><b>n</b></i><code>_t</code></td>
<td width="18%"><code>big_int</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="49%" align="center"><code>yes</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">16,32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>big_align_uint</code><i><b>n</b></i><code>_t</code></td>
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="49%" align="center"><code>yes</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">16,32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>big_align_float</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>little_align_int</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">16,32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>little_align_uint</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">16,32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>little_align_float</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>big_int</code><b><i>n</i></b><code>_t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_</code><code>t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>big_float</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="49%" align="center"><code>yes</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_</code><code>t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="18%"><code>big_int</code><b><i>n</i></b><code>_ut</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
</tr>
<tr>
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_</code><code>t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_ut</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
</tr>
<tr>
<td width="18%"><code>big_float</code><i><b>n</b></i><code>_ut</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
</tr>
<tr>
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="49%" align="center"><code>yes</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">16,32,64</td>
</tr>
<tr>
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="49%" align="center"><code>yes</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">16,32,64</td>
</tr>
<tr>
<td width="18%"><code>little_float</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="49%" align="center"><code>yes</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>native_int</code><i><b>n</b></i><code>_</code><code>t</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_ut</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>native_uint</code><i><b>n</b></i><code>_</code><code>t</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_ut</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>little_float</code><i><b>n</b></i><code>_ut</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
</tr>
<tr>
<td width="18%"><code>native_float</code><i><b>n</b></i><code>_t</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="49%" align="center"><code>yes</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
</tr>
<tr>
<td width="18%"><code>native_int</code><i><b>n</b></i><code>_ut</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
</tr>
<tr>
<td width="18%"><code>native_uint</code><i><b>n</b></i><code>_ut</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
</tr>
<tr>
<td width="18%"><code>native_float</code><i><b>n</b></i><code>_ut</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="49%" align="center"><code>no</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
</tr>
</table>
</blockquote>
<p>The unaligned types do not cause compilers to insert padding bytes in classes
@@ -339,7 +355,7 @@ are only available on architectures with 16, 32, and 64-bit integer types. </p>
<p><b><i>Note:</i></b> One-byte types
have identical
functionality. They are provided to improve code readability and searchability.</p>
<h2><a name="Class_template_endian">Class template <code>endian</code></a></h2>
<h2><a name="Class_template_endian">Class template <code>endian</code></a><code>_arithmetic</code></h2>
<p>An endian is an integer byte-holder with user-specified <a href="#endianness">
endianness</a>, value type, size, and <a href="#alignment">alignment</a>. The
usual operations on integers are supplied.</p>
@@ -359,20 +375,22 @@ usual operations on integers are supplied.</p>
enum class <a name="alignment">align</a> {no, yes};
template &lt;order Order, typename T, std::size_t n_bits, align A = align::no&gt;
class endian
template &lt;order Order, class T, std::size_t n_bits, align A = align::no&gt;
class endian_arithmetic
: public endian_buffer&lt;Order, T, n_bits, A&gt;
{
public:
typedef T value_type;
typedef T value_type;
// if BOOST_ENDIAN_FORCE_PODNESS is defined &amp;&amp; C++11 POD's are not
// available then these two constructors will not be present
<a href="#endian">endian</a>() noexcept = default;
<a href="#explicit-endian">endian</a>(T v) noexcept;
<a href="#endian">endian_arithmetic</a>() noexcept = default;
<a href="#explicit-endian">endian_arithmetic</a>(T v) noexcept;
endian&amp; <a href="#operator-eq">operator=</a>(T v) noexcept;
<a href="#operator-T">operator T</a>() const noexcept;
const char* <a href="#data">data</a>() const noexcept;
endian_arithmetic&amp; <a href="#operator-eq">operator=</a>(T v) noexcept;
<a href="#operator-T">operator value_type</a>() const noexcept;
value_type value() const noexcept; // exposition only; see endian_buffer
const char* <a href="#data">data</a>() const noexcept; // exposition only; see endian_buffer
// arithmetic operations
// note that additional operations are provided by the value_type
@@ -393,15 +411,27 @@ usual operations on integers are supplied.</p>
endian&amp; operator--(endian&amp; x) noexcept;
endian operator++(endian&amp; x, int) noexcept;
endian operator--(endian&amp; x, int) noexcept;
// Stream inserter
template &lt;class charT, class traits&gt;
friend std::basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(std::basic_ostream&lt;charT, traits&gt;&amp; os, const T&amp; x);
// Stream extractor
template &lt;class charT, class traits&gt;
friend std::basic_istream&lt;charT, traits&gt;&amp;
operator&gt;&gt;(std::basic_istream&lt;charT, traits&gt;&amp; is, T&amp; x);
};
// typedefs
// aligned big endian floating point types
typedef endian&lt;order::big, float, 32, align::yes&gt; big_align_float32_t;
typedef endian&lt;order::big, double, 64, align::yes&gt; big_align_float64_t;
typedef endian&lt;order::big, float, 32, align::yes&gt; big_float32_t;
typedef endian&lt;order::big, double, 64, align::yes&gt; big_float64_t;
// aligned little endian floating point types
typedef endian&lt;order::little, float, 32, align::yes&gt; little_align_float32_t;
typedef endian&lt;order::little, double, 64, align::yes&gt; little_align_float64_t;
typedef endian&lt;order::little, float, 32, align::yes&gt; little_float32_t;
typedef endian&lt;order::little, double, 64, align::yes&gt; little_float64_t;
// unaligned big endian floating point types
typedef endian&lt;order::big, float, 32, align::no&gt; big_float32un_t;
@@ -412,87 +442,87 @@ usual operations on integers are supplied.</p>
typedef endian&lt;order::little, double, 64, align::no&gt; little_float64un_t;
// aligned big endian signed integer types
typedef endian&lt;order::big, int16_t, 16, align::yes&gt; big_align_int16_t;
typedef endian&lt;order::big, int32_t, 32, align::yes&gt; big_align_int32_t;
typedef endian&lt;order::big, int64_t, 64, align::yes&gt; big_align_int64_t;
typedef endian&lt;order::big, int16_t, 16, align::yes&gt; big_int16_t;
typedef endian&lt;order::big, int32_t, 32, align::yes&gt; big_int32_t;
typedef endian&lt;order::big, int64_t, 64, align::yes&gt; big_int64_t;
// aligned big endian unsigned integer types
typedef endian&lt;order::big, uint16_t, 16, align::yes&gt; big_align_uint16_t;
typedef endian&lt;order::big, uint32_t, 32, align::yes&gt; big_align_uint32_t;
typedef endian&lt;order::big, uint64_t, 64, align::yes&gt; big_align_uint64_t;
typedef endian&lt;order::big, uint16_t, 16, align::yes&gt; big_uint16_t;
typedef endian&lt;order::big, uint32_t, 32, align::yes&gt; big_uint32_t;
typedef endian&lt;order::big, uint64_t, 64, align::yes&gt; big_uint64_t;
// aligned little endian signed integer types
typedef endian&lt;order::little, int16_t, 16, align::yes&gt; little_align_int16_t;
typedef endian&lt;order::little, int32_t, 32, align::yes&gt; little_align_int32_t;
typedef endian&lt;order::little, int64_t, 64, align::yes&gt; little_align_int64_t;
typedef endian&lt;order::little, int16_t, 16, align::yes&gt; little_int16_t;
typedef endian&lt;order::little, int32_t, 32, align::yes&gt; little_int32_t;
typedef endian&lt;order::little, int64_t, 64, align::yes&gt; little_int64_t;
// aligned little endian unsigned integer types
typedef endian&lt;order::little, uint16_t, 16, align::yes&gt; little_align_uint16_t;
typedef endian&lt;order::little, uint32_t, 32, align::yes&gt; little_align_uint32_t;
typedef endian&lt;order::little, uint64_t, 64, align::yes&gt; little_align_uint64_t;
typedef endian&lt;order::little, uint16_t, 16, align::yes&gt; little_uint16_t;
typedef endian&lt;order::little, uint32_t, 32, align::yes&gt; little_uint32_t;
typedef endian&lt;order::little, uint64_t, 64, align::yes&gt; little_uint64_t;
// aligned native endian typedefs are not provided because
// &lt;cstdint&gt; types are superior for that use case
// unaligned big endian signed integer types
typedef endian&lt;order::big, int_least8_t, 8&gt; big_int8_t;
typedef endian&lt;order::big, int_least16_t, 16&gt; big_int16_t;
typedef endian&lt;order::big, int_least32_t, 24&gt; big_int24_t;
typedef endian&lt;order::big, int_least32_t, 32&gt; big_int32_t;
typedef endian&lt;order::big, int_least64_t, 40&gt; big_int40_t;
typedef endian&lt;order::big, int_least64_t, 48&gt; big_int48_t;
typedef endian&lt;order::big, int_least64_t, 56&gt; big_int56_t;
typedef endian&lt;order::big, int_least64_t, 64&gt; big_int64_t;
typedef endian&lt;order::big, int_least8_t, 8&gt; big_int8_ut;
typedef endian&lt;order::big, int_least16_t, 16&gt; big_int16_ut;
typedef endian&lt;order::big, int_least32_t, 24&gt; big_int24_ut;
typedef endian&lt;order::big, int_least32_t, 32&gt; big_int32_ut;
typedef endian&lt;order::big, int_least64_t, 40&gt; big_int40_ut;
typedef endian&lt;order::big, int_least64_t, 48&gt; big_int48_ut;
typedef endian&lt;order::big, int_least64_t, 56&gt; big_int56_ut;
typedef endian&lt;order::big, int_least64_t, 64&gt; big_int64_ut;
// unaligned big endian unsigned integer types
typedef endian&lt;order::big, uint_least8_t, 8&gt; big_uint8_t;
typedef endian&lt;order::big, uint_least16_t, 16&gt; big_uint16_t;
typedef endian&lt;order::big, uint_least32_t, 24&gt; big_uint24_t;
typedef endian&lt;order::big, uint_least32_t, 32&gt; big_uint32_t;
typedef endian&lt;order::big, uint_least64_t, 40&gt; big_uint40_t;
typedef endian&lt;order::big, uint_least64_t, 48&gt; big_uint48_t;
typedef endian&lt;order::big, uint_least64_t, 56&gt; big_uint56_t;
typedef endian&lt;order::big, uint_least64_t, 64&gt; big_uint64_t;
typedef endian&lt;order::big, uint_least8_t, 8&gt; big_uint8_ut;
typedef endian&lt;order::big, uint_least16_t, 16&gt; big_uint16_ut;
typedef endian&lt;order::big, uint_least32_t, 24&gt; big_uint24_ut;
typedef endian&lt;order::big, uint_least32_t, 32&gt; big_uint32_ut;
typedef endian&lt;order::big, uint_least64_t, 40&gt; big_uint40_ut;
typedef endian&lt;order::big, uint_least64_t, 48&gt; big_uint48_ut;
typedef endian&lt;order::big, uint_least64_t, 56&gt; big_uint56_ut;
typedef endian&lt;order::big, uint_least64_t, 64&gt; big_uint64_ut;
// unaligned little endian signed integer types
typedef endian&lt;order::little, int_least8_t, 8&gt; little_int8_t;
typedef endian&lt;order::little, int_least16_t, 16&gt; little_int16_t;
typedef endian&lt;order::little, int_least32_t, 24&gt; little_int24_t;
typedef endian&lt;order::little, int_least32_t, 32&gt; little_int32_t;
typedef endian&lt;order::little, int_least64_t, 40&gt; little_int40_t;
typedef endian&lt;order::little, int_least64_t, 48&gt; little_int48_t;
typedef endian&lt;order::little, int_least64_t, 56&gt; little_int56_t;
typedef endian&lt;order::little, int_least64_t, 64&gt; little_int64_t;
typedef endian&lt;order::little, int_least8_t, 8&gt; little_int8_ut;
typedef endian&lt;order::little, int_least16_t, 16&gt; little_int16_ut;
typedef endian&lt;order::little, int_least32_t, 24&gt; little_int24_ut;
typedef endian&lt;order::little, int_least32_t, 32&gt; little_int32_ut;
typedef endian&lt;order::little, int_least64_t, 40&gt; little_int40_ut;
typedef endian&lt;order::little, int_least64_t, 48&gt; little_int48_ut;
typedef endian&lt;order::little, int_least64_t, 56&gt; little_int56_ut;
typedef endian&lt;order::little, int_least64_t, 64&gt; little_int64_ut;
// unaligned little endian unsigned integer types
typedef endian&lt;order::little, uint_least8_t, 8&gt; little_uint8_t;
typedef endian&lt;order::little, uint_least16_t, 16&gt; little_uint16_t;
typedef endian&lt;order::little, uint_least32_t, 24&gt; little_uint24_t;
typedef endian&lt;order::little, uint_least32_t, 32&gt; little_uint32_t;
typedef endian&lt;order::little, uint_least64_t, 40&gt; little_uint40_t;
typedef endian&lt;order::little, uint_least64_t, 48&gt; little_uint48_t;
typedef endian&lt;order::little, uint_least64_t, 56&gt; little_uint56_t;
typedef endian&lt;order::little, uint_least64_t, 64&gt; little_uint64_t;
typedef endian&lt;order::little, uint_least8_t, 8&gt; little_uint8_ut;
typedef endian&lt;order::little, uint_least16_t, 16&gt; little_uint16_ut;
typedef endian&lt;order::little, uint_least32_t, 24&gt; little_uint24_ut;
typedef endian&lt;order::little, uint_least32_t, 32&gt; little_uint32_ut;
typedef endian&lt;order::little, uint_least64_t, 40&gt; little_uint40_ut;
typedef endian&lt;order::little, uint_least64_t, 48&gt; little_uint48_ut;
typedef endian&lt;order::little, uint_least64_t, 56&gt; little_uint56_ut;
typedef endian&lt;order::little, uint_least64_t, 64&gt; little_uint64_ut;
// unaligned native endian signed integer types
typedef <b><i>implementation-defined</i></b>_int8_t native_int8_t;
typedef <b><i>implementation-defined</i></b>_int16_t native_int16_t;
typedef <b><i>implementation-defined</i></b>_int24_t native_int24_t;
typedef <b><i>implementation-defined</i></b>_int32_t native_int32_t;
typedef <b><i>implementation-defined</i></b>_int40_t native_int40_t;
typedef <b><i>implementation-defined</i></b>_int48_t native_int48_t;
typedef <b><i>implementation-defined</i></b>_int56_t native_int56_t;
typedef <b><i>implementation-defined</i></b>_int64_t native_int64_t;
typedef <b><i>implementation-defined</i></b>_int8_t native_int8_ut;
typedef <b><i>implementation-defined</i></b>_int16_t native_int16_ut;
typedef <b><i>implementation-defined</i></b>_int24_t native_int24_ut;
typedef <b><i>implementation-defined</i></b>_int32_t native_int32_ut;
typedef <b><i>implementation-defined</i></b>_int40_t native_int40_ut;
typedef <b><i>implementation-defined</i></b>_int48_t native_int48_ut;
typedef <b><i>implementation-defined</i></b>_int56_t native_int56_ut;
typedef <b><i>implementation-defined</i></b>_int64_t native_int64_ut;
// unaligned native endian unsigned integer types
typedef <b><i>implementation-defined</i></b>_uint8_t native_uint8_t;
typedef <b><i>implementation-defined</i></b>_uint16_t native_uint16_t;
typedef <b><i>implementation-defined</i></b>_uint24_t native_uint24_t;
typedef <b><i>implementation-defined</i></b>_uint32_t native_uint32_t;
typedef <b><i>implementation-defined</i></b>_uint40_t native_uint40_t;
typedef <b><i>implementation-defined</i></b>_uint48_t native_uint48_t;
typedef <b><i>implementation-defined</i></b>_uint56_t native_uint56_t;
typedef <b><i>implementation-defined</i></b>_uint64_t native_uint64_t;
typedef <b><i>implementation-defined</i></b>_uint8_t native_uint8_ut;
typedef <b><i>implementation-defined</i></b>_uint16_t native_uint16_ut;
typedef <b><i>implementation-defined</i></b>_uint24_t native_uint24_ut;
typedef <b><i>implementation-defined</i></b>_uint32_t native_uint32_ut;
typedef <b><i>implementation-defined</i></b>_uint40_t native_uint40_ut;
typedef <b><i>implementation-defined</i></b>_uint48_t native_uint48_ut;
typedef <b><i>implementation-defined</i></b>_uint56_t native_uint56_ut;
typedef <b><i>implementation-defined</i></b>_uint64_t native_uint64_ut;
} // namespace endian
} // namespace boost</pre>
@@ -531,6 +561,29 @@ in <code>*this</code>.</p>
<h3>Other operators</h3>
<p>Other operators on endian objects are forwarded to the equivalent
operator on <code>value_type</code>.</p>
<h3><a name="Stream-inserter">Stream inserter</a></h3>
<pre>template &lt;class charT, class traits&gt;
friend std::basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(std::basic_ostream&lt;charT, traits&gt;&amp; os, const T&amp; x);
</pre>
<blockquote>
<p><i>Returns:</i> <code>os &lt;&lt; +x</code>.</p>
</blockquote>
<h3><a name="Stream-extractor">Stream extractor</a></h3>
<pre>template &lt;class charT, class traits&gt;
friend std::basic_istream&lt;charT, traits&gt;&amp;
operator&gt;&gt;(std::basic_istream&lt;charT, traits&gt;&amp; is, T&amp; x);
</pre>
<blockquote>
<p><i>Effects: </i>As if:</p>
<blockquote>
<pre>T i;
if (is &gt;&gt; i)
x = i;
</pre>
</blockquote>
<p><i>Returns: </i><code>is</code><i>.</i></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
@@ -542,7 +595,7 @@ conversion or copying. They are already in the desired format for binary I/O.
Thus they can be read or written in bulk.</p>
<p><b>Are endian types POD's?</b> Yes for C++11. No for C++03, although several
<a href="#Compilation">macros</a> are available to force PODness in all cases.</p>
<p><b>What are the implications endian integer types not being POD's with C++03
<p><b>What are the implications of endian integer types not being POD's with C++03
compilers?</b> They
can't be used in unions. Also, compilers aren't required to align or lay
out storage in portable ways, although this potential problem hasn't prevented
@@ -628,7 +681,7 @@ differs from endian representation size. Vicente Botet and other reviewers
suggested supporting floating point types.</p>
<hr>
<p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->12 August, 2014<!--webbot bot="Timestamp" endspan i-checksum="34569" --></p>
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38642" --></p>
<p>© Copyright Beman Dawes, 2006-2009, 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>

75
bikeshed.txt Normal file
View File

@@ -0,0 +1,75 @@
Conversion function naming bikeshed
return-by-value modify-argument
------------------ ---------------
reverse_endianness reverse_endianness_in_place
" reverse_endianness_arg
endian_reverse endian_reverse_in_place
" endian_reverse_inplace
" endian_reverse_replace
" endian_reverse_in_situ
" endian_reverse_here
" endian_reverse_this
" endian_reverse_self
" endian_reverse_arg
" endian_reverse_in
reverse reverse_in_place
reverse_endian reverse_endian_in_place
swap_endianness swap_endianness_in_place
swap_endian swap_endian_in_place
endian_swap endian_swap_this
flip_endianness flip_endianness_in_place
flip_endian flip_endian_in_place
endian_flip endian_flip_in_place
reverse_order reverse_order_in_place
Key points:
* The above names are defined in a user namespace as customization points to be found by
ADL, and so cannot depend on the enclosing namespace name to signal readers that they
are related to endianness.
* The above functions are rarely called directly by user code, which is more likely to use
the various conditional functions instead. So explicitness is more important than
brevity.
Conditional names
big_to_native native_to_big little_to_native native_to_little
big_to_host host_to_big
be_to_ne ne_to_be
from_big, to_big
big_to_native big_to_native
native_to_big native_to_big
conditional_reverse runtime_conditional_reverse
conditional_reverse conditional_reverse <------
merriam-webster.com/dictionary
reverse [1] (adjective): opposite or contrary to a previous or normal condition <reverse order>
reverse [2] (verb) : to change (something) to an opposite state or condition
swap (verb) : to give something to someone and receive something in return : to trade or exchange (things)
flip (verb)
: to turn (something) over by throwing it up in the air with a quick movement
: to cause (something) to turn or turn over quickly
: to move (something) with a quick light movement

627
buffers.html Normal file
View File

@@ -0,0 +1,627 @@
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<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 Buffer Types</title>
<link href="styles.css" rel="stylesheet">
</style>
</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 Buffer Types</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="#Example">Example</a><br>
<a href="#Limitations">Limitations</a><br>
<a href="#Feature-set">Feature set</a><br>
<a href="#Types">Enums and typedefs</a><br>
<a href="#Class_template_endian">Class template <code>endian_buffer</code></a><br>
&nbsp;&nbsp;&nbsp;
<a href="#Synopsis">Synopsis</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Members">Members</a><br>
<a href="#FAQ">FAQ</a><br>
<a href="#Design">Design</a><br>
<a href="#C++0x">C++11</a><br>
<a href="#Compilation">Compilation</a></td>
</tr>
<tr>
<td width="100%" bgcolor="#D7EEFF" align="center">
<b><i>Headers</i></b></td>
</tr>
<tr>
<td width="100%" bgcolor="#E8F5FF">
<p dir="ltr">
<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>The internal byte order of arithmetic types is traditionally called <b><i>endianness</i></b>. See the
<a href="http://en.wikipedia.org/wiki/Endian" name="endianness">Wikipedia</a> for
a full
exploration of <b><i>endianness</i></b>, including definitions of <i><b>big
endian</b></i> and <i><b>little endian</b></i>.</p>
<p>Header <a href="buffers.html">boost/endian/buffers.hpp</a>
provides <code>endian_buffer</code>, a portable endian integer and floating-point binary buffer
class template with control over
byte order, value type, size, and alignment independent of the platform&#39;s native
endianness. Typedefs provide easy-to-use names
for common configurations.</p>
<p>Use cases primarily involve data portability, either via files or network
connections, but these byte-holders may
also be used to reduce memory use, file size, or network activity since they
provide binary numeric sizes not otherwise available.</p>
<p dir="ltr">Class <code>endian_buffer</code> is aimed at users who wish
explicit control over when endianness conversions occur. It also serves as the
base class for the <code><a href="arithmetic.html">endian_arithmetic</a></code>
class template, which is aimed at users who wish fully automatic endianness
conversion and direct support for all normal arithmetic operations.</p>
<h2><a name="Example">Example</a></h2>
<p>The <a href="../example/endian_example.cpp">endian_example.cpp</a> program writes a
binary file containing four byte big-endian and little-endian integers:</p>
<blockquote>
<pre>#include &lt;iostream&gt;
#include &lt;cstdio&gt;
#include &lt;boost/endian/buffers.hpp&gt;
#include &lt;boost/static_assert.hpp&gt;
using namespace boost::endian;
namespace
{
// This is an extract from a very widely used GIS file format. Why the designer
// decided to mix big and little endians in the same file is not known. But
// this is a real-world format and users wishing to write low level code
// manipulating these files have to deal with the mixed endianness.
struct header
{
big_int32_<code>buf_</code>t file_code;
big_int32_<code>buf_</code>t file_length;
little_int32_<code>buf_</code>t version;
little_int32_<code>buf_</code>t shape_type;
};
const char* filename = &quot;test.dat&quot;;
}
int main(int, char* [])
{
BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check
header h;
h.file_code = 0x01020304;
h.file_length = sizeof(header);
h.version = 1;
h.shape_type = 0x01020304;
// Low-level I/O such as POSIX read/write or &lt;cstdio&gt; fread/fwrite is sometimes
// used for binary file operations when ultimate efficiency is important. Such
// I/O is often performed in some C++ wrapper class, but to drive home the
// point that endian integers are often used in fairly low-level code that does
// bulk I/O operations, &lt;cstdio&gt; fopen/fwrite is used for I/O in this example.
std::FILE* fi = std::fopen(filename, &quot;wb&quot;); // MUST BE BINARY
if (!fi)
{
std::cout &lt;&lt; &quot;could not open &quot; &lt;&lt; filename &lt;&lt; '\n';
return 1;
}
if (std::fwrite(&amp;h, sizeof(header), 1, fi)!= 1)
{
std::cout &lt;&lt; &quot;write failure for &quot; &lt;&lt; filename &lt;&lt; '\n';
return 1;
}
std::fclose(fi);
std::cout &lt;&lt; &quot;created file &quot; &lt;&lt; filename &lt;&lt; '\n';
return 0;
}
</pre>
</blockquote>
<p>After compiling and executing <a href="../example/endian_example.cpp">endian_example.cpp</a>,
a hex dump of <code>test.dat</code> shows:</p>
<blockquote>
<pre>01020304 00000010 01000000 04030201</pre>
</blockquote>
<p>Notice that the first two 32-bit integers are big endian while the second two
are little endian, even though the machine this was compiled and run on was
little endian.</p>
<h2><a name="Limitations">Limitations</a></h2>
<p>Requires <code>&lt;climits&gt;</code> <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code>
is some other value, compilation will result in an <code>#error</code>. This
restriction is in place because the design, implementation, testing, and
documentation has only considered issues related to 8-bit bytes, and there have
been no real-world use cases presented for other sizes.</p>
<p>In C++03, <code>endian_buffer</code> does not meet the requirements for POD types
because it has constructors, private data members, and a base class. This means
that common use cases are relying on unspecified behavior in that the C++
Standard does not guarantee memory layout for non-POD types. This has not been a
problem in practice since all known C++ compilers do layout memory as if <code>
endian</code> were a POD type. In C++11, it is possible to specify the
default constructor as trivial, and private data members and base classes will
no longer disqualify a type from being a POD. Thus under C++11, <code>endian_buffer</code>
will no longer be relying on unspecified behavior.</p>
<h2><a name="Feature-set">Feature set</a></h2>
<ul>
<li>Big endian| little endian | native endian byte ordering.</li>
<li>Signed | unsigned</li>
<li>Unaligned | aligned</li>
<li>Integer | floating point</li>
<li>1-8 byte (unaligned) | 2, 4, 8 byte (aligned)</li>
<li>Choice of value type</li>
</ul>
<h2>Enums and t<a name="Types">ypedefs</a></h2>
<p>Two scoped enums are provided:</p>
<blockquote>
<pre>enum class order {big, little, native};
enum class align {no, yes}; </pre>
</blockquote>
<p>One class template is provided:</p>
<blockquote>
<pre>template &lt;order Order, typename T, std::size_t Nbits, align A = align::no&gt;
class endian_buffer;
</pre>
</blockquote>
<p>Typedefs, such as <code>big_int32_buf_t</code>, provide convenient naming
conventions for common use cases:</p>
<blockquote>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="49%">
<tr>
<td width="18%" align="center"><b><i>Name</i></b></td>
<td width="10%" align="center"><b><i>Endianness</i></b></td>
<td width="10%" align="center"><b><i>Sign</i></b></td>
<td width="15%" align="center"><b><i>Sizes in bits (n)</i></b></td>
<td width="49%" align="center"><b><i>Alignment</i></b></td>
</tr>
<tr>
<td width="18%"><code>big_int</code><i><b>n</b></i><code>_buf_t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">16,32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">16,32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>big_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>big_int</code><b><i>n</i></b><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>big_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>big_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>big</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">16,32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">16,32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>little_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>little_int</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>little_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>little_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>little</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>native_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>t</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>yes</code></td>
</tr>
<tr>
<td width="18%"><code>native_int</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>native_uint</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="10%" align="center">unsigned</td>
<td width="15%">8,16,24,32,40,48,56,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
<tr>
<td width="18%"><code>native_float</code><i><b>n</b></i><code>_</code><code>buf_</code><code>ut</code></td>
<td width="10%" align="center"><code>native</code></td>
<td width="10%" align="center">signed</td>
<td width="15%">32,64</td>
<td width="49%" align="center"><code>no</code></td>
</tr>
</table>
</blockquote>
<p>The unaligned types do not cause compilers to insert padding bytes in classes
and structs. This is an important characteristic that can be exploited to minimize wasted space in
memory, files, and network transmissions. </p>
<p><font color="#FF0000"><b><i><span style="background-color: #FFFFFF">Warning:</span></i></b></font><span style="background-color: #FFFFFF">
Code that uses a</span>ligned types is possibly non-portable because alignment
requirements vary between hardware architectures and because alignment may be
affected by compiler switches or pragmas. For example, alignment of an 64-bit
integer may be to a 32-bit boundary on a 32-bit machine. Furthermore, aligned types
are only available on architectures with 16, 32, and 64-bit integer types. </p>
<p><b><i>Note:</i></b> One-byte types
have identical
functionality. They are provided to improve code readability and searchability.</p>
<h2><a name="Class_template_endian">Class template <code>endian</code></a><code>_buffer</code></h2>
<p>An <code>endian_buffer</code> is an integer byte-holder with user-specified <a href="#endianness">
endianness</a>, value type, size, and <a href="#alignment">alignment</a>. The
usual operations on integers are supplied.</p>
<h3><a name="Synopsis">Synopsis</a></h3>
<pre>namespace boost
{
namespace endian
{
// C++11 features emulated if not available
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>};
enum class <a name="alignment">align</a> {no, yes};
template &lt;order Order, class T, std::size_t Nbits, align Align = align::no&gt;
class endian_buffer
{
public:
typedef T value_type;
<a href="#endian">endian_buffer</a>() noexcept = default;
explicit <a href="#explicit-endian">endian_buffer</a>(T v) noexcept;
endian_buffer&amp; <a href="#operator-eq">operator=</a>(T v) noexcept;
value_type <a href="#value">value</a>() const noexcept;
const char* <a href="#data">data</a>() const noexcept;
protected:
<b><i>implementaton-defined</i></b> endian_value; // for exposition only
};
// typedefs
// aligned big endian floating point buffers
typedef endian_buffer&lt;order::big, float, 32, align::yes&gt; big_float32_buf_t;
typedef endian_buffer&lt;order::big, double, 64, align::yes&gt; big_float64_buf_t;
// aligned little endian floating point buffers
typedef endian_buffer&lt;order::little, float, 32, align::yes&gt; little_float32_buf_t;
typedef endian_buffer&lt;order::little, double, 64, align::yes&gt; little_float64_buf_t;
// unaligned big endian floating point buffers
typedef endian_buffer&lt;order::big, float, 32, align::no&gt; big_float32_buf_ut;
typedef endian_buffer&lt;order::big, double, 64, align::no&gt; big_float64_buf_ut;
// unaligned little endian floating point buffers
typedef endian_buffer&lt;order::little, float, 32, align::no&gt; little_float32_buf_ut;
typedef endian_buffer&lt;order::little, double, 64, align::no&gt; little_float64_buf_ut;
// aligned big endian signed integer buffers
typedef endian_buffer&lt;order::big, int16_t, 16, align::yes&gt; big_int16_buf_t;
typedef endian_buffer&lt;order::big, int32_t, 32, align::yes&gt; big_int32_buf_t;
typedef endian_buffer&lt;order::big, int64_t, 64, align::yes&gt; big_int64_buf_t;
// aligned big endian unsigned integer buffers
typedef endian_buffer&lt;order::big, uint16_t, 16, align::yes&gt; big_uint16_buf_t;
typedef endian_buffer&lt;order::big, uint32_t, 32, align::yes&gt; big_uint32_buf_t;
typedef endian_buffer&lt;order::big, uint64_t, 64, align::yes&gt; big_uint64_buf_t;
// aligned little endian signed integer buffers
typedef endian_buffer&lt;order::little, int16_t, 16, align::yes&gt; little_int16_buf_t;
typedef endian_buffer&lt;order::little, int32_t, 32, align::yes&gt; little_int32_buf_t;
typedef endian_buffer&lt;order::little, int64_t, 64, align::yes&gt; little_int64_buf_t;
// aligned little endian unsigned integer buffers
typedef endian_buffer&lt;order::little, uint16_t, 16, align::yes&gt; little_uint16_buf_t;
typedef endian_buffer&lt;order::little, uint32_t, 32, align::yes&gt; little_uint32_buf_t;
typedef endian_buffer&lt;order::little, uint64_t, 64, align::yes&gt; little_uint64_buf_t;
// aligned native endian typedefs are not provided because
// &lt;cstdint&gt; types are superior for this use case
// unaligned big endian signed integer buffers
typedef endian_buffer&lt;order::big, int_least8_t, 8&gt; big_int8_buf_ut;
typedef endian_buffer&lt;order::big, int_least16_t, 16&gt; big_int16_buf_ut;
typedef endian_buffer&lt;order::big, int_least32_t, 24&gt; big_int24_buf_ut;
typedef endian_buffer&lt;order::big, int_least32_t, 32&gt; big_int32_buf_ut;
typedef endian_buffer&lt;order::big, int_least64_t, 40&gt; big_int40_buf_ut;
typedef endian_buffer&lt;order::big, int_least64_t, 48&gt; big_int48_buf_ut;
typedef endian_buffer&lt;order::big, int_least64_t, 56&gt; big_int56_buf_ut;
typedef endian_buffer&lt;order::big, int_least64_t, 64&gt; big_int64_buf_ut;
// unaligned big endian unsigned integer buffers
typedef endian_buffer&lt;order::big, uint_least8_t, 8&gt; big_uint8_buf_ut;
typedef endian_buffer&lt;order::big, uint_least16_t, 16&gt; big_uint16_buf_ut;
typedef endian_buffer&lt;order::big, uint_least32_t, 24&gt; big_uint24_buf_ut;
typedef endian_buffer&lt;order::big, uint_least32_t, 32&gt; big_uint32_buf_ut;
typedef endian_buffer&lt;order::big, uint_least64_t, 40&gt; big_uint40_buf_ut;
typedef endian_buffer&lt;order::big, uint_least64_t, 48&gt; big_uint48_buf_ut;
typedef endian_buffer&lt;order::big, uint_least64_t, 56&gt; big_uint56_buf_ut;
typedef endian_buffer&lt;order::big, uint_least64_t, 64&gt; big_uint64_buf_ut;
// unaligned little endian signed integer buffers
typedef endian_buffer&lt;order::little, int_least8_t, 8&gt; little_int8_buf_ut;
typedef endian_buffer&lt;order::little, int_least16_t, 16&gt; little_int16_buf_ut;
typedef endian_buffer&lt;order::little, int_least32_t, 24&gt; little_int24_buf_ut;
typedef endian_buffer&lt;order::little, int_least32_t, 32&gt; little_int32_buf_ut;
typedef endian_buffer&lt;order::little, int_least64_t, 40&gt; little_int40_buf_ut;
typedef endian_buffer&lt;order::little, int_least64_t, 48&gt; little_int48_buf_ut;
typedef endian_buffer&lt;order::little, int_least64_t, 56&gt; little_int56_buf_ut;
typedef endian_buffer&lt;order::little, int_least64_t, 64&gt; little_int64_buf_ut;
// unaligned little endian unsigned integer buffers
typedef endian_buffer&lt;order::little, uint_least8_t, 8&gt; little_uint8_buf_ut;
typedef endian_buffer&lt;order::little, uint_least16_t, 16&gt; little_uint16_buf_ut;
typedef endian_buffer&lt;order::little, uint_least32_t, 24&gt; little_uint24_buf_ut;
typedef endian_buffer&lt;order::little, uint_least32_t, 32&gt; little_uint32_buf_ut;
typedef endian_buffer&lt;order::little, uint_least64_t, 40&gt; little_uint40_buf_ut;
typedef endian_buffer&lt;order::little, uint_least64_t, 48&gt; little_uint48_buf_ut;
typedef endian_buffer&lt;order::little, uint_least64_t, 56&gt; little_uint56_buf_ut;
typedef endian_buffer&lt;order::little, uint_least64_t, 64&gt; little_uint64_buf_ut;
// unaligned native endian signed integer types
typedef <b><i>implementation-defined</i></b>_int8_buf_ut native_int8_buf_ut;
typedef <b><i>implementation-defined</i></b>_int16_buf_ut native_int16_buf_ut;
typedef <b><i>implementation-defined</i></b>_int24_buf_ut native_int24_buf_ut;
typedef <b><i>implementation-defined</i></b>_int32_buf_ut native_int32_buf_ut;
typedef <b><i>implementation-defined</i></b>_int40_buf_ut native_int40_buf_ut;
typedef <b><i>implementation-defined</i></b>_int48_buf_ut native_int48_buf_ut;
typedef <b><i>implementation-defined</i></b>_int56_buf_ut native_int56_buf_ut;
typedef <b><i>implementation-defined</i></b>_int64_buf_ut native_int64_buf_ut;
// unaligned native endian unsigned integer types
typedef <b><i>implementation-defined</i></b>_uint8_buf_ut native_uint8_buf_ut;
typedef <b><i>implementation-defined</i></b>_uint16_buf_ut native_uint16_buf_ut;
typedef <b><i>implementation-defined</i></b>_uint24_buf_ut native_uint24_buf_ut;
typedef <b><i>implementation-defined</i></b>_uint32_buf_ut native_uint32_buf_ut;
typedef <b><i>implementation-defined</i></b>_uint40_buf_ut native_uint40_buf_ut;
typedef <b><i>implementation-defined</i></b>_uint48_buf_ut native_uint48_buf_ut;
typedef <b><i>implementation-defined</i></b>_uint56_buf_ut native_uint56_buf_ut;
typedef <b><i>implementation-defined</i></b>_uint64_buf_ut native_uint64_buf_ut;
} // namespace endian
} // namespace boost</pre>
<p>The <i><b><code>implementation-defined</code></b></i> text in typedefs above is either
<code>big</code> or <code>little</code> according to the native endianness of the
platform.</p>
<p>The expository data member <code>endian_value</code> stores the current value
of an <code>endian_value</code> object as a sequence of bytes ordered as
specified by the <code>Order</code> template parameter.&nbsp; The <i><b><code>
implementation-defined</code></b></i> type of <code>endian_value</code> is a
type such as <code><span style="font-size: 85%">char[Nbits/CHAR_BIT]</span></code>
or <code><span style="font-size: 85%">T</span></code> that meets the
requirements imposed by the <code>Nbits</code> and <code>Align</code> template
parameters.&nbsp; The <code><span style="font-size: 85%">CHAR_BIT</span></code>
macro is defined in <code><span style="font-size: 85%">&lt;climits&gt;</span></code>.
The only value of <code><span style="font-size: 85%">CHAR_BIT</span></code> that
is required to be supported is 8.</p>
<p>Template parameter <code><span style="font-size: 85%">T</span></code> is
required to be a standard integer type (C++std, 3.9.1) and <code>
<span style="font-size: 85%">sizeof(T)*CHAR_BIT</span></code> is required to be
greater or equal to <span style="font-size: 85%"> <code>Nbits</code>.</span></p>
<h3><a name="Members">Members</a></h3>
<pre><code><a name="endian">endian</a>_buffer() noexcept = default;</code></pre>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>endian_buffer&lt;Order, T,
Nbits, Align&gt;</code>.</p>
</blockquote>
<pre><code>explicit <a name="explicit-endian">endian</a>_buffer(T v) noexcept;</code></pre>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>endian_buffer&lt;Order, T,
Nbits, Align&gt;</code>.</p>
<p><i>Postcondition:</i> <code>value() == v &amp; mask</code>, where <code>mask</code>
is a constant of type <code>value_type</code> with <code>Nbits</code> low-order
bits set to one.</p>
<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then
endianness conversion if required is performed by <code>
boost::endian::endian_reverse</code>.</p>
</blockquote>
<pre><code>endian_buffer&amp; <a name="operator-eq">operator=</a>(T v) noexcept;</code></pre>
<blockquote>
<p><i>Postcondition:</i> <code>value() == v &amp; mask</code>, where <code>mask</code>
is a constant of type <code>value_type</code> with <code>Nbits</code>
low-order bits set to one..</p>
<p><i>Returns:</i> <code>*this</code>.</p>
<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then
endianness conversion if required is performed by <code>
boost::endian::endian_reverse</code>.</p>
</blockquote>
<pre>value_type <a name="value">value</a>()<code> const noexcept;</code></pre>
<blockquote>
<p><i>Returns:</i> <code>endian_value</code>, converted to <code>value_type</code>
if necessary and having the endianness of the native platform.</p>
<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then
endianness conversion if required is performed by <code>
boost::endian::endian_reverse</code>.</p>
</blockquote>
<pre><code>const char* <a name="data">data</a>() const noexcept;</code></pre>
<blockquote>
<p><i>Returns:</i> A pointer to the first byte of <code>endian_value</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 not just use Boost.Serialization?</b> Serialization involves a
conversion for every object involved in I/O. Endian integers require no
conversion or copying. They are already in the desired format for binary I/O.
Thus they can be read or written in bulk.</p>
<p><b>Are endian types POD's?</b> Yes for C++11. No for C++03, although several
<a href="#Compilation">macros</a> are available to force PODness in all cases.</p>
<p><b>What are the implications of endian integer types not being POD's with C++03
compilers?</b> They
can't be used in unions. Also, compilers aren't required to align or lay
out storage in portable ways, although this potential problem hasn't prevented
use of Boost.Endian with
real compilers.</p>
<p><b>What good is <i>native </i>endianness?</b> It provides alignment and
size guarantees not available from the built-in types. It eases generic
programming.</p>
<p><b>Why bother with the aligned endian types?</b> Aligned integer operations
may be faster (as much as 10 to 20 times faster) if the endianness and alignment of
the type matches the endianness and alignment requirements of the machine. The code,
however, is
likely to be somewhat less portable than with the unaligned types.</p>
<p><b>Why provide the arithmetic operations?</b> Providing a full set of operations reduces program
clutter and makes code both easier to write and to read. Consider
incrementing a variable in a record. It is very convenient to write:</p>
<pre wrap> ++record.foo;</pre>
<p wrap>Rather than:</p>
<pre wrap> int temp(record.foo);
++temp;
record.foo = temp;</pre>
<h2><a name="Design">Design</a> considerations for Boost.Endian buffers</h2>
<ul>
<li>Must be suitable for I/O - in other words, must be memcpyable.</li>
<li>Must provide exactly the size and internal byte ordering specified.</li>
<li>Must work correctly when the internal integer representation has more bits
that the sum of the bits in the external byte representation. Sign extension
must work correctly when the internal integer representation type has more
bits than the sum of the bits in the external bytes. For example, using
a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for
both positive and negative values.</li>
<li>Must work correctly (including using the same defined external
representation) regardless of whether a compiler treats char as signed or
unsigned.</li>
<li>Unaligned types must not cause compilers to insert padding bytes.</li>
<li>The implementation should supply optimizations with great care. Experience has shown that optimizations of endian
integers often become pessimizations when changing
machines or compilers. Pessimizations can also happen when changing compiler switches,
compiler versions, or CPU models of the same architecture.</li>
</ul>
<h2><a name="C++0x">C++11</a></h2>
<p>The availability of the C++11
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
Defaulted Functions</a> feature is detected automatically, and will be used if
present to ensure that objects of <code>class endian</code> are trivial, and
thus POD's.</p>
<h2><a name="Compilation">Compilation</a></h2>
<p>Boost.Endian is implemented entirely within headers, with no need to link to
any Boost object libraries.</p>
<p>Several macros allow user control over features:</p>
<ul>
<li>BOOST_ENDIAN_NO_CTORS causes <code>class endian</code> to have no
constructors. The intended use is for compiling user code that must be
portable between compilers regardless of C++11
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
Defaulted Functions</a> support. Use of constructors will always fail, <br>
&nbsp;</li>
<li>BOOST_ENDIAN_FORCE_PODNESS causes BOOST_ENDIAN_NO_CTORS to be defined if
the compiler does not support C++11
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">
Defaulted Functions</a>. This is ensures that , and so can be used in unions.
In C++11, <code>class endian</code> objects are POD's even though they have
constructors.</li>
</ul>
<hr>
<p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->06 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38644" --></p>
<p>© Copyright Beman Dawes, 2006-2009, 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>

View File

@@ -5,13 +5,8 @@
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Boost Endian Conversion Functions</title>
<style type="text/css">
ins {background-color:#CCFFCC}
del {background-color:#FFCACA}
body { font-family: sans-serif; width:8.0in; }
pre { background-color:#D7EEFF }
</style>
<title>Endian Conversion Functions</title>
<link href="styles.css" rel="stylesheet">
</head>
<body>
@@ -20,10 +15,10 @@
<tr>
<td>
<a href="../../../index.html">
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="277" height="86" border="0"></a></td>
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" border="0" width="277" height="86" ></a></td>
<td align="middle">
<font size="7">Endian Conversion<br>
Functions</font></td>
<b>
<font size="6">Endian Conversion Functions</font></b></td>
</tr>
</table>
@@ -32,7 +27,8 @@
<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="types.html">Endian Types</a></b></td>
<a href="arithmetic.html">Arithmetic Types</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="buffers.html">Buffer Types</a></b></td>
</tr>
</table>
@@ -49,7 +45,10 @@
<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; <a href="#Functions">Functions</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>
@@ -60,7 +59,8 @@
<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/types.hpp">&lt;boost/endian/types.hpp&gt;</a></td>
<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>
@@ -68,7 +68,7 @@
<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 multi-byte built-in
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>
@@ -77,9 +77,12 @@ ordering. User defined types are also supported.</p>
<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>
Boost scoped enum emulation is used so that the library still works for compilers that do not support scoped enums.</p>
<p>&nbsp;</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;
@@ -90,255 +93,290 @@ 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>
big, // big endian
little, // little endian
native = <b><i>implementation-defined-as-big-or-little
</i></b>};
// reverse byte order (i.e. endianness)
int8_t <a href="#reverse_value">reverse_value</a>(int8_t x) noexcept;
int16_t <a href="#reverse_value">reverse_value</a>(int16_t x) noexcept;
int32_t <a href="#reverse_value">reverse_value</a>(int32_t x) noexcept;
int64_t <a href="#reverse_value">reverse_value</a>(int64_t x) noexcept;
uint8_t <a href="#reverse_value">reverse_value</a>(uint8_t x) noexcept;
uint16_t <a href="#reverse_value">reverse_value</a>(uint16_t x) noexcept;
uint32_t <a href="#reverse_value">reverse_value</a>(uint32_t x) noexcept;
uint64_t <a href="#reverse_value">reverse_value</a>(uint64_t x) noexcept;
float <a href="#reverse_value">reverse_value</a>(float x) noexcept;
double <a href="#reverse_value">reverse_value</a>(double x) noexcept;
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 &lt;class Value&gt;
void <a href="#reverse">reverse</a>(Value&amp; 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;
// 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;
// synonyms, based on names popularized by BSD (e.g. OS X, Linux) endian.h
// &quot;h&quot; for &quot;host&quot; (i.e. native), &quot;be&quot; for &quot;big endian&quot;,
// &quot;le&quot; for &quot;little endian&quot;, &quot;m&quot; for &quot;modify&quot; in place
template &lt;class T&gt; T bswap(T x) noexcept {return reverse_value(x);}
template &lt;class T&gt; T htobe(T host) noexcept {return big_endian_value(host);}
template &lt;class T&gt; T htole(T host) noexcept {return little_endian_value(host);}
template &lt;class T&gt; T betoh(T big) noexcept {return big_endian_value(big);}
template &lt;class T&gt; T letoh(T little) noexcept {return little_endian_value(little);}
template &lt;class T&gt; void bswapm(T&amp; x) noexcept {reverse(x);}
template &lt;class T&gt; void htobem(T&amp; host) noexcept {big_endian(host);}
template &lt;class T&gt; void htole(mT&amp; host noexcept) {little_endian(host);}
template &lt;class T&gt; void betohm(T&amp; big) noexcept {big_endian(big);}
template &lt;class T&gt; void letohm(T&amp; little) noexcept {little_endian(little);}
// 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 effective byte order determination
order <a href="#effective_order">effective_order</a>(order 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;
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>The <i><b><code>implementation-defined</code></b></i> text above is either
<code>big</code> or <code>little</code> according to the endianness of the
platform.</p>
<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>,
and the floating point types <code>float</code> and <code>double</code> are
collectively called the <i>endian types</i>.</p>
<h3><a name="Requirements">Requirements</a></h3>
<p>The template definitions in this header refer to named
requirements whose details are set out in this section. User defined types may
be used in the function templates in this header only if they meet the
function's template parameter requirements.</p>
<h4><a name="ReversibleValue">ReversibleValue</a> requirements</h4>
<p><code>ReversibleValue</code> is an object 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>
<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 width="160"><b>Expression</b></td>
<td width="150"><b>Return type</b></td>
<td width="347"><b>Requirement</b></td>
<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 valign="top">
<p><code>reverse_value(x)</code></td>
<td valign="top">
<p><code>ReversibleValue</code></td>
<td>
<p>The returned value is the value of <code>x</code> with the
order of its constituent bytes reversed.</td>
<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 an 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>
<h4><a name="Reversible">Reversible</a> requirements</h4>
<p><code>Reversible</code> is an object type to be
supplied by a C++ program instantiating a template; <code>x</code> is a
modifiable lvalue of type <code>Reversible</code>.</p>
<p>&nbsp;</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>
<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 valign="top">
<p><code>reverse(x)</code></td>
<td>
<p>The order of the constituent bytes of <code>x</code> are
reversed.</td>
<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 an 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 dir="ltr">See <a href="../example/udt_conversion_example.cpp">
udt_conversion_example.cpp</a> for an example of a UDT that can used in the
<code><a href="#big_endian">big_endian</a></code>, <code>
<a href="#little_endian">little_endian</a></code>, and <code>
<a href="#convert_generic">convert</a></code> function templates.</p>
<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 improved 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 <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_value"></a>int8_t reverse_value(int8_t x) noexcept;
int16_t reverse_value(int16_t x) noexcept;
int32_t reverse_value(int32_t x) noexcept;
int64_t reverse_value(int64_t x) noexcept;
uint8_t reverse_value(uint8_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>
<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
<p dir="ltr"><i>Returns:</i> <i><code>x</code></i>, with the order of its
constituent bytes reversed.</p>
<p><i>Remarks:</i> Meet 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><a name="reverse"></a>template &lt;class Value&gt;
void reverse(Value&amp; x) noexcept;</pre>
<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>Postconditions:</i> The order of the constituent bytes of
<code>x</code> are reversed.</p>
<p><i>Returns:</i> <code>conditional_reverse&lt;order::native, order::big&gt;(x)</code>.</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>
<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>Returns (first form)</i>: <code>x</code> if the native byte order is big
endian, otherwise <code>reverse_value(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>
<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>Returns (first form)</i>: <code>x</code> if the native byte order is little
endian, otherwise <code>reverse_value(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>
<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>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_value(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="effective_order"></a>order effective_order(order x) noexcept;
</pre>
<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>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><i>Example:</i></p><blockquote><pre>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><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_value(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>
<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 the template versions of <code>reverse()</code> and <code>reverse_value()</code>
in a detail namespace?</b></p>
<blockquote>
<p>They are unsafe for general use. Consider reversing
the bytes of a <code>std::pai<b>r</b></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
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 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_value()</code> and templated
<code>reverse()</code> implementations.</p>
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 -->12 August, 2014<!--webbot bot="Timestamp" endspan i-checksum="34569" --></p>
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->16 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38645" --></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>

View File

@@ -5,24 +5,20 @@
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Boost Endian Library</title>
<style type="text/css">
ins {background-color:#CCFFCC}
del {background-color:#FFCACA}
body { font-family: sans-serif; width:8.0in; }
pre { background-color:#D7EEFF }
</style>
<title>Endian Library</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>
<td width="339">
<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">
<font size="7">Endian Library</font></td>
<td align="middle" width="1253">
<b>
<font size="6">Endian Library</font></b></td>
</tr>
</table>
@@ -31,7 +27,8 @@
<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="types.html">Endian Types</a></b></td>
<a href="arithmetic.html">Arithmetic Types</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="buffers.html">Buffer Types</a></b></td>
</tr>
</table>
<p></p>
@@ -61,24 +58,37 @@
<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/types.hpp">&lt;boost/endian/types.hpp&gt;</a></td>
<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="Abstract">Abstract</a></h2>
<p>Boost.Endian provides facilities to manipulate the endianness of integers,
floating point, and user defined data.</p>
<p>Boost.Endian provides facilities to manipulate the
<a href="#Introduction-to-endianness">endianness</a> of integers,
floating point numbers, and user-defined types.</p>
<ul>
<li>The primary use case is binary I/O for portable data exchange with
other systems, via either external media or network transmission.<br>
<li>Primary use cases:<br>
&nbsp;<ul>
<li>Data portability. The Endian library supports binary data exchange, via either external media or network transmission,
regardless of platform endianness.<br>
&nbsp;</li>
<li>A second use case is minimizing storage size via sizes and/or
alignments not supported by the built-in types.<br>
<li>Program portability. POSIX-based and
Windows-based operating systems traditionally supply libraries with
non-portable functions to perform endian conversion. There are at least four
non-compatible sets of functions in common use. The Endian library is
portable across all C++ platforms.<br>
&nbsp;</li>
<li>Two distinct approaches to dealing with endianness are provided. Each approach has a
</ul>
</li>
<li>Secondary use case: Minimizing storage size via sizes and/or alignments not supported by the
standard C++ arithmetic types.<br>
<br></li>
<li>Three approaches to dealing with endianness are provided. Each approach has a
long history of successful use, and each approach has use cases where it is
superior to the other approach.</li>
preferred over the other approaches.</li>
</ul>
<h2><a name="Introduction-to-endianness">Introduction to endianness</a></h2>
@@ -116,102 +126,199 @@ at different ends.</p>
<p>See the Wikipedia's
<a href="http://en.wikipedia.org/wiki/Endianness">Endianness</a> article for an
extensive discussion of endianness.</p>
<p>Most programmers can ignore endianness, except perhaps for reading a core
dump on little-endian systems. Programmers have to deal with endianness in their
code when exchanging binary integers and binary floating point
values between computer systems with differing endianness, whether by physical file transfer or over a network,
. </p>
<p>Programmers can usually ignore endianness, except when reading a core
dump on little-endian systems. But programmers have to deal with endianness when exchanging binary integers and binary floating point
values between computer systems with differing endianness, whether by physical file transfer or over a network.
And programmers may also want to use the library when minimizing either internal or
external data sizes is advantageous.</p>
<h2><a name="Introduction">Introduction</a> to the Boost.Endian library</h2>
<p>The Boost.Endian library provides two different approaches to dealing with
integer endianness. Both approaches support integers, floating point types
except&nbsp; <code>long double</code>, and user defined types (UDTs).</p>
<p>The Boost.Endian library provides three different approaches to dealing with
endianness. All three approaches support integers, floating point types
except&nbsp; <code>long double</code>, and user-define types (UDTs).</p>
<p>Each approach has a long history of successful use, and each approach has use
cases where it is superior to the other approach.</p>
cases where it is preferred to the other approaches.</p>
<blockquote>
<p><b><a href="types.html">Endian types</a> -</b> The application uses the provided endian types
which mimic the
built-in integer types. For example, <code>big_int32_t</code> or <code>little_float64_t</code>.
Integer types with lengths of 1 through 8 bytes are supported, rather than just
2, 4, and 8 byte integers. The types may be aligned or unaligned.</p>
<p><b><a href="conversion.html">Endian conversion functions</a> -</b> The
application uses the built-in integer and floating point types, and calls the
application uses the built-in integer and floating point types to hold values, and calls the
provided conversion functions to convert byte ordering as needed. Both mutating
and non-mutating conversions are supplied, and each comes in unconditional and
conditional variants.</p>
<p><b><a href="buffers.html">Endian buffer types</a> -</b> The application uses the provided endian
buffer types
to hold values, and explicitly converts to and from the built-in integer and
floating point types to perform arithmetic. Buffer lengths of 1 through 8 bytes
are supported, rather than just 2, 4, and 8 bytes. The types may be aligned or
unaligned.</p>
<p><b><a href="arithmetic.html">Endian arithmetic types</a> -</b> The application uses the provided endian
arithmetic types, which supply the same operations as the built-in C++
arithmetic types. All conversions are implicit. Arithmetic integer types with
lengths of 1 through 8 bytes are supported, rather than just 2, 4, and 8 byte
integers. The types may be aligned.</p>
</blockquote>
<p>Boost Endian is a header-only library.</p>
<h2><a name="Choosing">Choosing</a> between endian types and endian
conversion functions</h2>
<h2><a name="Choosing">Choosing</a> between endian conversion functions, endian buffer types,
and endian arithmetic types</h2>
<p>Which approach is better for dealing with endianness depends on
application needs.</p>
<p>The best approach to endianness depends on interaction between
the approach characteristics and
the application needs.</p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr>
<th colspan="2">Needs that favor one approach over the other</th>
</tr>
<tr>
<th width="50%"><b><a href="types.html">Endian types</a> may be better for
these needs</b></th>
<th><b><a href="conversion.html">Endian conversion functions</a> may be
better for
these needs</b></th>
</tr>
<tr>
<td valign="top">
<ul>
<li><p>A need to simplify program logic and eliminate logic
errors. Since the endian types mimic the built-in types, there is no need to reason about the current endianness of variables
and that can simplify program logic and eliminate logic errors.</p></li>
<li><p>A need to use unusual integer sizes (i.e. 3, 5,
6, or 7 bytes) to reduce internal and external space usage and
save I/O time.</li>
<li><p>A need to use unaligned variables. Endian types can eliminate padding bytes in
structures, reducing internal and external space usage and saving I/O
time. They can deals with structures defined like this:
<h3><a name="Approach-characteristics">Approach characteristics</a></h3>
<p>The characteristics that differentiate the approaches are the endianness
invariants, conversion explicitness, arithmetic operations, sizes available, and
alignment requirements.</p>
<h4>Endianness invariants</h4>
<blockquote>
<p><b>Endian conversion functions</b> use objects of the ordinary C++ arithmetic
types like <code>int</code> or <code>unsigned short</code> to hold values. That
breaks the implicit invariant that the C++ language rules apply. The usual
language rules only apply if the endianness of the object is currently set by
the conversion functions to the native endianness for the platform. That can
make it very hard to reason about complex logic flow, and result in difficult to
find bugs.</p>
<p><b>Endian buffer and arithmetic types</b> hold values internally as arrays of
characters with an invariant that the endianness of the array never changes.
That makes these types easy to use and programs easy to maintain.</p>
</blockquote>
<h4>Conversion explicitness</h4>
<blockquote>
<p><b>Endian conversion functions</b> and <b>buffer types</b> never perform
implicit conversions. This gives users explicit control of when conversion
occurs, and may help avoid unnecessary conversions.</p>
<p><b>Endian arithmetic types</b> perform conversion implicitly. That makes
these types very easy to use, but can result in unnecessary conversions. Failure
to hoist conversions out of inner loops can bring a performance penalty.</p>
</blockquote>
<h4>Arithmetic operations</h4>
<blockquote>
<p><b>Endian conversion functions</b> do not supply arithmetic
operations, but this is not a concern since this approach uses ordinary C++
arithmetic types to hold values.</p>
<p><b>Endian buffer types</b> do not supply arithmetic operations. Although this
approach avoids unnecessary conversions, it can result in the introduction of
additional variables and confuse maintenance programmers.</p>
<p><b>Endian</b> <b>arithmetic types</b> do supply arithmetic operations. They
are very easy to use if lots of arithmetic is involved. </p>
</blockquote>
<h4>Sizes available</h4>
<blockquote>
<p><b>Endianness conversion functions</b> only support 1, 2, 4, and 8 byte
integers. That&#39;s sufficient for many applications.</p>
<p><b>Endian buffer and arithmetic types</b> support 1, 2, 3, 4, 5, 6, 7, and 8
byte integers. For an application where memory use or I/O speed is the limiting
factor, using sizes tailored to application needs can be useful.</p>
</blockquote>
<h4>Alignments available</h4>
<blockquote>
<p><b>Endianness conversion functions</b> only support aligned integer and
floating-point types. That&#39;s sufficient for most applications.</p>
<p><b>Endian buffer and arithmetic types</b> support both aligned and unaligned
integer and floating-point types. Unaligned types are rarely needed, but when
needed they are often very useful and workarounds are painful. For example,</p>
<blockquote>
<p>Non-portable code like this:<blockquote>
<p><code>struct S {<br>
&nbsp; uint16_t a;&nbsp; // big endian<br>
&nbsp; uint32_t b;&nbsp; // big endian<br>
} __attribute__ ((packed));</code>
</p></blockquote>
<p>Can be replaced with portable code like this:</p>
<blockquote>
<p><code>struct S {<br>
&nbsp; uint16_t a;<br>
&nbsp; uint32_t b;<br>
} __attribute__ ((packed));</code>
</blockquote></p></li>
<li>
<p>Programmer preference.</p></li>
</ul>
</td>
<td valign="top">
<ul>
<li><p>A need to leverage knowledge of developers who have been using C byte
swapping
functions for years.</p></li>
<li>A need to save CPU time when a variable is used many times
relative to its I/O.</li>
<li>
<p>A need to pass structures to third-party libraries expecting a
specific structure format.</li>
<li>
<p>Programmer preference.</li>
</ul>
</td>
</tr>
</table>
&nbsp; big_uint16_ut a;<br>
&nbsp; big_uint32_ut b;<br>
};</code>
</p></blockquote>
</blockquote>
</blockquote>
<h3><a name="Use-cases">Use cases</a></h3>
<h4>Program portability use case</h4>
<p>An existing large codebase runs on little-endian Linux systems. It already
deals with endianness via
<a href="http://man7.org/linux/man-pages/man3/endian.3.html">Linux provided
functions</a>. Because of a business merger, the codebase has to be quickly
modified for Windows and possibly other operating systems, while still
supporting Linux. The codebase is reliable and the programmers are all
well-aware of endian issues. </p>
<p>These factors all argue for an <a href="conversion.html">endian conversion
approach</a> that just mechanically changes the calls to <code>htobe32</code>,
etc. to <code>boost::endian::native_to_big</code>, etc. and replaces <code>&lt;endian.h&gt;</code>
with <code>&lt;boost/endian/conversion.hpp&gt;</code>.</p>
<h4>Reliability and arithmetic-speed use case</h4>
<p>A new, complex, multi-threaded application is to be developed that must run
on little endian machines, but do big endian network I/O. The developers believe
computational speed for endian variable is critical but have seen numerous bugs
result from inability to reason about endian conversion state. They are also
worried that future maintenance changes could inadvertently introduce a lot of
slow conversions if full-blown endian arithmetic types are used.</p>
<p>The <a href="buffers.html">endian buffers</a> approach is made-to-order for
this use case.</p>
<h4>Reliability and ease-of-use use case</h4>
<p>A new, complex, multi-threaded application is to be developed that must run
on little endian machines, but do big endian network I/O. The developers believe
computational speed for endian variables is <b>not critical</b> but have seen
numerous bugs result from inability to reason about endian conversion state.
They are also concerned about ease-of-use both during development and long-term
maintenance.</p>
<p>Removing concern about conversion speed and adding concern about ease-of-use
tips the balance strongly in favor the <a href="arithmetic.html">endian
arithmetic approach</a>.</p>
<h2>Built-in support for <a name="Intrinsic">Intrinsic</a>s</h2>
<p>Recent compilers, including GCC, Clang, and Microsoft, supply built-in support for byte swapping
intrinsics. Such support is automatically detected and
used since it may in smaller and faster generated code, particularly for release
<p>Supply compilers, including GCC, Clang, and Visual C++, supply built-in support for byte swapping intrinsics.
The library uses these intrinsics when available since they may result in smaller and faster generated code, particularly for release
builds.</p>
<p>Defining <code>BOOST_ENDIAN_NO_INTRINSICS</code> will suppress use
of the intrinsics. Please try defining it if you get compiler errors, such as
header byteswap.h not being found.</p>
of the intrinsics. Useful when intrinsic headers such as
<code>byteswap.h </code>are not being found on your platform.</p>
<p>The macro <code>BOOST_ENDIAN_INTRINSIC_MSG</code> is defined as
either <code>&quot;no byte swap intrinsics&quot;</code> or a string describing the
particular set of intrinsics being used.</p>
@@ -230,8 +337,8 @@ particular set of intrinsics being used.</p>
result to a file</i> </b> </td>
</tr>
<tr>
<td><i><b>Endian type approach</b></i></td>
<td><i><b>Endian conversion approach</b></i></td>
<td><i><b>Endian arithmetic type approach</b></i></td>
<td><i><b>Endian conversion function approach</b></i></td>
</tr>
<tr>
<td valign="top">
@@ -250,9 +357,9 @@ int32_t x;
... read into x from a file ...
big_endian(x);
big_to_native_inplace(x);
x += 100;
big_endian(x);
native_to_big_inplace(x);
... write x to a file ...
</pre>
@@ -264,7 +371,8 @@ big_endian(x);
release builds,
regardless of the native endianness of the machine.</b> That&#39;s because optimizing compilers will likely
generate exactly the same code for each. That conclusion was confirmed by
studying the generated assembly code for GCC and Visual C++.</p>
studying the generated assembly code for GCC and Visual C++. Furthermore, time
spent doing I/O will determine the speed of this application.</p>
<p>Now consider a slightly different problem:&nbsp; </p>
@@ -278,8 +386,8 @@ studying the generated assembly code for GCC and Visual C++.</p>
result to a file </b></i> </td>
</tr>
<tr>
<td><i><b>Endian type approach</b></i></td>
<td><i><b>Endian conversion approach</b></i></td>
<td><i><b>Endian arithmetic type approach</b></i></td>
<td><i><b>Endian conversion function approach</b></i></td>
</tr>
<tr>
<td valign="top">
@@ -298,12 +406,12 @@ for (int32_t i = 0; i &lt; 1000000; ++i)
... read into x from a file ...
big_endian(x);
big_to_native_inplace(x);
for (int32_t i = 0; i &lt; 1000000; ++i)
x += i;
big_endian(x);
native_to_big_inplace(x);
... write x to a file ...
</pre>
@@ -311,10 +419,10 @@ big_endian(x);
</tr>
</table>
<p>With the Endian type approach, an implicit conversion from and then back to
<p>With the Endian arithmetic approach, on little endian platforms an implicit conversion from and then back to
big endian is done inside the loop. With the Endian conversion function
approach, the conversions are explicit, so only need to be done once, before and
after the loop.</p>
approach, the user has ensured the conversions are done outside the loop, so the
code may run more quickly on little endian platforms.</p>
<h3><a name="Timings">Timings</a> for Example 2 (conversion functions hoisted
out of loop)</h3>
@@ -331,201 +439,204 @@ setup.
32-bit intrinsics.)</p>
<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111">
<tr><td colspan="6" align="center" dir="ltr"><b><font size="2">GNU C++ version 4.7.0</font></b></td></tr>
<tr><td colspan="6" align="center" dir="ltr"><b> <font size="2">Iterations: 1000000000, Intrinsics: __builtin_bswap16, etc.</font></b></td></tr>
<tr><td dir="ltr"><b><font size="2">Test Case</font></b></td>
<td align="center" dir="ltr"><b><font size="2">Endian<br>type</font></b></td>
<td align="center" dir="ltr"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
<tr><td colspan="6" align="center"><b><font size="2">GNU C++ version 4.7.0</font></b></td></tr>
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: __builtin_bswap16, etc.</font></b></td></tr>
<tr><td><b><font size="2">Test Case</font></b></td>
<td align="center"><b><font size="2">Endian<br>arithmetic</font></b></td>
<td align="center"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
</tr>
<tr><td dir="ltr"><font size="2">16-bit aligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">1.37 s</font></td>
<td align="right" dir="ltr"><font size="2">0.81 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.83 s</font></td>
<td align="right" dir="ltr"><font size="2">0.81 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">1.09 s</font></td>
<td align="right" dir="ltr"><font size="2">0.83 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">1.09 s</font></td>
<td align="right" dir="ltr"><font size="2">0.81 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit aligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">0.98 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.28 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">3.82 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">3.82 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit aligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">1.65 s</font></td>
<td align="right" dir="ltr"><font size="2">0.41 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.41 s</font></td>
<td align="right" dir="ltr"><font size="2">0.41 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">17.53 s</font></td>
<td align="right" dir="ltr"><font size="2">0.41 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">17.52 s</font></td>
<td align="right" dir="ltr"><font size="2">0.41 s</font></td></tr>
<tr><td><font size="2">16-bit aligned big endian</font></td>
<td align="right"><font size="2">1.37 s</font></td>
<td align="right"><font size="2">0.81 s</font></td></tr>
<tr><td><font size="2">16-bit aligned little endian</font></td>
<td align="right"><font size="2">0.83 s</font></td>
<td align="right"><font size="2">0.81 s</font></td></tr>
<tr><td><font size="2">16-bit unaligned big endian</font></td>
<td align="right"><font size="2">1.09 s</font></td>
<td align="right"><font size="2">0.83 s</font></td></tr>
<tr><td><font size="2">16-bit unaligned little endian</font></td>
<td align="right"><font size="2">1.09 s</font></td>
<td align="right"><font size="2">0.81 s</font></td></tr>
<tr><td><b><font size="2">32-bit aligned big endian</font></b></td>
<td align="right"><b><font size="2">0.98 s</font></b></td>
<td align="right"><b><font size="2">0.27 s</font></b></td></tr>
<tr><td><font size="2">32-bit aligned little endian</font></td>
<td align="right"><font size="2">0.28 s</font></td>
<td align="right"><font size="2">0.27 s</font></td></tr>
<tr><td><font size="2">32-bit unaligned big endian</font></td>
<td align="right"><font size="2">3.82 s</font></td>
<td align="right"><font size="2">0.27 s</font></td></tr>
<tr><td><font size="2">32-bit unaligned little endian</font></td>
<td align="right"><font size="2">3.82 s</font></td>
<td align="right"><font size="2">0.27 s</font></td></tr>
<tr><td><font size="2">64-bit aligned big endian</font></td>
<td align="right"><font size="2">1.65 s</font></td>
<td align="right"><font size="2">0.41 s</font></td></tr>
<tr><td><font size="2">64-bit aligned little endian</font></td>
<td align="right"><font size="2">0.41 s</font></td>
<td align="right"><font size="2">0.41 s</font></td></tr>
<tr><td><font size="2">64-bit unaligned big endian</font></td>
<td align="right"><font size="2">17.53 s</font></td>
<td align="right"><font size="2">0.41 s</font></td></tr>
<tr><td><font size="2">64-bit unaligned little endian</font></td>
<td align="right"><font size="2">17.52 s</font></td>
<td align="right"><font size="2">0.41 s</font></td></tr>
<tr><td colspan="6" align="center" dir="ltr"><b> <font size="2">Iterations: 1000000000, Intrinsics: no byte swap intrinsics</font></b></td></tr>
<tr><td dir="ltr"><b><font size="2">Test Case</font></b></td>
<td align="center" dir="ltr"><b><font size="2">Endian<br>type</font></b></td>
<td align="center" dir="ltr"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: no byte swap intrinsics</font></b></td></tr>
<tr><td><b><font size="2">Test Case</font></b></td>
<td align="center"><b><font size="2">Endian<br>arithmetic</font></b></td>
<td align="center"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
</tr>
<tr><td dir="ltr"><font size="2">16-bit aligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">1.95 s</font></td>
<td align="right" dir="ltr"><font size="2">0.81 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.83 s</font></td>
<td align="right" dir="ltr"><font size="2">0.81 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">1.19 s</font></td>
<td align="right" dir="ltr"><font size="2">0.81 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">1.20 s</font></td>
<td align="right" dir="ltr"><font size="2">0.81 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit aligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">0.97 s</font></td>
<td align="right" dir="ltr"><font size="2">0.28 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td>
<td align="right" dir="ltr"><font size="2">0.28 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">4.10 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">4.10 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit aligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">1.64 s</font></td>
<td align="right" dir="ltr"><font size="2">0.42 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.41 s</font></td>
<td align="right" dir="ltr"><font size="2">0.41 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">17.52 s</font></td>
<td align="right" dir="ltr"><font size="2">0.42 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">17.52 s</font></td>
<td align="right" dir="ltr"><font size="2">0.41 s</font></td></tr>
<tr><td><font size="2">16-bit aligned big endian</font></td>
<td align="right"><font size="2">1.95 s</font></td>
<td align="right"><font size="2">0.81 s</font></td></tr>
<tr><td><font size="2">16-bit aligned little endian</font></td>
<td align="right"><font size="2">0.83 s</font></td>
<td align="right"><font size="2">0.81 s</font></td></tr>
<tr><td><font size="2">16-bit unaligned big endian</font></td>
<td align="right"><font size="2">1.19 s</font></td>
<td align="right"><font size="2">0.81 s</font></td></tr>
<tr><td><font size="2">16-bit unaligned little endian</font></td>
<td align="right"><font size="2">1.20 s</font></td>
<td align="right"><font size="2">0.81 s</font></td></tr>
<tr><td><b><font size="2">32-bit aligned big endian</font></b></td>
<td align="right"><b><font size="2">0.97 s</font></b></td>
<td align="right"><b><font size="2">0.28 s</font></b></td></tr>
<tr><td><font size="2">32-bit aligned little endian</font></td>
<td align="right"><font size="2">0.27 s</font></td>
<td align="right"><font size="2">0.28 s</font></td></tr>
<tr><td><font size="2">32-bit unaligned big endian</font></td>
<td align="right"><font size="2">4.10 s</font></td>
<td align="right"><font size="2">0.27 s</font></td></tr>
<tr><td><font size="2">32-bit unaligned little endian</font></td>
<td align="right"><font size="2">4.10 s</font></td>
<td align="right"><font size="2">0.27 s</font></td></tr>
<tr><td><font size="2">64-bit aligned big endian</font></td>
<td align="right"><font size="2">1.64 s</font></td>
<td align="right"><font size="2">0.42 s</font></td></tr>
<tr><td><font size="2">64-bit aligned little endian</font></td>
<td align="right"><font size="2">0.41 s</font></td>
<td align="right"><font size="2">0.41 s</font></td></tr>
<tr><td><font size="2">64-bit unaligned big endian</font></td>
<td align="right"><font size="2">17.52 s</font></td>
<td align="right"><font size="2">0.42 s</font></td></tr>
<tr><td><font size="2">64-bit unaligned little endian</font></td>
<td align="right"><font size="2">17.52 s</font></td>
<td align="right"><font size="2">0.41 s</font></td></tr>
</table>
<p></p>
<p><b>Comment:</b> Note that the <b><font size="2">32-bit aligned big endian </font></b>
timings are the same with or without intrinsics turned on. Presumably the
optimizer is recognizing the byte swapping and applying the intrinsics itself.</p>
<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111" dir="ltr">
<tr><td colspan="6" align="center" dir="ltr"><b><font size="2">Microsoft Visual C++ version 11.0</font></b></td></tr>
<tr><td colspan="6" align="center" dir="ltr"><b> <font size="2">Iterations: 1000000000, Intrinsics: cstdlib _byteswap_ushort, etc.</font></b></td></tr>
<tr><td dir="ltr"><b><font size="2">Test Case</font></b></td>
<td align="center" dir="ltr"><b><font size="2">Endian<br>type</font></b></td>
<td align="center" dir="ltr"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111">
<tr><td colspan="6" align="center"><b><font size="2">Microsoft Visual C++ version 11.0</font></b></td></tr>
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: cstdlib _byteswap_ushort, etc.</font></b></td></tr>
<tr><td><b><font size="2">Test Case</font></b></td>
<td align="center"><b><font size="2">Endian<br>type</font></b></td>
<td align="center"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
</tr>
<tr><td dir="ltr"><font size="2">16-bit aligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">0.83 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td>
<td align="right" dir="ltr"><font size="2">0.50 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">1.37 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">1.37 s</font></td>
<td align="right" dir="ltr"><font size="2">0.50 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit aligned big endian</font></td>
<td align="right" bgcolor="#CCFFCC" dir="ltr"><font size="2">0.81 s</font></td>
<td align="right" dir="ltr"><font size="2">0.50 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">2.98 s</font></td>
<td align="right" dir="ltr"><font size="2">0.53 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">3.00 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit aligned big endian</font></td>
<td align="right" bgcolor="#CCFFCC" dir="ltr"><font size="2">1.33 s</font></td>
<td align="right" dir="ltr"><font size="2">0.33 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.34 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">7.05 s</font></td>
<td align="right" dir="ltr"><font size="2">0.33 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">7.11 s</font></td>
<td align="right" dir="ltr"><font size="2">0.31 s</font></td></tr>
<tr><td><font size="2">16-bit aligned big endian</font></td>
<td align="right"><font size="2">0.83 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><font size="2">16-bit aligned little endian</font></td>
<td align="right"><font size="2">0.51 s</font></td>
<td align="right"><font size="2">0.50 s</font></td></tr>
<tr><td><font size="2">16-bit unaligned big endian</font></td>
<td align="right"><font size="2">1.37 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><font size="2">16-bit unaligned little endian</font></td>
<td align="right"><font size="2">1.37 s</font></td>
<td align="right"><font size="2">0.50 s</font></td></tr>
<tr><td><b><font size="2">32-bit aligned big endian</font></b></td>
<td align="right"><b><font size="2">0.81 s</font></b></td>
<td align="right"><b><font size="2">0.50 s</font></b></td></tr>
<tr><td><font size="2">32-bit aligned little endian</font></td>
<td align="right"><font size="2">0.51 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><font size="2">32-bit unaligned big endian</font></td>
<td align="right"><font size="2">2.98 s</font></td>
<td align="right"><font size="2">0.53 s</font></td></tr>
<tr><td><font size="2">32-bit unaligned little endian</font></td>
<td align="right"><font size="2">3.00 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><font size="2">64-bit aligned big endian</font></td>
<td align="right"><font size="2">1.33 s</font></td>
<td align="right"><font size="2">0.33 s</font></td></tr>
<tr><td><font size="2">64-bit aligned little endian</font></td>
<td align="right"><font size="2">0.34 s</font></td>
<td align="right"><font size="2">0.27 s</font></td></tr>
<tr><td><font size="2">64-bit unaligned big endian</font></td>
<td align="right"><font size="2">7.05 s</font></td>
<td align="right"><font size="2">0.33 s</font></td></tr>
<tr><td><font size="2">64-bit unaligned little endian</font></td>
<td align="right"><font size="2">7.11 s</font></td>
<td align="right"><font size="2">0.31 s</font></td></tr>
<tr><td colspan="6" align="center" dir="ltr"><b> <font size="2">Iterations: 1000000000, Intrinsics: no byte swap intrinsics</font></b></td></tr>
<tr><td dir="ltr"><b><font size="2">Test Case</font></b></td>
<td align="center" dir="ltr"><b><font size="2">Endian<br>type</font></b></td>
<td align="center" dir="ltr"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
<tr><td colspan="6" align="center"><b> <font size="2">Iterations: 1000000000, Intrinsics: no byte swap intrinsics</font></b></td></tr>
<tr><td><b><font size="2">Test Case</font></b></td>
<td align="center"><b><font size="2">Endian<br>type</font></b></td>
<td align="center"><b><font size="2">Endian<br>conversion<br>function</font></b></td>
</tr>
<tr><td dir="ltr"><font size="2">16-bit aligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">0.83 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">1.36 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">16-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">1.37 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit aligned big endian</font></td>
<td align="right" bgcolor="#FFCACA" dir="ltr"><font size="2">3.42 s</font></td>
<td align="right" dir="ltr"><font size="2">0.50 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td>
<td align="right" dir="ltr"><font size="2">0.51 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">2.93 s</font></td>
<td align="right" dir="ltr"><font size="2">0.50 s</font></td></tr>
<tr><td dir="ltr"><font size="2">32-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">2.95 s</font></td>
<td align="right" dir="ltr"><font size="2">0.50 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit aligned big endian</font></td>
<td align="right" bgcolor="#FFCACA" dir="ltr"><font size="2">5.99 s</font></td>
<td align="right" dir="ltr"><font size="2">0.33 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit aligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">0.33 s</font></td>
<td align="right" dir="ltr"><font size="2">0.33 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit unaligned big endian</font></td>
<td align="right" dir="ltr"><font size="2">7.02 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td dir="ltr"><font size="2">64-bit unaligned little endian</font></td>
<td align="right" dir="ltr"><font size="2">7.02 s</font></td>
<td align="right" dir="ltr"><font size="2">0.27 s</font></td></tr>
<tr><td><font size="2">16-bit aligned big endian</font></td>
<td align="right"><font size="2">0.83 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><font size="2">16-bit aligned little endian</font></td>
<td align="right"><font size="2">0.51 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><font size="2">16-bit unaligned big endian</font></td>
<td align="right"><font size="2">1.36 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><font size="2">16-bit unaligned little endian</font></td>
<td align="right"><font size="2">1.37 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><b><font size="2">32-bit aligned big endian</font></b></td>
<td align="right"><b><font size="2">3.42 s</font></b></td>
<td align="right"><b><font size="2">0.50 s</font></b></td></tr>
<tr><td><font size="2">32-bit aligned little endian</font></td>
<td align="right"><font size="2">0.51 s</font></td>
<td align="right"><font size="2">0.51 s</font></td></tr>
<tr><td><font size="2">32-bit unaligned big endian</font></td>
<td align="right"><font size="2">2.93 s</font></td>
<td align="right"><font size="2">0.50 s</font></td></tr>
<tr><td><font size="2">32-bit unaligned little endian</font></td>
<td align="right"><font size="2">2.95 s</font></td>
<td align="right"><font size="2">0.50 s</font></td></tr>
<tr><td><font size="2">64-bit aligned big endian</font></td>
<td align="right"><font size="2">5.99 s</font></td>
<td align="right"><font size="2">0.33 s</font></td></tr>
<tr><td><font size="2">64-bit aligned little endian</font></td>
<td align="right"><font size="2">0.33 s</font></td>
<td align="right"><font size="2">0.33 s</font></td></tr>
<tr><td><font size="2">64-bit unaligned big endian</font></td>
<td align="right"><font size="2">7.02 s</font></td>
<td align="right"><font size="2">0.27 s</font></td></tr>
<tr><td><font size="2">64-bit unaligned little endian</font></td>
<td align="right"><font size="2">7.02 s</font></td>
<td align="right"><font size="2">0.27 s</font></td></tr>
</table>
<h3><a name="Conclusions">Conclusions</a></h3>
<p>When program logic dictates many more conversions for the Endian integer
<p>When program logic dictates many more conversions for the Endian arithmetic
approach than the Endian conversion function approach (<a href="#Example-2">example
2</a>):</p>
<blockquote>
<p><b>There may be a considerable performance difference. </b>If machine endianness differs from the
desired endianness, the Endian type approach must do the byte reversal many
desired endianness, the Endian arithmetic approach must do the byte reversal many
times while the Endian conversion approach only does the reversal once. But if
the endianness is the same, there is no conversion with either approach and no
conversion code is generated for typical release builds.</p>
<p><b>Whether or not compiler byte swap intrinsics are explicitly available has little
impact as tested.</b> Byte swap intrinsics are not available on some older
compilers and on some machine architectures, such as pre-486 X86 CPUs.</p>
impact on GCC but a lot of impact on Visual C++, for the tested compiler
versions.</b> Yet another example of why actual timing tests are needed to
determine if some coding technique has significant impact on performance.</p>
<p><b>Unaligned types are much slower that aligned types, regardless of
endianness considerations.</b> Instead of single instruction register loads and
@@ -565,9 +676,9 @@ memory space is a minor secondary use case.</p>
<p><b>Why bother with binary I/O? Why not just use C++ Standard Library stream
inserters and extractors?</b></p>
<blockquote>
<p>Data interchange formats often specify binary arithmetic data.</p>
<p>Binary arithmetic data is smaller and therefore I/O is faster and file sizes
are smaller. Transfer between systems is less expensive. Standard interchange
formats often specify binary arithmetic data.</p>
are smaller. Transfer between systems is less expensive.</p>
<p>Furthermore, binary arithmetic data is of fixed size, and so fixed-size disk
records are possible without padding, easing sorting and allowing direct access.
Disadvantages, such as the inability to use text utilities on the resulting
@@ -584,7 +695,7 @@ CPU's. The <a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> article
gives more pros and cons.</p>
</blockquote>
<p><b>Why is only big, little, and native endianness supported?</b></p>
<p><b>Why are only big, little, and native endianness supported?</b></p>
<blockquote>
<p>These are the only endian schemes that have any practical value today. PDP-11
and the other middle endian approaches are interesting historical curiosities
@@ -595,10 +706,10 @@ but have no relevance to today&#39;s C++ developers.</p>
<blockquote>
<p>The only supported types are four byte <code>float</code> and eight byte
<p>The only supported types are four-byte <code>float</code> and eight-byte
<code>double</code>. Even after endianness has been accounted for, floating
point values will not be portable between systems that use different floating
point formats. Systems where the integer endianness differs from floating point
point formats. Systems where integer endianness differs from floating point
endianness are not supported.</p>
</blockquote>
@@ -618,21 +729,28 @@ and 16, 32, and 64-bit aligned integers.</p>
<h2><a name="Release-history">Release history</a></h2>
<h3>Changes since formal review</h3>
<ul>
<li>Headers have been renamed to endian/types.hpp and endian/conversion.hpp.
<li>
<p>The endian types have been decomposed into endian buffer types
and endian arithmetic types, as requested. The arithmetic types derive from
the buffer types.</li>
<li>
<p>Headers have been renamed to <code>endian/arithmetic.hpp</code> and
<code>endian/conversion.hpp</code>. <code>endian/buffers.hpp</code> has been
added.
Infrastructure file names were changed accordingly.</li>
<li>The endian types and endian conversion functions now support 32-bit (<code>float)</code> and
<li>
<p>The endian buffer and arithmetic types and endian conversion functions now support 32-bit (<code>float)</code> and
64-bit <code>(double)</code> floating point, as requested.</li>
<li>The endian types now have stream inserter and extractor templates, as
requested.</li>
<li>Both the endian types and endian conversion functions now support UDTs, as requested.</li>
<li>The endian type aliases have been renamed,
using a naming pattern that is consistent for both integer and floating point.</li>
using a naming pattern that is consistent for both integer and floating point, .</li>
<li>The conversion functions have been much revised,
refactored, and otherwise improved based on review comments.<ul>
<li>Functions have been renamed to clarify their functionality.</li>
<li>Both return-by-value and modify-in-place interfaces are provided, as
requested.</li>
<li>Synonyms for the BSD byte swapping function names popularized by OS X
and Linux are provided, so that that developers already used to these names
can continue to use them if they wish.</li>
<li>In addition to the named-endianness functions, functions that perform
compile-time (via template) and run-time (via function argument) dispatch
are now provided, as requested.</li>
@@ -646,10 +764,10 @@ and 16, 32, and 64-bit aligned integers.</p>
<li><code>order::native</code> is now a synonym for <code>order::big</code>
or <code>order::little</code> according to the endianness of the platform, as
requested. This reduces the number of template specializations required.</li>
<li><code>reverse_value()</code> overloads for <code>int8_t</code> and <code>
<li><code>endian_reverse()</code> overloads for <code>int8_t</code> and <code>
uint8_t</code> have been added for improved generality. (Pierre Talbot)</li>
<li>Overloads of <code>reverse()</code> have been replaced with a single <code>
reverse()</code> template. (Pierre Talbot)</li>
<li>Overloads of <code>endian_reverse_inplace()</code> have been replaced with a single <code>
endian_reverse_inplace()</code> template. (Pierre Talbot)</li>
<li>C++11 features such as <code>noexcept</code> are now used, while still
supporting C++03 compilers.</li>
<li>Headers have been reorganized to make them easier to read,
@@ -670,13 +788,11 @@ Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and
Vitaly Budovski,.</p>
<hr>
<p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->12 August, 2014<!--webbot bot="Timestamp" endspan i-checksum="34569" --></p>
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->16 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38645" --></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>
<p>&nbsp;</p>
</body>
</html>

109
mini_review_topics.html Normal file
View File

@@ -0,0 +1,109 @@
<html>
<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>Endian Mini-Review</title>
</head>
<link href="styles.css" rel="stylesheet">
<body>
<p>Here is what needs to be done to get the library ready for a mini-review:
</p>
<p><b>Common use case scenarios should be developed.</b></p>
<blockquote>
<p>&nbsp;</p>
</blockquote>
<p><b>Example programs should be developed for the common use case scenarios.</b></p>
<blockquote>
<p>&nbsp;</p>
</blockquote>
<p><b>Documentation should illuminate the differences between endian
integer/float type and endian conversion approaches to the common use
case scenarios, and provide guidelines for choosing the most appropriate
approach in user's applications.</b></p>
<blockquote>
<p>Done. See <a href="index.html#Choosing">Choosing between
<span style="background-color: #FFFF00">endian types</span> and
endian conversion functions</a>.</p>
</blockquote>
<p><b>Conversion functions supplying results via return should be provided.</b></p>
<blockquote>
<p>Done. See <a href="conversion.html">conversion docs</a>.</p>
</blockquote>
<p><b>Platform specific performance enhancements such as use of compiler intrinsics or relaxed alignment requirements should be supported.</b></p>
<blockquote>
<p>Done. Compiler (Clang, GCC, VisualC++, etc.) intrinsics and built-in
functions are used in the implementation where appropriate, as requested. See
<a href="index.html#Intrinsic">Built-in support for Intrinsics</a>. See
<a href="index.html#Timings">Timings for Example 2</a> to gauge the impact of
intrinsics.</p>
</blockquote>
<p><b>Endian integer (and floating) types should be implemented via the
conversion functions. If that can't be done efficiently, consideration
should be given to expanding the conversion function signatures to
resolve the inefficiencies.</b></p>
<blockquote>
<p>Done. For the endian types, the implementation uses the endian conversion
functions, and thus the intrinsics, as requested.</p>
</blockquote>
<p><b>Benchmarks that measure performance should be provided. It should be
possible to compare platform specific performance enhancements against
portable base implementations, and to compare endian integer approaches
against endian conversion approaches for the common use case scenarios.</b></p>
<blockquote>
<p>Done. See <a href="index.html#Timings">Timings for Example 2</a>. The <code>endian/test</code> directory
also contains several addional benchmark and speed test programs.</p>
</blockquote>
<p><b>Float (32-bits) and double (64-bits) should be supported. IEEE 754 is
the primary use case.</b></p>
<blockquote>
<p>Done. The <a href="types.html">endian types</a> and
<a href="conversion.html">endian conversion</a> functions now support 32-bit (<code>float)</code>
and 64-bit <code>(double)</code> floating point, as requested.</p>
</blockquote>
<p><b>Support for user defined types (UDTs) is desirable, and should be
provided where there would be no conflict with the other concerns.</b></p>
<blockquote>
<p>Done. See <a href="conversion.html#Requirements">conversion requirements</a>.</p>
</blockquote>
<p><b>There is some concern that endian integer/float arithmetic operations
might used inadvertently or inappropriately. The impact of adding an endian_buffer
class without arithmetic operations should be investigated.</b></p>
<blockquote>
<p>Done. The endian types have been decomposed into class template <code>
<a href="buffers.html">endian_buffer</a></code> and class template <code>
<a href="arithmetic.html">endian_arithmetic</a></code>. Class
<code>endian_buffer</code> is a public base class for <code>endian_arithmetic</code>,
and can also be used by users as a stand-alone class.</p>
</blockquote>
<p><b>Stream insertion and extraction of the endian integer/float types should
be documented and included in the test coverage.</b></p>
<blockquote>
<p>Done. See <a href="types.html#Stream-inserter">Stream inserter</a> and
<a href="types.html#Stream-extractor">Stream extractor</a>.</p>
</blockquote>
<p><b>Binary I/O support that was investigated during development of the Endian
library should be put up for mini-review for inclusion in the Boost I/O
library.</b></p>
<blockquote>
<p>&nbsp;</p>
</blockquote>
<hr>
<p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38642" --></p>
<p><EFBFBD> Copyright Beman Dawes, 2014</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>

13
styles.css Normal file
View File

@@ -0,0 +1,13 @@
body
{
font-family: sans-serif;
max-width: 6.5in;
font-size: 85%;
}
ins {background-color: #CCFFCC;}
del {background-color: #FFCACA;}
pre {background-color: #D7EEFF; font-size: 100%;}
code {font-size: 110%;}
table{font-size: 100%;}

232
todo_list.html Normal file
View File

@@ -0,0 +1,232 @@
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<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>Endian Library Do List</title>
</head>
<body>
<h1>Endian Library TODO List</h1>
<p>Last revised:
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->15 December, 2014<!--webbot bot="Timestamp" endspan i-checksum="38643" --></p>
<p><b>August 12, 2014: The many items that have been completed should be
removed, after verifying that they are in fact taken care of.</b></p>
<h2>To Do</h2>
<ul>
<li>Develop the use-cases example programs, using plain integers and UDT's.</li>
<li>Review UDT examples.</li>
<li>Review buffer stream extractors and inserters, and how they work for
arithmetic types. TEST. Make sure nothing got dropped on the floor during
buffer decomposition.</li>
<li><span style="background-color: #FFFF00">Run inspect.</span>
</li>
</ul>
<h2>Format Review Comments</h2>
<h3 dir="ltr">Votes</h3>
<ul>
<li dir="ltr">
<p dir="ltr">John Filo - &quot;Absolutely. I'd like to see support for float and
double, but<br>
even without those additions, I still vote yes.&quot; &quot;For those who deal with
non-native endian data, this library is<br>
extremely useful. It automatically eliminates a whole class of common<br>
programming errors when dealing with such data.&quot;<br>
&nbsp;</li>
<li dir="ltr">
<p dir="ltr">Hartmut Kaiser - &quot;Even if this is not a full review, I would like
to vote YES to include this <br>
library into Boost.
<p>Boost.Spirit is using (and shipping) with an older version of this library
<br>
for several years now and we never had any problems with its usage in <br>
Spirit. It is used as the underlying framework for the binary parsers and <br>
generators and it is functioning as advertised.</p>
<p>As a quick test I replaced the internal (older) version of Boost.Endian in
<br>
Spirit with the reviewed version. All of Spirits regression tests still <br>
pass. &quot;<br>
&nbsp;</li>
<li dir="ltr">
<p dir="ltr">Robert Stewart - &quot;There are issues that keep me from saying yes
at this time. &nbsp;There are too many suggested variations and ideas under
consideration to accept the library in its present state. &nbsp;However, a
mini-review should be sufficient to evaluate the final form, once Beman
determines a course of action, and determine whether to accept it or not.&quot;<br>
&nbsp;</li>
<li dir="ltr">
<p dir="ltr">Tim Blechmann - &quot;the library should be accepted, if<br>
<br>
(a) the interface of the conversion functions is changed<br>
(b) the performance can be improved<br>
(c) the documentation integrates better with the rest of the boost<br>
&nbsp; &nbsp;documentation.&quot;<br>
&nbsp;</li>
<li dir="ltr">
<p dir="ltr">Vicente J. Botet Escriba - &quot;No in its current state.<br>
Once the library takes in account the requested modification (that Beman has
already accepted) a mini-review will be necessary to improve the library
before release.&quot;</li>
</ul>
<h3>Executive summary</h3>
<ul>
<li>Common use case scenarios should be developed.</li>
<li>Example programs should be developed for the common use case scenarios.</li>
<li>Documentation should illuminate the differences between endian
integer/float type and endian conversion approaches to the common use case
scenarios, and provide guidelines for choosing the most appropriate approach
for user's applications.</li>
<li>Conversion functions supplying results via <code>return</code> should be
provided.</li>
<li>Platform specific performance enhancements such as use of compiler
intrinsics or relaxed alignment requirements should be supported.</li>
<li>Endian integer (and floating) types should be implemented via the
conversion functions. If that can't be done efficiently, consideration should
be given to expanding the conversion function signatures to resolve the
inefficiencies.</li>
<li>Benchmarks that measure performance should be provided. It should be
possible to compare platform specific performance enhancements against
portable base implementations, and to compare endian integer approaches
against endian conversion approaches for the common use case scenarios.</li>
<li>Float (32-bits) and double (64-bits) should be supported. IEEE 754 is the
primary use case.</li>
<li>Support for user defined types (UDTs) is desirable, and should be
supported where there would be no conflict with the other concerns.</li>
<li>There is some concern that endian integer/float arithmetic operations
might used
inadvertently or inappropriately. The impact of adding an endian_buffer class without arithmetic
operations should be investigated.</li>
<li>Stream insertion and extraction of the endian integer/float types should
be documented and included in the test coverage.</li>
<li>Binary I/O support that was investigated during development of the Endian
library should be put up for min-review for inclusion in the Boost I/O
library.</li>
</ul>
<h3>Docs</h3>
<ul>
<li>Document use of endian integers with stream inserters and extractors.</li>
<li>Conversion in note mention similarity to htonl() , etc.</li>
<li>Conversion: add discussion of alignment, packing, etc. Bottom line; use at
your own risk. Use Phil's example:<br>
struct S {<br>
&nbsp;uint16_t a;<br>
&nbsp;uint32_t b;<br>
} __attribute__ ((packed));</li>
<li>Requirements for template parameters. </li>
<li>UDTs<ul>
<li>Integers</li>
<li>Conversion</li>
</ul>
</li>
<li>Distinguish use cases and recommendations for which approach (integers vs
conversion) is appropriate.<ul>
<li><a href="http://lists.boost.org/Archives/boost/2011/09/185698.php">
http://lists.boost.org/Archives/boost/2011/09/185698.php</a></li>
</ul>
</li>
<li>&gt; section `experience': this section gives no insights for people who use
or<br>
&gt; read the code. it mainly tells: &quot;we are not the first and the domain of the<br>
&gt; library is important.&quot;. imo this section can be removed (maybe the part that<br>
&gt; it is not related to any c library can go to the `design considerations'<br>
&gt;<br>
&gt; section &quot;motivating use cases&quot;: this is more a marketing blurb/testimonial.<br>
&gt; maybe this could be changed to a section about possible use cases, listing<br>
&gt; `communicating between different devices' and `reading/writing of binary
file<br>
&gt; formats'.</li>
<li>one other point ... the help file seems to directly link to the c++
headers.<br>
this should be changed:<br>
<br>
* some browsers (at least chromium) will not display the header when clicking<br>
&nbsp;the link, but will save them on disk.<br>
<br>
* providing a direct link to the source code from the docs implies that the<br>
&nbsp;user will get some information that are necessary to use the library by<br>
&nbsp;reading the sources. imo, this is not the case for using boost.endian.<br>
<br>
* if a user opens integer.hpp, the first 60 lines just contain copyright, some<br>
&nbsp;historical notes, compiler-specific stuff, includes and ifdefs. imo, this is<br>
&nbsp;the implementation part, which should not be exposed to a user.<br>
<br>
so i'd suggest to completely remove the links to the c++ headers.<br>
&nbsp;</li>
<li>
<div class="im">
&gt; explaining the other builting types are not considered. Why only
big/little<br>
&gt; endianness has been taken in account?</div>
<p>I'll add FAQ and/or add more entries to the final docs.<br>
<br>
Only big/little endianness is taken into account because these are the<br>
only endian schemes that have any practical value. All the others are<br>
just historical curiosities.</li>
</ul>
<h3>Code</h3>
<p>Also change docs if applicable.</p>
<ul>
<li><span style="background-color: #FFCCFF">Beman: TODO</span><span style="background-color: #FFCCFF">:
</span><span style="background-color: #FFCCFF">Google</span><span style="background-color: #FFCCFF">
&quot;unaligned integer&quot;, look at various entries. For example, http://</span><span style="background-color: #FFCCFF">infocenter.arm.com</span><span style="background-color: #FFCCFF">/help/</span><span style="background-color: #FFCCFF">index.jsp?topic</span><span style="background-color: #FFCCFF">=/</span><span style="background-color: #FFCCFF">com.arm.doc.faqs</span><span style="background-color: #FFCCFF">/ka3544.html</span></li>
<li>Beman: Some platforms (compiler/processor taken together) don't require
alignment for the conversion functions if code is inlined, although speed may
suffer. (test to verify this assertion). On those platforms, conversion
functions (perhaps in-place) can be used to implement unaligned integers.<ul>
<li>Microsoft <a href="http://msdn.microsoft.com/en-us/library/ms253978.aspx">
UNALIGNED / __unaligned</a> keywords for pointers. Also
<a href="http://msdn.microsoft.com/en-us/library/ms253935.aspx">Packing
Structures</a>.</li>
<li>GCC
<a href="http://www.mailinglistarchive.com/gcc@gcc.gnu.org/msg21079.html">
http://www.mailinglistarchive.com/gcc@gcc.gnu.org/msg21079.html</a></li>
<li>Intel performs well on simple unaligned test. See
<a href="../test/unaligned_test.cpp">../test/unaligned_test.cpp</a></li>
</ul>
</li>
<li>Beman: Does the use of the unrolling templates get in the way of processor
specific optimization code?</li>
<li>Test use of endian integers with stream inserters and extractors.</li>
<li>Continue work on benchmarks and timings. Consider using use-case example
programs as benchmarks.</li>
<li dir="ltr">
<div class="im">
&gt; The library should provide in addition endian conversion functions that
have<br>
&gt; the endiannes as template parameters to make possible generic functions.</div>
<p dir="ltr">Compile time dispatch on an endianness enum was also requested in<br>
another review. That's fine with me, but I haven't had a chance to<br>
figure out the interface details.</li>
</ul>
<h3>Infrastructure</h3>
<ul>
<li>
<div class="im">
&gt; endian_operations_test.cpp and endian_in_union_test.cpp ... maybe rename
from<br>
&gt; _test.cpp to _compile_test.cpp? they don't seem to do any run-time tests.
they<br>
&gt; also should not include &lt;cassert&gt; since no assertion statement is needed,
this<br>
&gt; might speed up the compilation time of the testsuite by something like
50ms ;)</div>
<p>Will do.</li>
<li>Make the bin() functionality available</li>
</ul>
<p>* I'm only willing to provide conversion.hpp FP support. Providing<br>
types that mimic FP types is far beyond my knowledge of how to deal<br>
with floating point's notorious arithmetic issues.</p>
<p>Support IEEE754 format (32 bit, 64 bit) only.</p>
<hr>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body>
</html>