@@ -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
// anyo ne 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 desig ner 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 > <EFBFBD> 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 > <EFBFBD> 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 >