forked from boostorg/endian
Endian: docs and examples improvements
git-svn-id: http://svn.boost.org/svn/boost/sandbox/endian@51855 b8fc166d-592f-0410-95f2-cb63ce0dd405
This commit is contained in:
1 parent
1218fc6f5c
commit
0f36e2670d
6 files changed
+133
-47
No files matched your search
@@ -39,13 +39,13 @@
|
||||
# error Platforms with CHAR_BIT != 8 are not supported
|
||||
# endif
|
||||
|
||||
# ifndef BOOST_NO_DEFAULTED_FUNCTIONS
|
||||
# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
|
||||
# else
|
||||
# ifdef BOOST_NO_DEFAULTED_FUNCTIONS
|
||||
# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03
|
||||
# else
|
||||
# define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_NO_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIANS_IN_UNIONS)
|
||||
# if defined(BOOST_NO_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS)
|
||||
# define BOOST_ENDIAN_NO_CTORS
|
||||
# endif
|
||||
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
|
||||
// unformatted binary (as opposed to formatted character-set) input and output
|
||||
// unformatted binary (as opposed to formatted character) stream insertion
|
||||
// and extraction.
|
||||
|
||||
// Caution: Use only on streams opened with filemode std::ios_base::binary. Thus
|
||||
// Warning: Use only on streams opened with filemode std::ios_base::binary. Thus
|
||||
// unformatted binary I/O should not be with the standard streams (cout, cin, etc.)
|
||||
// since they are opened in text mode. Use on text streams may produce incorrect
|
||||
// results, such as insertion of unwanted characters or premature end-of-file.
|
||||
|
||||
+107
-25
@@ -37,6 +37,7 @@
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="#Introduction">Introduction</a><br>
|
||||
<a href="#Hello-endian-world">Hello endian world</a><br>
|
||||
<a href="#Limitations">Limitations</a><br>
|
||||
<a href="#Feature-set">Feature set</a><br>
|
||||
<a href="#Types">Typedefs</a><br>
|
||||
@@ -46,9 +47,12 @@
|
||||
<a href="#Synopsis">Synopsis</a><br>
|
||||
<a href="#Members">Members</a><br>
|
||||
<a href="#FAQ">FAQ</a><br>
|
||||
<a href="#Binary-I-O-cautions">Binary I/O warnings and cautions</a><br>
|
||||
<a href="#Example">Example</a><br>
|
||||
<a href="#Design">Design</a><br>
|
||||
<a href="#Experience">Experience</a><br>
|
||||
<a href="#C++0x">C++0x</a><br>
|
||||
<a href="#Compilation">Compilation</a><br>
|
||||
<a href="#Acknowledgements">Acknowledgements</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -59,7 +63,8 @@
|
||||
<tr>
|
||||
<td width="100%" bgcolor="#E8F5FF">
|
||||
<a href="../../../boost/integer/endian.hpp"><boost/integer/endian.hpp></a><br>
|
||||
<a href="../../../boost/integer/endian_io.hpp"><boost/integer/endian_io.hpp></a></td>
|
||||
<a href="../../../boost/integer/endian_binary_stream.hpp"><boost/integer/endian_binary_stream.hpp></a><br>
|
||||
<a href="../../../boost/binary_stream.hpp"><boost/binary_stream.hpp></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a name="Introduction">Introduction</a></h2>
|
||||
@@ -70,7 +75,7 @@ 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 portability is the primary motivation, these
|
||||
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>
|
||||
@@ -91,9 +96,43 @@ arithmetic operators are <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 conversion is provided to the underlying integer value type.</p>
|
||||
<p>Header <a href="../../../boost/integer/endian_io.hpp"><boost/integer/endian_io.hpp></a>
|
||||
provides operators <code><<</code> and <code>>></code> for
|
||||
stream insertion and extraction.</p>
|
||||
<p>Header <a href="../../../boost/integer/endian_binary_stream.hpp"><boost/integer/endian_binary_stream.hpp></a>
|
||||
provides operators <= and <code>=></code> for unformatted binary (as opposed to
|
||||
formatted character) stream insertion and extraction of endian types.</p>
|
||||
<p>Header <a href="../../../boost/binary_stream.hpp"><boost/binary_stream.hpp></a>
|
||||
provides operators <= and <code>=></code> for unformatted binary (as opposed to
|
||||
formatted character) stream insertion and extraction of built-in and std::string
|
||||
types.</p>
|
||||
<h2><a name="Hello-endian-world">Hello endian world</a></h2>
|
||||
<blockquote>
|
||||
<pre>#include <boost/integer/endian.hpp>
|
||||
#include <boost/integer/endian_binary_stream.hpp>
|
||||
#include <boost/binary_stream.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::integer;
|
||||
|
||||
int main()
|
||||
{
|
||||
int_least32_t v = 0x31323334L; // = ASCII { '1', '2', '3', '4' }
|
||||
// value chosen to work on text stream
|
||||
big32_t b(v);
|
||||
little32_t l(v);
|
||||
|
||||
std::cout << "Hello, endian world!\n\n";
|
||||
|
||||
std::cout << v << ' ' << b << ' ' << l << '\n';
|
||||
std::cout <= v <= ' ' <= b <= ' ' <= l <= '\n';
|
||||
}</pre>
|
||||
</blockquote>
|
||||
<p>On a little-endian CPU, this program outputs:</p>
|
||||
<blockquote>
|
||||
<pre>Hello, endian world!
|
||||
|
||||
825373492 825373492 825373492
|
||||
4321 1234 4321</pre>
|
||||
</blockquote>
|
||||
<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
|
||||
@@ -395,11 +434,9 @@ alignment.</p>
|
||||
compared to arithmetic operations on native integer types. However, these types
|
||||
are usually be faster, and sometimes much faster, for I/O compared to stream
|
||||
inserters and extractors, or to serialization.</p>
|
||||
<p><b>Are endian types POD's?</b> In C++03, no. For C++0x, yes, after applying
|
||||
<code>
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">=
|
||||
default</a></code> to the default constructor.</p>
|
||||
<p><b>What are the implications of C++03 endian types not being POD's?</b> They
|
||||
<p><b>Are endian types POD's?</b> Yes for C++0x. 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 types not being POD's of C++03?</b> They
|
||||
can't be used in unions. In theory, compilers aren't required to align or lay
|
||||
out storage in portable ways, although this problem has never been observed in a
|
||||
real compiler.</p>
|
||||
@@ -428,6 +465,27 @@ incrementing a variable in a record. It is very convenient to write:</p>
|
||||
<pre wrap> int temp( record.foo);
|
||||
++temp;
|
||||
record.foo = temp;</pre>
|
||||
<p wrap><b>Why do binary stream insertion and extraction use operators <= and >=
|
||||
rather than <<= and >>=?</b> <<= and >>= associate right-to-left, which is the
|
||||
opposite of << and >>, so would be very confusing and error prone. <= and >=
|
||||
associate left-to-right. </p>
|
||||
<h2><a name="Binary-I-O-cautions">Binary I/O warnings and cautions</a></h2>
|
||||
<p><font color="#FF0000"><b><i><span style="background-color: #FFFFFF">Warning:</span></i></b></font><span style="background-color: #FFFFFF"> </span> Use
|
||||
only on streams opened with filemode <code>std::ios_base::binary</code>. Thus
|
||||
unformatted binary I/O should not be with the standard streams (cout, cin, etc.)
|
||||
since they are opened in text mode. Use on text streams may produce incorrect
|
||||
results, such as insertion of unwanted characters or premature end-of-file. For
|
||||
example, on Windows 0x0D would become 0x0D, 0x0A.</p>
|
||||
<p><i><b><font color="#FF0000">Caution:</font><font color="#FFFF00"> </font></b>
|
||||
</i>When mixing formatted (i.e. operator << or >>) and unformatted (i.e.
|
||||
operator <= or >=) stream I/O, be aware that << and >> take precedence over <=
|
||||
and >=. Use parentheses to force correct order of evaluation. For example:</p>
|
||||
<blockquote>
|
||||
<pre>my_stream << foo <= bar; // no parentheses needed
|
||||
(my_stream <= foo) << bar; // parentheses required </pre>
|
||||
</blockquote>
|
||||
<p>As a practical matter, it may be easier and safer to never mix the character
|
||||
and binary insertion or extraction operators in the same statement.</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>
|
||||
@@ -437,15 +495,14 @@ binary file containing four byte big-endian and little-endian integers:</p>
|
||||
#include <cstdio>
|
||||
#include <boost/integer/endian.hpp>
|
||||
|
||||
using boost::integer::big32_t;
|
||||
using boost::integer::little32_t;
|
||||
using namespace boost::integer;
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is a portion of a widely used GIS file format. I have no idea why
|
||||
// anyone would mix big and little endians in the same format - but it is
|
||||
// a real format and users wishing to write code manipulating files in that
|
||||
// format have to deal with it.
|
||||
// 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.
|
||||
|
||||
struct header
|
||||
{
|
||||
@@ -460,7 +517,7 @@ namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
assert( sizeof( header ) == 16 );
|
||||
assert( sizeof( header ) == 16 ); // requirement for interoperability
|
||||
|
||||
header h;
|
||||
|
||||
@@ -469,15 +526,15 @@ int main()
|
||||
h.version = -1;
|
||||
h.shape_type = 0x04030201;
|
||||
|
||||
// Low-level I/O such as POSIX read/write or <cstdio> fread/fwrite is
|
||||
// typically used for binary file operations. Such I/O is often performed in
|
||||
// some C++ wrapper class, but to drive home the point that endian integers
|
||||
// are usually used in fairly low-level code, <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" )) )
|
||||
if ( !(fi = std::fopen( filename, "wb" )) ) // MUST BE BINARY
|
||||
{
|
||||
std::cout << "could not open " << filename << '\n';
|
||||
return 1;
|
||||
@@ -490,6 +547,7 @@ int main()
|
||||
}
|
||||
|
||||
std::fclose( fi );
|
||||
|
||||
std::cout << "created file " << filename << '\n';
|
||||
return 0;
|
||||
}</pre>
|
||||
@@ -527,6 +585,30 @@ 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 integers have proven widely useful across a wide
|
||||
range of computer architectures and applications.</p>
|
||||
<h2><a name="C++0x">C++0x</a></h2>
|
||||
<p>The availability of the C++0x
|
||||
<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++0x
|
||||
<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++0x
|
||||
<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++0x, <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>
|
||||
@@ -553,8 +635,8 @@ Tomas Puverle, and
|
||||
Yuval Ronen.</p>
|
||||
<hr>
|
||||
<p>Last revised:
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->12 March, 2009<!--webbot bot="Timestamp" endspan i-checksum="29025" --></p>
|
||||
<p>© Copyright Beman Dawes, 2006</p>
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->19 March, 2009<!--webbot bot="Timestamp" endspan i-checksum="29039" --></p>
|
||||
<p>© Copyright Beman Dawes, 2006-2009</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a>)</p>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
// Copyright Beman Dawes, 2006
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// See library home page at http://www.boost.org/libs/endian
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
#include <cstdio>
|
||||
#include <boost/integer/endian.hpp>
|
||||
|
||||
using boost::integer::big32_t;
|
||||
using boost::integer::little32_t;
|
||||
using namespace boost::integer;
|
||||
|
||||
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 format and users wishing to write low level code
|
||||
// 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
|
||||
@@ -39,7 +38,7 @@ namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
assert( sizeof( header ) == 16 );
|
||||
assert( sizeof( header ) == 16 ); // requirement for interoperability
|
||||
|
||||
header h;
|
||||
|
||||
@@ -48,15 +47,15 @@ int main()
|
||||
h.version = -1;
|
||||
h.shape_type = 0x04030201;
|
||||
|
||||
// Low-level I/O such as POSIX read/write or <cstdio> fread/fwrite is
|
||||
// typically used for binary file operations. Such I/O is often performed in
|
||||
// some C++ wrapper class, but to drive home the point that endian integers
|
||||
// are usually used in fairly low-level code, <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" )) )
|
||||
if ( !(fi = std::fopen( filename, "wb" )) ) // MUST BE BINARY
|
||||
{
|
||||
std::cout << "could not open " << filename << '\n';
|
||||
return 1;
|
||||
|
||||
@@ -19,8 +19,12 @@ int main()
|
||||
{
|
||||
int_least32_t v = 0x31323334L; // = ASCII { '1', '2', '3', '4' }
|
||||
// value chosen to work on text stream
|
||||
std::cout << "Hello, endian world!\n";
|
||||
std::cout << v << " " << big32_t(v) << " " << little32_t(v) << '\n';
|
||||
std::cout <= v <= ' ' <= big32_t(v) <= ' ' <= little32_t(v) <= '\n';
|
||||
big32_t b(v);
|
||||
little32_t l(v);
|
||||
|
||||
std::cout << "Hello, endian world!\n\n";
|
||||
|
||||
std::cout << v << ' ' << b << ' ' << l << '\n';
|
||||
std::cout <= v <= ' ' <= b <= ' ' <= l <= '\n';
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define BOOST_ENDIANS_IN_UNIONS
|
||||
#define BOOST_ENDIAN_FORCE_PODNESS
|
||||
|
||||
#include <boost/integer/endian.hpp>
|
||||
#include <cassert>
|
||||
|
||||
Reference in new issue
Block a user