mirror of
https://github.com/boostorg/endian.git
synced 2025-08-01 13:34:39 +02:00
Initial done_list.html. Improve general FAQ. Update example. Add BOOST_NOEXCEPT to types.hpp and cover_operators.hpp.
This commit is contained in:
44
doc/done_list.html
Normal file
44
doc/done_list.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<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>New Page 1</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Endian changes since formal review</h1>
|
||||
<ul>
|
||||
<li>Headers rename to endian/types.hpp and endian/conversion.hpp.
|
||||
Infrastructure file names changed accordingly.</li>
|
||||
<li>The conversion.hpp conversion functions have been much revised, refactored,
|
||||
renamed and otherwise improved based on review comments.<ul>
|
||||
<li>UDT's are supported.</li>
|
||||
<li><code>float</code>(32-bits) and <code>double</code> (64-bits) are
|
||||
supported.</li>
|
||||
<li>Both return-by-value and modify-in-place interfaces are provided.</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 name
|
||||
can continue to use them if they wish.</li>
|
||||
<li>In addition to the fixed endianness functions, functions that perform
|
||||
compile-time (via template) and run-time (via function argument) dispatch
|
||||
are now provided.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Compiler (Clang, GCC, VisualC++, etc.) intrinsics and built-in functions
|
||||
are used in the implementation where appropriate.</li>
|
||||
<li>For the aligned endian integer types, the implementation uses
|
||||
conversion.hpp conversion functions.</li>
|
||||
<li>C++11 features such as <code>noexcept</code> are used, while still
|
||||
supporting C++03 compilers.</li>
|
||||
<li>Acknowledgements have been updated.</li>
|
||||
<li>Headers have been reorganized to make them easier to read, as requested,
|
||||
with a synopsis at the front and implementation following.</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@@ -178,11 +178,14 @@ application.</p>
|
||||
</table>
|
||||
|
||||
<h2>Overall <a name="FAQ">FAQ</a></h2>
|
||||
<p><b>Why bother with endianness? Does endianness have any uses outside of
|
||||
portable binary file or network I/O formats?</b> </p>
|
||||
<p><b>Why bother with endianness?</b></p>
|
||||
<blockquote>
|
||||
<p>Binary data portability is the primary use case, and that implies I/O.</p>
|
||||
<p>Using the 3, 5, 6, and 7 byte integer types to save internal or external
|
||||
<p>Binary data portability is the primary use case.</p>
|
||||
</blockquote>
|
||||
<p><b>Does endianness have any uses outside of portable binary file or network
|
||||
I/O formats?</b> </p>
|
||||
<blockquote>
|
||||
<p>Using the unaligned integer types to save internal or external
|
||||
memory space is a minor secondary use case.</p>
|
||||
</blockquote>
|
||||
<p><b>Why bother with binary I/O? Why not just use C++ Standard Library stream
|
||||
@@ -198,6 +201,13 @@ files, limit usefulness to applications where the binary I/O advantages are
|
||||
paramount.</p>
|
||||
</blockquote>
|
||||
|
||||
<p><b>Why is 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
|
||||
but have no relevance to C++ developers.</p>
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
|
||||
<p>Comments and suggestions were
|
||||
received from
|
||||
@@ -216,7 +226,7 @@ Tim 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 -->20 May, 2013<!--webbot bot="Timestamp" endspan i-checksum="13976" --></p>
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->22 May, 2013<!--webbot bot="Timestamp" endspan i-checksum="13980" --></p>
|
||||
<p><EFBFBD> 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>
|
||||
|
198
doc/types.html
198
doc/types.html
@@ -109,64 +109,69 @@ using namespace boost::endian;
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is an extract from a very widely used GIS file format. I have no idea
|
||||
// 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. 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.
|
||||
|
||||
struct header
|
||||
{
|
||||
big32_t file_code;
|
||||
big32_t file_length;
|
||||
little32_t version;
|
||||
little32_t shape_type;
|
||||
big_int32_t file_code;
|
||||
big_int32_t file_length;
|
||||
little_int32_t version;
|
||||
little_int32_t shape_type;
|
||||
};
|
||||
|
||||
const char * filename = "test.dat";
|
||||
const char* filename = "test.dat";
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(int, char* [])
|
||||
{
|
||||
BOOST_STATIC_ASSERT( sizeof( header ) == 16U ); // check requirement
|
||||
|
||||
BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check
|
||||
|
||||
header h;
|
||||
|
||||
h.file_code = 0x01020304;
|
||||
h.file_length = sizeof( header );
|
||||
h.version = -1;
|
||||
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.
|
||||
// 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;
|
||||
|
||||
if ( !(fi = std::fopen( filename, "wb" )) ) // MUST BE BINARY
|
||||
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 )
|
||||
if (std::fwrite(&h, sizeof(header), 1, fi)!= 1)
|
||||
{
|
||||
std::cout << "write failure for " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::fclose( fi );
|
||||
std::fclose(fi);
|
||||
|
||||
std::cout << "created file " << filename << '\n';
|
||||
|
||||
return 0;
|
||||
}</pre>
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>After compiling and executing <a href="endian_example.cpp">endian_example.cpp</a>,
|
||||
a hex dump of <code>test.dat</code> shows:</p>
|
||||
<blockquote>
|
||||
<pre>0102 0304 0000 0010 ffff ffff 0403 0201</pre>
|
||||
<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
|
||||
@@ -178,7 +183,7 @@ 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 will be possible to specify the
|
||||
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>
|
||||
@@ -190,15 +195,19 @@ will no longer be relying on unspecified behavior.</p>
|
||||
<li>1-8 byte (unaligned) | 2, 4, 8 byte (aligned)</li>
|
||||
<li>Choice of integer value type</li>
|
||||
</ul>
|
||||
<h2><a name="Types">Typedefs</a></h2>
|
||||
<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 <<a href="#endianness">endianness</a>::enum_t E, typename T, std::size_t n_bytes,
|
||||
<a href="#alignment">alignment</a>::enum_t A = alignment::unaligned>
|
||||
class endian;
|
||||
<pre>template <order Order, typename T, std::size_t n_bits, align A = align::no>
|
||||
class endian;
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>Sixty typedefs, such as <code>big32_t</code>, provide convenient naming
|
||||
<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%">
|
||||
@@ -210,76 +219,76 @@ conventions for common use cases:</p>
|
||||
<td width="49%" align="center"><b><i>Alignment</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>big</code><b><i>n</i></b><code>_t</code></td>
|
||||
<td width="10%"><code>big</code></td>
|
||||
<td width="10%">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%"><code>unaligned</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>ubig</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>big</code></td>
|
||||
<td width="10%">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%"><code>unaligned</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>little</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>little</code></td>
|
||||
<td width="10%">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%"><code>unaligned</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>ulittle</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>little</code></td>
|
||||
<td width="10%">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%"><code>unaligned</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>native</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>native</code></td>
|
||||
<td width="10%">signed</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%"><code>unaligned</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>unative</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>native</code></td>
|
||||
<td width="10%">unsigned</td>
|
||||
<td width="15%">8,16,24,32,40,48,56,64</td>
|
||||
<td width="49%"><code>unaligned</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>aligned_big</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>big</code></td>
|
||||
<td width="10%">signed</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="10%" align="center">signed</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
<td width="49%"><code>aligned</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>aligned_ubig</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>big</code></td>
|
||||
<td width="10%">unsigned</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="10%" align="center">unsigned</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
<td width="49%"><code>aligned</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>aligned_little</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>little</code></td>
|
||||
<td width="10%">signed</td>
|
||||
<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="10%" align="center">signed</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
<td width="49%"><code>aligned</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="18%"><code>aligned_ulittle</code><i><b>n</b></i><code>_t</code></td>
|
||||
<td width="10%"><code>little</code></td>
|
||||
<td width="10%">unsigned</td>
|
||||
<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="10%" align="center">unsigned</td>
|
||||
<td width="15%">16,32,64</td>
|
||||
<td width="49%"><code>aligned</code></td>
|
||||
<td width="49%" align="center"><code>yes</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
<tr>
|
||||
<td width="18%"><code>big_</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_u</code><i><b>n</b></i><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>little_</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%">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_u</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%">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_</code><i><b>n</b></i><code>_t</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_u</code><i><b>n</b></i><code>_t</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>
|
||||
</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
|
||||
@@ -289,8 +298,9 @@ Code that uses a</span>ligned types is inherently non-portable because alignment
|
||||
requirements vary between hardware architectures and because alignment may be
|
||||
affected by compiler switches or pragmas. 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 big-endian, little-endian, and native-endian types provide identical
|
||||
functionality. All three names are provided to improve code readability and searchability.</p>
|
||||
<p><b><i>Note:</i></b> One-byte big-endian, little-endian, and native-endian types
|
||||
have identical
|
||||
functionality. They are provided to improve code readability and searchability.</p>
|
||||
<h3><a name="Comment-on-naming">Comment on naming</a></h3>
|
||||
<p>When first exposed to endian types, programmers often fit them into a mental model
|
||||
based on the <code><cstdint></code> types. Using that model, it is natural to
|
||||
@@ -593,7 +603,7 @@ sign partial specialization to correctly extend the sign when cover integer size
|
||||
differs from endian representation size.</p>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->21 May, 2013<!--webbot bot="Timestamp" endspan i-checksum="13978" --></p>
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->22 May, 2013<!--webbot bot="Timestamp" endspan i-checksum="13980" --></p>
|
||||
<p><EFBFBD> Copyright Beman Dawes, 2006-2009</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>
|
||||
|
@@ -22,7 +22,7 @@ using namespace boost::endian;
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is an extract from a very widely used GIS file format. I have no idea
|
||||
// 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.
|
||||
@@ -35,18 +35,18 @@ namespace
|
||||
little_int32_t shape_type;
|
||||
};
|
||||
|
||||
const char * filename = "test.dat";
|
||||
const char* filename = "test.dat";
|
||||
}
|
||||
|
||||
int main(int, char * [])
|
||||
int main(int, char* [])
|
||||
{
|
||||
BOOST_STATIC_ASSERT( sizeof( header ) == 16U ); // check requirement
|
||||
BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check
|
||||
|
||||
header h;
|
||||
|
||||
h.file_code = 0x01020304;
|
||||
h.file_length = sizeof( header );
|
||||
h.version = -1;
|
||||
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
|
||||
@@ -55,21 +55,21 @@ int main(int, char * [])
|
||||
// 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
|
||||
std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
|
||||
|
||||
if ( !fi )
|
||||
if (!fi)
|
||||
{
|
||||
std::cout << "could not open " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( std::fwrite( &h, sizeof( header ), 1, fi ) != 1 )
|
||||
if (std::fwrite(&h, sizeof(header), 1, fi)!= 1)
|
||||
{
|
||||
std::cout << "write failure for " << filename << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::fclose( fi );
|
||||
std::fclose(fi);
|
||||
|
||||
std::cout << "created file " << filename << '\n';
|
||||
|
||||
|
@@ -23,7 +23,7 @@ namespace boost
|
||||
namespace endian
|
||||
{
|
||||
#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED
|
||||
BOOST_SCOPED_ENUM_START(order) { big, little, native }; BOOST_SCOPED_ENUM_END
|
||||
BOOST_SCOPED_ENUM_START(order) {big, little, native}; BOOST_SCOPED_ENUM_END
|
||||
# define BOOST_ENDIAN_ORDER_ENUM_DEFINED
|
||||
#endif
|
||||
|
||||
|
@@ -28,6 +28,7 @@
|
||||
# include <boost/operators.hpp>
|
||||
# endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace boost
|
||||
@@ -47,46 +48,46 @@ namespace boost
|
||||
// built into unary +.
|
||||
|
||||
// Unary operations.
|
||||
friend IntegerType operator+(const T& x) { return x; }
|
||||
friend IntegerType operator+(const T& x) BOOST_NOEXCEPT { return x; }
|
||||
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
|
||||
friend IntegerType operator-(const T& x) { return -+x; }
|
||||
friend IntegerType operator~(const T& x) { return ~+x; }
|
||||
friend IntegerType operator!(const T& x) { return !+x; }
|
||||
friend IntegerType operator-(const T& x) BOOST_NOEXCEPT { return -+x; }
|
||||
friend IntegerType operator~(const T& x) BOOST_NOEXCEPT { return ~+x; }
|
||||
friend IntegerType operator!(const T& x) BOOST_NOEXCEPT { return !+x; }
|
||||
|
||||
// The basic ordering operations.
|
||||
friend bool operator==(const T& x, IntegerType y) { return +x == y; }
|
||||
friend bool operator<(const T& x, IntegerType y) { return +x < y; }
|
||||
friend bool operator==(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x == y; }
|
||||
friend bool operator<(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x < y; }
|
||||
# endif
|
||||
|
||||
// The basic arithmetic operations.
|
||||
friend T& operator+=(T& x, IntegerType y) { return x = +x + y; }
|
||||
friend T& operator-=(T& x, IntegerType y) { return x = +x - y; }
|
||||
friend T& operator*=(T& x, IntegerType y) { return x = +x * y; }
|
||||
friend T& operator/=(T& x, IntegerType y) { return x = +x / y; }
|
||||
friend T& operator%=(T& x, IntegerType y) { return x = +x % y; }
|
||||
friend T& operator&=(T& x, IntegerType y) { return x = +x & y; }
|
||||
friend T& operator|=(T& x, IntegerType y) { return x = +x | y; }
|
||||
friend T& operator^=(T& x, IntegerType y) { return x = +x ^ y; }
|
||||
friend T& operator<<=(T& x, IntegerType y) { return x = +x << y; }
|
||||
friend T& operator>>=(T& x, IntegerType y) { return x = +x >> y; }
|
||||
friend T& operator+=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x + y; }
|
||||
friend T& operator-=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x - y; }
|
||||
friend T& operator*=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x * y; }
|
||||
friend T& operator/=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x / y; }
|
||||
friend T& operator%=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x % y; }
|
||||
friend T& operator&=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x & y; }
|
||||
friend T& operator|=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x | y; }
|
||||
friend T& operator^=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x ^ y; }
|
||||
friend T& operator<<=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x << y; }
|
||||
friend T& operator>>=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x >> y; }
|
||||
|
||||
// A few binary arithmetic operations not covered by operators base class.
|
||||
friend IntegerType operator<<(const T& x, IntegerType y) { return +x << y; }
|
||||
friend IntegerType operator>>(const T& x, IntegerType y) { return +x >> y; }
|
||||
friend IntegerType operator<<(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x << y; }
|
||||
friend IntegerType operator>>(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x >> y; }
|
||||
|
||||
// Auto-increment and auto-decrement can be defined in terms of the
|
||||
// arithmetic operations.
|
||||
friend T& operator++(T& x) { return x += 1; }
|
||||
friend T& operator--(T& x) { return x -= 1; }
|
||||
friend T& operator++(T& x) BOOST_NOEXCEPT { return x += 1; }
|
||||
friend T& operator--(T& x) BOOST_NOEXCEPT { return x -= 1; }
|
||||
|
||||
# ifdef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
|
||||
friend T operator++(T& x, int)
|
||||
friend T operator++(T& x, int) BOOST_NOEXCEPT
|
||||
{
|
||||
T tmp(x);
|
||||
x += 1;
|
||||
return tmp;
|
||||
}
|
||||
friend T operator--(T& x, int)
|
||||
friend T operator--(T& x, int) BOOST_NOEXCEPT
|
||||
{
|
||||
T tmp(x);
|
||||
x -= 1;
|
||||
|
@@ -182,17 +182,17 @@ namespace endian
|
||||
{
|
||||
typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
|
||||
|
||||
static T load_big(const unsigned char* bytes)
|
||||
static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *(bytes - 1) | (next::load_big(bytes - 1) << 8); }
|
||||
static T load_little(const unsigned char* bytes)
|
||||
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *bytes | (next::load_little(bytes + 1) << 8); }
|
||||
|
||||
static void store_big(char* bytes, T value)
|
||||
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{
|
||||
*(bytes - 1) = static_cast<char>(value);
|
||||
next::store_big(bytes - 1, value >> 8);
|
||||
}
|
||||
static void store_little(char* bytes, T value)
|
||||
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{
|
||||
*bytes = static_cast<char>(value);
|
||||
next::store_little(bytes + 1, value >> 8);
|
||||
@@ -202,13 +202,13 @@ namespace endian
|
||||
template <typename T>
|
||||
struct unrolled_byte_loops<T, 1, false>
|
||||
{
|
||||
static T load_big(const unsigned char* bytes)
|
||||
static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *(bytes - 1); }
|
||||
static T load_little(const unsigned char* bytes)
|
||||
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *bytes; }
|
||||
static void store_big(char* bytes, T value)
|
||||
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{ *(bytes - 1) = static_cast<char>(value); }
|
||||
static void store_little(char* bytes, T value)
|
||||
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{ *bytes = static_cast<char>(value); }
|
||||
|
||||
};
|
||||
@@ -216,19 +216,19 @@ namespace endian
|
||||
template <typename T>
|
||||
struct unrolled_byte_loops<T, 1, true>
|
||||
{
|
||||
static T load_big(const unsigned char* bytes)
|
||||
static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *reinterpret_cast<const signed char*>(bytes - 1); }
|
||||
static T load_little(const unsigned char* bytes)
|
||||
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
|
||||
{ return *reinterpret_cast<const signed char*>(bytes); }
|
||||
static void store_big(char* bytes, T value)
|
||||
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{ *(bytes - 1) = static_cast<char>(value); }
|
||||
static void store_little(char* bytes, T value)
|
||||
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
|
||||
{ *bytes = static_cast<char>(value); }
|
||||
};
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
T load_big_endian(const void* bytes)
|
||||
T load_big_endian(const void* bytes) BOOST_NOEXCEPT
|
||||
{
|
||||
return unrolled_byte_loops<T, n_bytes>::load_big
|
||||
(static_cast<const unsigned char*>(bytes) + n_bytes);
|
||||
@@ -236,7 +236,7 @@ namespace endian
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
T load_little_endian(const void* bytes)
|
||||
T load_little_endian(const void* bytes) BOOST_NOEXCEPT
|
||||
{
|
||||
return unrolled_byte_loops<T, n_bytes>::load_little
|
||||
(static_cast<const unsigned char*>(bytes));
|
||||
@@ -244,7 +244,7 @@ namespace endian
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
void store_big_endian(void* bytes, T value)
|
||||
void store_big_endian(void* bytes, T value) BOOST_NOEXCEPT
|
||||
{
|
||||
unrolled_byte_loops<T, n_bytes>::store_big
|
||||
(static_cast<char*>(bytes) + n_bytes, value);
|
||||
@@ -252,7 +252,7 @@ namespace endian
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
void store_little_endian(void* bytes, T value)
|
||||
void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT
|
||||
{
|
||||
unrolled_byte_loops<T, n_bytes>::store_little
|
||||
(static_cast<char*>(bytes), value);
|
||||
@@ -281,7 +281,7 @@ namespace endian
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian(T val)
|
||||
explicit endian(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
@@ -290,8 +290,9 @@ namespace endian
|
||||
detail::store_big_endian<T, n_bits/8>(m_value, val);
|
||||
}
|
||||
# endif
|
||||
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const
|
||||
endian & operator=(T val) BOOST_NOEXCEPT
|
||||
{ detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
@@ -299,7 +300,7 @@ namespace endian
|
||||
# endif
|
||||
return detail::load_big_endian<T, n_bits/8>(m_value);
|
||||
}
|
||||
const char* data() const { return m_value; }
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
private:
|
||||
char m_value[n_bits/8];
|
||||
};
|
||||
@@ -314,7 +315,7 @@ namespace endian
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian(T val)
|
||||
explicit endian(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
@@ -323,8 +324,9 @@ namespace endian
|
||||
detail::store_little_endian<T, n_bits/8>(m_value, val);
|
||||
}
|
||||
# endif
|
||||
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const
|
||||
endian & operator=(T val) BOOST_NOEXCEPT
|
||||
{ detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
@@ -332,7 +334,7 @@ namespace endian
|
||||
# endif
|
||||
return detail::load_little_endian<T, n_bits/8>(m_value);
|
||||
}
|
||||
const char* data() const { return m_value; }
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
private:
|
||||
char m_value[n_bits/8];
|
||||
};
|
||||
@@ -348,19 +350,23 @@ namespace endian
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
explicit endian(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); }
|
||||
explicit endian(T val) BOOST_NOEXCEPT { detail::store_big_endian<T, n_bits/8>(m_value, val); }
|
||||
# else
|
||||
explicit endian(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); }
|
||||
explicit endian(T val) BOOST_NOEXCEPT { detail::store_little_endian<T, n_bits/8>(m_value, val); }
|
||||
# endif
|
||||
# endif
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const { return detail::load_big_endian<T, n_bits/8>(m_value); }
|
||||
endian & operator=(T val) BOOST_NOEXCEPT
|
||||
{ detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const BOOST_NOEXCEPT
|
||||
{ return detail::load_big_endian<T, n_bits/8>(m_value); }
|
||||
# else
|
||||
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const { return detail::load_little_endian<T, n_bits/8>(m_value); }
|
||||
endian & operator=(T val) BOOST_NOEXCEPT
|
||||
{ detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const BOOST_NOEXCEPT
|
||||
{ return detail::load_little_endian<T, n_bits/8>(m_value); }
|
||||
# endif
|
||||
const char* data() const { return m_value; }
|
||||
const char* data() const BOOST_NOEXCEPT { return m_value; }
|
||||
private:
|
||||
char m_value[n_bits/8];
|
||||
};
|
||||
@@ -378,7 +384,7 @@ namespace endian
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian(T val)
|
||||
explicit endian(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
@@ -388,12 +394,12 @@ namespace endian
|
||||
}
|
||||
|
||||
# endif
|
||||
endian& operator=(T val)
|
||||
endian& operator=(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
m_value = ::boost::endian::big_endian_value(val);
|
||||
return *this;
|
||||
}
|
||||
operator T() const
|
||||
operator T() const BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
@@ -401,7 +407,7 @@ namespace endian
|
||||
# endif
|
||||
return ::boost::endian::big_endian_value(m_value);
|
||||
}
|
||||
const char* data() const {return reinterpret_cast<const char*>(&m_value);}
|
||||
const char* data() const BOOST_NOEXCEPT {return reinterpret_cast<const char*>(&m_value);}
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
@@ -417,7 +423,7 @@ namespace endian
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian(T val)
|
||||
explicit endian(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
@@ -427,12 +433,12 @@ namespace endian
|
||||
}
|
||||
|
||||
# endif
|
||||
endian& operator=(T val)
|
||||
endian& operator=(T val) BOOST_NOEXCEPT
|
||||
{
|
||||
m_value = ::boost::endian::little_endian_value(val);
|
||||
return *this;
|
||||
}
|
||||
operator T() const
|
||||
operator T() const BOOST_NOEXCEPT
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
@@ -440,7 +446,7 @@ namespace endian
|
||||
# endif
|
||||
return ::boost::endian::little_endian_value(m_value);
|
||||
}
|
||||
const char* data() const {return reinterpret_cast<const char*>(&m_value);}
|
||||
const char* data() const BOOST_NOEXCEPT {return reinterpret_cast<const char*>(&m_value);}
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
|
Reference in New Issue
Block a user