forked from boostorg/endian
Rename the conversion functions to discourage unthinking use of the in-place versions as these are unsafe in that they effectively break the type system by treating the buffer as an undescriminated union. Remove the synonym functions based on names popularized by BSD, OS X, and Linux since these are permitted to be implemented as macros, which would cause endless difficulties if encountered.
This commit is contained in:
688
doc/buffers.html
Normal file
688
doc/buffers.html
Normal file
@@ -0,0 +1,688 @@
|
|||||||
|
<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 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="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>
|
||||||
|
<a href="index.html">Endian Home</a>
|
||||||
|
<a href="conversion.html">Conversion Functions</a>
|
||||||
|
<a href="arithmetic.html">Arithmetic Types</a>
|
||||||
|
<a href="buffers.html">Buffer Types</a></b></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p></p>
|
||||||
|
|
||||||
|
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right">
|
||||||
|
<tr>
|
||||||
|
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||||
|
<i><b>Contents</b></i></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="100%" bgcolor="#E8F5FF">
|
||||||
|
<a href="#Introduction">Introduction</a><br>
|
||||||
|
<a href="#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</code></a><br>
|
||||||
|
|
||||||
|
<a href="#Synopsis">Synopsis</a><br>
|
||||||
|
<a href="#Members">Members</a><br>
|
||||||
|
<a href="#Stream-inserter">Stream inserter</a><br>
|
||||||
|
<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>
|
||||||
|
<a href="#Motivating-use-cases">Motivating use cases</a><br>
|
||||||
|
<a href="#C++0x">C++11</a><br>
|
||||||
|
<a href="#Compilation">Compilation</a><br>
|
||||||
|
<a href="#Acknowledgements">Acknowledgements</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="100%" bgcolor="#D7EEFF" align="center">
|
||||||
|
<b><i>Headers</i></b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="100%" bgcolor="#E8F5FF">
|
||||||
|
<a href="../include/boost/endian/conversion.hpp"><boost/endian/conversion.hpp></a><br>
|
||||||
|
<a href="../include/boost/endian/arithmetic.hpp"><boost/endian/arithmetic.hpp></a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h2><a name="Introduction">Introduction</a></h2>
|
||||||
|
<p>Header <a href="buffers.html">boost/endian/buffers.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>
|
||||||
|
<p>These types provide portable byte-holders for integer data, independent of
|
||||||
|
particular computer architectures. Use cases almost always involve I/O, either via files or
|
||||||
|
network connections. Although data portability is the primary motivation, these
|
||||||
|
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" 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>Boost endian integers provide the same full set of C++ assignment,
|
||||||
|
arithmetic, and relational operators as C++ standard integral types, with
|
||||||
|
the standard semantics.</p>
|
||||||
|
<p>Unary arithmetic operators are <code>+</code>, <code>-</code>, <code>~</code>,
|
||||||
|
<code>!</code>, prefix and postfix <code>--</code> and <code>++</code>. Binary
|
||||||
|
arithmetic operators are <code>+</code>, <code>+=</code>, <code>-</code>, <code>
|
||||||
|
-=</code>, <code>*</code>, <code>*=</code>, <code>/</code>, <code>/=</code>,
|
||||||
|
<code>%/ %=</code>, <code>&</code>, <code>&=</code>, <code>|</code>, <code>|=</code>,
|
||||||
|
<code>^</code>, <code>^=</code>, <code><<</code>, <code><<=</code>, <code>>></code>,
|
||||||
|
<code>>>=</code>. Binary relational operators are <code>==</code>, <code>!=</code>,
|
||||||
|
<code><</code>, <code><=</code>, <code>></code>, <code>>=</code>.</p>
|
||||||
|
<p>Automatic implicit conversion to the underlying value type is provided. An
|
||||||
|
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
|
||||||
|
binary file containing four byte big-endian and little-endian integers:</p>
|
||||||
|
<blockquote>
|
||||||
|
<pre>#include <iostream>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <boost/endian/arithmetic.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
using namespace boost::endian;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
big_int32_t file_code;
|
||||||
|
big_int32_t file_length;
|
||||||
|
little_int32_t version;
|
||||||
|
little_int32_t shape_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* filename = "test.dat";
|
||||||
|
}
|
||||||
|
|
||||||
|
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 <cstdio> 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, <cstdio> fopen/fwrite is used for I/O in this example.
|
||||||
|
|
||||||
|
std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
|
||||||
|
|
||||||
|
if (!fi)
|
||||||
|
{
|
||||||
|
std::cout << "could not open " << filename << '\n';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::fwrite(&h, sizeof(header), 1, fi)!= 1)
|
||||||
|
{
|
||||||
|
std::cout << "write failure for " << filename << '\n';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::fclose(fi);
|
||||||
|
|
||||||
|
std::cout << "created file " << filename << '\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><climits></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</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</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 <order Order, typename T, std::size_t n_bits, align A = align::no>
|
||||||
|
class endian_arithmetic;
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
<p>Typedefs, such as <code>big_int32_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="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>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
</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>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<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>
|
||||||
|
</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
|
||||||
|
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>_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>
|
||||||
|
<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 <order Order, class T, std::size_t n_bits, align A = align::no>
|
||||||
|
class endian
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
// if BOOST_ENDIAN_FORCE_PODNESS is defined && 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;
|
||||||
|
|
||||||
|
endian& <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;
|
||||||
|
|
||||||
|
// arithmetic operations
|
||||||
|
// note that additional operations are provided by the value_type
|
||||||
|
value_type operator+(const endian& x) noexcept;
|
||||||
|
endian& operator+=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator-=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator*=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator/=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator%=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator&=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator|=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator^=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator<<=(endian& x, value_type y) noexcept;
|
||||||
|
endian& operator>>=(endian& x, value_type y noexcept;
|
||||||
|
value_type operator<<(const endian& x, value_type y) noexcept;
|
||||||
|
value_type operator>>(const endian& x, value_type y) noexcept;
|
||||||
|
endian& operator++(endian& x) noexcept;
|
||||||
|
endian& operator--(endian& x) noexcept;
|
||||||
|
endian operator++(endian& x, int) noexcept;
|
||||||
|
endian operator--(endian& x, int) noexcept;
|
||||||
|
|
||||||
|
// Stream inserter
|
||||||
|
template <class charT, class traits>
|
||||||
|
friend std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const T& x);
|
||||||
|
|
||||||
|
// Stream extractor
|
||||||
|
template <class charT, class traits>
|
||||||
|
friend std::basic_istream<charT, traits>&
|
||||||
|
operator>>(std::basic_istream<charT, traits>& is, T& x);
|
||||||
|
};
|
||||||
|
|
||||||
|
// typedefs
|
||||||
|
|
||||||
|
// aligned big endian floating point types
|
||||||
|
typedef endian<order::big, float, 32, align::yes> big_float32_t;
|
||||||
|
typedef endian<order::big, double, 64, align::yes> big_float64_t;
|
||||||
|
|
||||||
|
// aligned little endian floating point types
|
||||||
|
typedef endian<order::little, float, 32, align::yes> little_float32_t;
|
||||||
|
typedef endian<order::little, double, 64, align::yes> little_float64_t;
|
||||||
|
|
||||||
|
// unaligned big endian floating point types
|
||||||
|
typedef endian<order::big, float, 32, align::no> big_float32un_t;
|
||||||
|
typedef endian<order::big, double, 64, align::no> big_float64un_t;
|
||||||
|
|
||||||
|
// unaligned little endian floating point types
|
||||||
|
typedef endian<order::little, float, 32, align::no> little_float32un_t;
|
||||||
|
typedef endian<order::little, double, 64, align::no> little_float64un_t;
|
||||||
|
|
||||||
|
// aligned big endian signed integer types
|
||||||
|
typedef endian<order::big, int16_t, 16, align::yes> big_int16_t;
|
||||||
|
typedef endian<order::big, int32_t, 32, align::yes> big_int32_t;
|
||||||
|
typedef endian<order::big, int64_t, 64, align::yes> big_int64_t;
|
||||||
|
|
||||||
|
// aligned big endian unsigned integer types
|
||||||
|
typedef endian<order::big, uint16_t, 16, align::yes> big_uint16_t;
|
||||||
|
typedef endian<order::big, uint32_t, 32, align::yes> big_uint32_t;
|
||||||
|
typedef endian<order::big, uint64_t, 64, align::yes> big_uint64_t;
|
||||||
|
|
||||||
|
// aligned little endian signed integer types
|
||||||
|
typedef endian<order::little, int16_t, 16, align::yes> little_int16_t;
|
||||||
|
typedef endian<order::little, int32_t, 32, align::yes> little_int32_t;
|
||||||
|
typedef endian<order::little, int64_t, 64, align::yes> little_int64_t;
|
||||||
|
|
||||||
|
// aligned little endian unsigned integer types
|
||||||
|
typedef endian<order::little, uint16_t, 16, align::yes> little_uint16_t;
|
||||||
|
typedef endian<order::little, uint32_t, 32, align::yes> little_uint32_t;
|
||||||
|
typedef endian<order::little, uint64_t, 64, align::yes> little_uint64_t;
|
||||||
|
|
||||||
|
// aligned native endian typedefs are not provided because
|
||||||
|
// <cstdint> types are superior for that use case
|
||||||
|
|
||||||
|
// unaligned big endian signed integer types
|
||||||
|
typedef endian<order::big, int_least8_t, 8> big_int8_ut;
|
||||||
|
typedef endian<order::big, int_least16_t, 16> big_int16_ut;
|
||||||
|
typedef endian<order::big, int_least32_t, 24> big_int24_ut;
|
||||||
|
typedef endian<order::big, int_least32_t, 32> big_int32_ut;
|
||||||
|
typedef endian<order::big, int_least64_t, 40> big_int40_ut;
|
||||||
|
typedef endian<order::big, int_least64_t, 48> big_int48_ut;
|
||||||
|
typedef endian<order::big, int_least64_t, 56> big_int56_ut;
|
||||||
|
typedef endian<order::big, int_least64_t, 64> big_int64_ut;
|
||||||
|
|
||||||
|
// unaligned big endian unsigned integer types
|
||||||
|
typedef endian<order::big, uint_least8_t, 8> big_uint8_ut;
|
||||||
|
typedef endian<order::big, uint_least16_t, 16> big_uint16_ut;
|
||||||
|
typedef endian<order::big, uint_least32_t, 24> big_uint24_ut;
|
||||||
|
typedef endian<order::big, uint_least32_t, 32> big_uint32_ut;
|
||||||
|
typedef endian<order::big, uint_least64_t, 40> big_uint40_ut;
|
||||||
|
typedef endian<order::big, uint_least64_t, 48> big_uint48_ut;
|
||||||
|
typedef endian<order::big, uint_least64_t, 56> big_uint56_ut;
|
||||||
|
typedef endian<order::big, uint_least64_t, 64> big_uint64_ut;
|
||||||
|
|
||||||
|
// unaligned little endian signed integer types
|
||||||
|
typedef endian<order::little, int_least8_t, 8> little_int8_ut;
|
||||||
|
typedef endian<order::little, int_least16_t, 16> little_int16_ut;
|
||||||
|
typedef endian<order::little, int_least32_t, 24> little_int24_ut;
|
||||||
|
typedef endian<order::little, int_least32_t, 32> little_int32_ut;
|
||||||
|
typedef endian<order::little, int_least64_t, 40> little_int40_ut;
|
||||||
|
typedef endian<order::little, int_least64_t, 48> little_int48_ut;
|
||||||
|
typedef endian<order::little, int_least64_t, 56> little_int56_ut;
|
||||||
|
typedef endian<order::little, int_least64_t, 64> little_int64_ut;
|
||||||
|
|
||||||
|
// unaligned little endian unsigned integer types
|
||||||
|
typedef endian<order::little, uint_least8_t, 8> little_uint8_ut;
|
||||||
|
typedef endian<order::little, uint_least16_t, 16> little_uint16_ut;
|
||||||
|
typedef endian<order::little, uint_least32_t, 24> little_uint24_ut;
|
||||||
|
typedef endian<order::little, uint_least32_t, 32> little_uint32_ut;
|
||||||
|
typedef endian<order::little, uint_least64_t, 40> little_uint40_ut;
|
||||||
|
typedef endian<order::little, uint_least64_t, 48> little_uint48_ut;
|
||||||
|
typedef endian<order::little, uint_least64_t, 56> little_uint56_ut;
|
||||||
|
typedef endian<order::little, uint_least64_t, 64> little_uint64_ut;
|
||||||
|
|
||||||
|
// unaligned native endian signed integer types
|
||||||
|
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_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>
|
||||||
|
<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>
|
||||||
|
<h3><a name="Members">Members</a></h3>
|
||||||
|
<div dir="ltr">
|
||||||
|
<pre><code><a name="endian">endian</a>() = default; // C++03: endian(){}</code></pre>
|
||||||
|
</div>
|
||||||
|
<blockquote>
|
||||||
|
<p><i>Effects:</i> Constructs an object of type <code>endian<E, T, n_bits, A></code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><code><a name="explicit-endian">endian</a>(T v);</code></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><i>Effects:</i> Constructs an object of type <code>endian<E, T, n_bits, A></code>.</p>
|
||||||
|
<p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the
|
||||||
|
constructed object.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><code>endian& <a name="operator-eq">operator=</a>(T v);</code></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the
|
||||||
|
constructed object.</p>
|
||||||
|
<p><i>Returns:</i> <code>*this</code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><code><a name="operator-T">operator T</a>() const;</code></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><i>Returns:</i> The current value stored in <code>*this</code>, converted to
|
||||||
|
<code>value_type</code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><code>const char* <a name="data">data</a>() const;</code></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><i>Returns:</i> A pointer to the first byte of the endian binary value stored
|
||||||
|
in <code>*this</code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
<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 <class charT, class traits>
|
||||||
|
friend std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const T& x);
|
||||||
|
</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><i>Returns:</i> <code>os << +x</code>.</p>
|
||||||
|
</blockquote>
|
||||||
|
<h3><a name="Stream-extractor">Stream extractor</a></h3>
|
||||||
|
<pre>template <class charT, class traits>
|
||||||
|
friend std::basic_istream<charT, traits>&
|
||||||
|
operator>>(std::basic_istream<charT, traits>& is, T& x);
|
||||||
|
</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><i>Effects: </i>As if:</p>
|
||||||
|
<blockquote>
|
||||||
|
<pre>T i;
|
||||||
|
if (is >> 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
|
||||||
|
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 types</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="Experience">Experience</a></h2>
|
||||||
|
<p>Classes with similar functionality have been independently developed by
|
||||||
|
several Boost programmers and used very successful in high-value, high-use
|
||||||
|
applications for many years. These independently developed endian libraries
|
||||||
|
often evolved from C libraries that were also widely used. Endian types have proven widely useful across a wide
|
||||||
|
range of computer architectures and applications.</p>
|
||||||
|
<h2><a name="Motivating-use-cases">Motivating use cases</a></h2>
|
||||||
|
<p>Neil Mayhew writes: "I can also provide a meaningful use-case for this
|
||||||
|
library: reading TrueType font files from disk and processing the contents. The
|
||||||
|
data format has fixed endianness (big) and has unaligned values in various
|
||||||
|
places. Using Boost.Endian simplifies and cleans the code wonderfully."</p>
|
||||||
|
<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>
|
||||||
|
</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>
|
||||||
|
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
|
||||||
|
<p>Original design developed by Darin Adler based on classes developed by Mark
|
||||||
|
Borgerding. Four original class templates combined into a single <code>endian</code>
|
||||||
|
class template by Beman Dawes, who put the library together, provided
|
||||||
|
documentation, added the typedefs, and also added the <code>unrolled_byte_loops</code>
|
||||||
|
sign partial specialization to correctly extend the sign when cover integer size
|
||||||
|
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 -->20 November, 2014<!--webbot bot="Timestamp" endspan i-checksum="39482" --></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>
|
@@ -41,91 +41,85 @@ namespace endian
|
|||||||
// suggested by Phil Endecott //
|
// suggested by Phil Endecott //
|
||||||
//--------------------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
// reverse byte order (i.e. endianness)
|
// reverse byte order (i.e. endianness)
|
||||||
//
|
|
||||||
inline int8_t reverse_value(int8_t x) BOOST_NOEXCEPT;
|
inline int8_t reverse(int8_t x) BOOST_NOEXCEPT;
|
||||||
inline int16_t reverse_value(int16_t x) BOOST_NOEXCEPT;
|
inline int16_t reverse(int16_t x) BOOST_NOEXCEPT;
|
||||||
inline int32_t reverse_value(int32_t x) BOOST_NOEXCEPT;
|
inline int32_t reverse(int32_t x) BOOST_NOEXCEPT;
|
||||||
inline int64_t reverse_value(int64_t x) BOOST_NOEXCEPT;
|
inline int64_t reverse(int64_t x) BOOST_NOEXCEPT;
|
||||||
inline uint8_t reverse_value(uint8_t x) BOOST_NOEXCEPT;
|
inline uint8_t reverse(uint8_t x) BOOST_NOEXCEPT;
|
||||||
inline uint16_t reverse_value(uint16_t x) BOOST_NOEXCEPT;
|
inline uint16_t reverse(uint16_t x) BOOST_NOEXCEPT;
|
||||||
inline uint32_t reverse_value(uint32_t x) BOOST_NOEXCEPT;
|
inline uint32_t reverse(uint32_t x) BOOST_NOEXCEPT;
|
||||||
inline uint64_t reverse_value(uint64_t x) BOOST_NOEXCEPT;
|
inline uint64_t reverse(uint64_t x) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
// reverse_value overloads for floating point types as requested by Vicente
|
|
||||||
// Botet and others.
|
|
||||||
// TODO: Track progress of Floating-Point Typedefs Having Specified Widths proposal (N3626)
|
// TODO: Track progress of Floating-Point Typedefs Having Specified Widths proposal (N3626)
|
||||||
inline float reverse_value(float x) BOOST_NOEXCEPT;
|
inline float reverse(float x) BOOST_NOEXCEPT;
|
||||||
inline double reverse_value(double x) BOOST_NOEXCEPT;
|
inline double reverse(double x) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
|
// The conversion function templates, both value returning and in-place, are specified
|
||||||
|
// and implemented by calling the preceding overloads of reverse(). As a consequence,
|
||||||
|
// there is no need for explicit overloads in addition to the generic templates.
|
||||||
|
|
||||||
|
// generic byte order reverse
|
||||||
|
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
|
||||||
|
class ReversibleValue >
|
||||||
|
ReversibleValue reverse(ReversibleValue from) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
|
// reverse byte order unless native endianness is big
|
||||||
|
|
||||||
// reverse bytes unless native endianness is big
|
|
||||||
// possible names: reverse_unless_native_big, reverse_value_unless_big, reverse_unless_big
|
|
||||||
template <class ReversibleValue >
|
template <class ReversibleValue >
|
||||||
inline ReversibleValue big_endian_value(ReversibleValue x) BOOST_NOEXCEPT;
|
inline ReversibleValue big(ReversibleValue x) BOOST_NOEXCEPT;
|
||||||
// Return: x if native endian order is big, otherwise reverse_value(x)
|
// Returns: x if native endian order is big, otherwise reverse(x)
|
||||||
|
|
||||||
|
// reverse byte order unless native endianness is little
|
||||||
|
|
||||||
// reverse bytes unless native endianness is little
|
|
||||||
// possible names: reverse_unless_native_little, reverse_value_unless_little, reverse_unless_little
|
|
||||||
template <class ReversibleValue >
|
template <class ReversibleValue >
|
||||||
inline ReversibleValue little_endian_value(ReversibleValue x) BOOST_NOEXCEPT;
|
inline ReversibleValue little(ReversibleValue x) BOOST_NOEXCEPT;
|
||||||
// Return: x if native endian order is little, otherwise reverse_value(x);
|
// Returns: x if native endian order is little, otherwise reverse(x)
|
||||||
|
|
||||||
// synonyms based on names popularized by BSD, e.g. OS X, Linux
|
// runtime byte order determination
|
||||||
// "h" stands for "host" (i.e. native), "be" for "big endian", "le" for "little endian"
|
|
||||||
template <class T> inline T bswap(T x) BOOST_NOEXCEPT {return reverse_value(x);}
|
|
||||||
template <class T> inline T htobe(T host) BOOST_NOEXCEPT {return big_endian_value(host);}
|
|
||||||
template <class T> inline T htole(T host) BOOST_NOEXCEPT {return little_endian_value(host);}
|
|
||||||
template <class T> inline T betoh(T big) BOOST_NOEXCEPT {return big_endian_value(big);}
|
|
||||||
template <class T> inline T letoh(T little) BOOST_NOEXCEPT {return little_endian_value(little);}
|
|
||||||
|
|
||||||
// compile-time generic byte order conversion
|
|
||||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class ReversibleValue >
|
|
||||||
ReversibleValue convert_value(ReversibleValue from) BOOST_NOEXCEPT;
|
|
||||||
|
|
||||||
// runtime actual byte-order determination
|
|
||||||
inline BOOST_SCOPED_ENUM(order) effective_order(BOOST_SCOPED_ENUM(order) o) BOOST_NOEXCEPT;
|
inline BOOST_SCOPED_ENUM(order) effective_order(BOOST_SCOPED_ENUM(order) o) BOOST_NOEXCEPT;
|
||||||
// Return: o if o != native, otherwise big or little depending on native ordering
|
// Return: o if o != native, otherwise big or little depending on native ordering
|
||||||
|
|
||||||
// runtime byte-order conversion
|
// runtime byte order reverse
|
||||||
|
|
||||||
template <class ReversibleValue >
|
template <class ReversibleValue >
|
||||||
ReversibleValue convert_value(ReversibleValue from, BOOST_SCOPED_ENUM(order) from_order,
|
ReversibleValue reverse(ReversibleValue from, BOOST_SCOPED_ENUM(order) from_order,
|
||||||
BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT;
|
BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
|
// Q: What happended to bswap, htobe, and the other synonym functions based on names
|
||||||
|
// popularized by BSD, OS X, and Linux?
|
||||||
|
// A: Turned out these may be implemented as macros on some systems. Ditto POSIX names
|
||||||
|
// for such functionality. Since macros would cause endless problems with these
|
||||||
|
// function names, and these functions are just synonyms anyhow, they have been
|
||||||
|
// removed.
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------------------//
|
||||||
// modify in place interface //
|
// in place interface //
|
||||||
//--------------------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
// reverse byte order (i.e. endianness)
|
// reverse byte order (i.e. endianness)
|
||||||
//
|
//
|
||||||
template <class Value>
|
template <class Value>
|
||||||
inline void reverse(Value& x) BOOST_NOEXCEPT;
|
inline void reverse_in_place(Value& x) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
// reverse unless native endianness is big
|
// reverse unless native endianness is big
|
||||||
template <class Reversible>
|
template <class Reversible>
|
||||||
inline void big_endian(Reversible& x) BOOST_NOEXCEPT;
|
inline void big_in_place(Reversible& x) BOOST_NOEXCEPT;
|
||||||
// Effects: none if native endian order is big, otherwise reverse(x)
|
// Effects: none if native endian order is big, otherwise reverse(x)
|
||||||
|
|
||||||
// reverse unless native endianness is little
|
// reverse unless native endianness is little
|
||||||
template <class Reversible>
|
template <class Reversible>
|
||||||
inline void little_endian(Reversible& x) BOOST_NOEXCEPT;
|
inline void little_in_place(Reversible& x) BOOST_NOEXCEPT;
|
||||||
// Effects: none if native endian order is little, otherwise reverse(x);
|
// Effects: none if native endian order is little, otherwise reverse(x);
|
||||||
|
|
||||||
// synonyms based on names popularized by BSD, e.g. OS X, Linux.
|
// generic byte order conversion
|
||||||
// "h" stands for "host" (i.e. native), "be" for "big endian",
|
|
||||||
// "le" for "little endian", "m" for "modify in place"
|
|
||||||
template <class T> inline void mbswap(T& x) BOOST_NOEXCEPT {reverse(x);}
|
|
||||||
template <class T> inline void mhtobe(T& host) BOOST_NOEXCEPT {big_endian(host);}
|
|
||||||
template <class T> inline void mhtole(T& host) BOOST_NOEXCEPT {little_endian(host);}
|
|
||||||
template <class T> inline void mbetoh(T& big) BOOST_NOEXCEPT {big_endian(big);}
|
|
||||||
template <class T> inline void mletoh(T& little) BOOST_NOEXCEPT {little_endian(little);}
|
|
||||||
|
|
||||||
// compile-time generic byte order conversion
|
|
||||||
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class Reversible>
|
template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class Reversible>
|
||||||
void convert(Reversible& x) BOOST_NOEXCEPT;
|
void reverse_in_place(Reversible& x) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
// runtime byte-order conversion
|
// runtime byte-order reverse
|
||||||
template <class Reversible>
|
template <class Reversible>
|
||||||
void convert(Reversible& x, BOOST_SCOPED_ENUM(order) from_order,
|
void reverse_in_place(Reversible& x, BOOST_SCOPED_ENUM(order) from_order,
|
||||||
BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT;
|
BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT;
|
||||||
|
|
||||||
//----------------------------------- end synopsis -------------------------------------//
|
//----------------------------------- end synopsis -------------------------------------//
|
||||||
|
Reference in New Issue
Block a user