Initial commit, corresponding to endian-0.8

git-svn-id: http://svn.boost.org/svn/boost/sandbox/endian@45953 b8fc166d-592f-0410-95f2-cb63ce0dd405
This commit is contained in:
bemandawes
2008-05-30 15:26:33 +00:00
commit 59c79ecb75
11 changed files with 1899 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
// boost/integer/cover_operators.hpp ----------------------------------------//
// (C) Copyright Darin Adler 2000
// 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)
//----------------------------------------------------------------------------//
#ifndef BOOST_INTEGER_COVER_OPERATORS_HPP
#define BOOST_INTEGER_COVER_OPERATORS_HPP
#include <boost/operators.hpp>
#include <iosfwd>
namespace boost
{
namespace integer
{
// A class that adds integer operators to an integer cover class
template <typename T, typename IntegerType>
class cover_operators : boost::operators<T>
{
// The other operations take advantage of the type conversion that's
// built into unary +.
// Unary operations.
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) { 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; }
// 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; }
// 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; }
// 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; }
/// TODO: stream I/O needs to be templatized on the stream type, so will
/// work with wide streams, etc.
// Stream input and output.
friend std::ostream& operator<<(std::ostream& s, const T& x)
{ return s << +x; }
friend std::istream& operator>>(std::istream& s, T& x)
{
IntegerType i;
if (s >> i)
x = i;
return s;
}
};
} // namespace integer
} // namespace boost
#endif // BOOST_INTEGER_COVER_OPERATORS_HPP

346
boost/integer/endian.hpp Normal file
View File

@@ -0,0 +1,346 @@
// Boost endian.hpp header file (proposed) ----------------------------------//
// (C) Copyright Darin Adler 2000
// (C) 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)
// See library home page at http://www.boost.org/libs/endian
//----------------------------------------------------------------------------//
// Original design developed by Darin Adler based on classes developed by Mark
// Borgerding. Four original class templates combined into a single endian
// class template by Beman Dawes, who also added the unrolled_byte_loops sign
// partial specialization to correctly extend the sign when cover integer size
// differs from endian representation size.
// TODO:
// * Use C++0x scoped enums if available
// * Use C++0x defaulted default constructor if available
// * Propose, use, BOOST_CONSTEXPR.
// * Propose BOOST_EXPLICIT, apply if needed
// * Should there be a conversion to bool?
#ifndef BOOST_ENDIAN_HPP
#define BOOST_ENDIAN_HPP
#include <boost/detail/endian.hpp>
#include <boost/integer/cover_operators.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <iosfwd>
#include <climits>
# if CHAR_BIT != 8
# error Platforms with CHAR_BIT != 8 are not supported
# endif
namespace boost
{
namespace detail
{
// Unrolled loops for loading and storing streams of bytes.
template <typename T, std::size_t n_bytes,
bool sign=boost::is_signed<T>::value >
struct unrolled_byte_loops
{
typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
static T load_big(const unsigned char* bytes)
{ return *(bytes - 1) | (next::load_big(bytes - 1) << 8); }
static T load_little(const unsigned char* bytes)
{ return *bytes | (next::load_little(bytes + 1) << 8); }
static void store_big(char* bytes, T value)
{
*(bytes - 1) = static_cast<char>(value);
next::store_big(bytes - 1, value >> 8);
}
static void store_little(char* bytes, T value)
{
*bytes = static_cast<char>(value);
next::store_little(bytes + 1, value >> 8);
}
};
template <typename T>
struct unrolled_byte_loops<T, 1, false>
{
static T load_big(const unsigned char* bytes)
{ return *(bytes - 1); }
static T load_little(const unsigned char* bytes)
{ return *bytes; }
static void store_big(char* bytes, T value)
{ *(bytes - 1) = static_cast<char>(value); }
static void store_little(char* bytes, T value)
{ *bytes = static_cast<char>(value); }
};
template <typename T>
struct unrolled_byte_loops<T, 1, true>
{
static T load_big(const unsigned char* bytes)
{ return *reinterpret_cast<const signed char*>(bytes - 1); }
static T load_little(const unsigned char* bytes)
{ return *reinterpret_cast<const signed char*>(bytes); }
static void store_big(char* bytes, T value)
{ *(bytes - 1) = static_cast<char>(value); }
static void store_little(char* bytes, T value)
{ *bytes = static_cast<char>(value); }
};
template <typename T, std::size_t n_bytes>
inline
T load_big_endian(const void* bytes)
{
return unrolled_byte_loops<T, n_bytes>::load_big
(static_cast<const unsigned char*>(bytes) + n_bytes);
}
template <typename T, std::size_t n_bytes>
inline
T load_little_endian(const void* bytes)
{
return unrolled_byte_loops<T, n_bytes>::load_little
(static_cast<const unsigned char*>(bytes));
}
template <typename T, std::size_t n_bytes>
inline
void store_big_endian(void* bytes, T value)
{
unrolled_byte_loops<T, n_bytes>::store_big
(static_cast<char*>(bytes) + n_bytes, value);
}
template <typename T, std::size_t n_bytes>
inline
void store_little_endian(void* bytes, T value)
{
unrolled_byte_loops<T, n_bytes>::store_little
(static_cast<char*>(bytes), value);
}
} // namespace detail
namespace integer
{
// endian class template and specializations -----------------------------//
// simulate C++0x scoped enums
namespace endianness { enum enum_t { big, little, native }; }
namespace alignment { enum enum_t { unaligned, aligned }; }
template <endianness::enum_t E, typename T, std::size_t n_bits,
alignment::enum_t A = alignment::unaligned>
class endian;
// Specializations that represent unaligned bytes.
// Taking an integer type as a parameter provides a nice way to pass both
// the size and signedness of the desired integer and get the appropriate
// corresponding integer type for the interface.
template <typename T, std::size_t n_bits>
class endian< endianness::big, T, n_bits, alignment::unaligned >
: cover_operators< endian< endianness::big, T, n_bits >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
typedef T value_type;
endian() {}
endian(T val) { detail::store_big_endian<T, n_bits/8>(bytes, val); }
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(bytes, val); return *this; }
operator T() const { return detail::load_big_endian<T, n_bits/8>(bytes); }
private:
char bytes[n_bits/8];
};
template <typename T, std::size_t n_bits>
class endian< endianness::little, T, n_bits, alignment::unaligned >
: cover_operators< endian< endianness::little, T, n_bits >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
typedef T value_type;
endian() {}
endian(T val) { detail::store_little_endian<T, n_bits/8>(bytes, val); }
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(bytes, val); return *this; }
operator T() const { return detail::load_little_endian<T, n_bits/8>(bytes); }
private:
char bytes[n_bits/8];
};
template <typename T, std::size_t n_bits>
class endian< endianness::native, T, n_bits, alignment::unaligned >
: cover_operators< endian< endianness::native, T, n_bits >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
typedef T value_type;
endian() {}
# ifdef BOOST_BIG_ENDIAN
endian(T val) { detail::store_big_endian<T, n_bits/8>(bytes, val); }
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(bytes, val); return *this; }
operator T() const { return detail::load_big_endian<T, n_bits/8>(bytes); }
# else
endian(T val) { detail::store_little_endian<T, n_bits/8>(bytes, val); }
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(bytes, val); return *this; }
operator T() const { return detail::load_little_endian<T, n_bits/8>(bytes); }
# endif
private:
char bytes[n_bits/8];
};
// Specializations that mimic built-in integer types.
// These typically have the same alignment as the underlying types.
template <typename T, std::size_t n_bits>
class endian< endianness::big, T, n_bits, alignment::aligned >
: cover_operators< endian< endianness::big, T, n_bits, alignment::aligned >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
public:
typedef T value_type;
endian() {}
#ifdef BOOST_BIG_ENDIAN
endian(T val) : integer(val) { }
endian & operator=(T val) { integer = val); return *this; }
operator T() const { return integer; }
#else
endian(T val) { detail::store_big_endian<T, sizeof(T)>(&integer, val); }
endian & operator=(T val) { detail::store_big_endian<T, sizeof(T)>(&integer, val); return *this; }
operator T() const { return detail::load_big_endian<T, sizeof(T)>(&integer); }
#endif
private:
T integer;
};
template <typename T, std::size_t n_bits>
class endian< endianness::little, T, n_bits, alignment::aligned >
: cover_operators< endian< endianness::little, T, n_bits, alignment::aligned >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
public:
typedef T value_type;
endian() {}
#ifdef BOOST_LITTLE_ENDIAN
endian(T val) : integer(val) { }
endian & operator=(T val) { integer = val; return *this; }
operator T() const { return integer; }
#else
endian(T val) { detail::store_little_endian<T, sizeof(T)>(&integer, val); }
endian & operator=(T val) { detail::store_little_endian<T, sizeof(T)>(&integer, val); return *this; }
operator T() const { return detail::load_little_endian<T, sizeof(T)>(&integer); }
#endif
private:
T integer;
};
// naming convention typedefs --------------------------------------------//
// unaligned big endian signed integer types
typedef endian< endianness::big, int_least8_t, 8 > big8_t;
typedef endian< endianness::big, int_least16_t, 16 > big16_t;
typedef endian< endianness::big, int_least32_t, 24 > big24_t;
typedef endian< endianness::big, int_least32_t, 32 > big32_t;
typedef endian< endianness::big, int_least64_t, 40 > big40_t;
typedef endian< endianness::big, int_least64_t, 48 > big48_t;
typedef endian< endianness::big, int_least64_t, 56 > big56_t;
typedef endian< endianness::big, int_least64_t, 64 > big64_t;
// unaligned big endian unsigned integer types
typedef endian< endianness::big, uint_least8_t, 8 > ubig8_t;
typedef endian< endianness::big, uint_least16_t, 16 > ubig16_t;
typedef endian< endianness::big, uint_least32_t, 24 > ubig24_t;
typedef endian< endianness::big, uint_least32_t, 32 > ubig32_t;
typedef endian< endianness::big, uint_least64_t, 40 > ubig40_t;
typedef endian< endianness::big, uint_least64_t, 48 > ubig48_t;
typedef endian< endianness::big, uint_least64_t, 56 > ubig56_t;
typedef endian< endianness::big, uint_least64_t, 64 > ubig64_t;
// unaligned little endian signed integer types
typedef endian< endianness::little, int_least8_t, 8 > little8_t;
typedef endian< endianness::little, int_least16_t, 16 > little16_t;
typedef endian< endianness::little, int_least32_t, 24 > little24_t;
typedef endian< endianness::little, int_least32_t, 32 > little32_t;
typedef endian< endianness::little, int_least64_t, 40 > little40_t;
typedef endian< endianness::little, int_least64_t, 48 > little48_t;
typedef endian< endianness::little, int_least64_t, 56 > little56_t;
typedef endian< endianness::little, int_least64_t, 64 > little64_t;
// unaligned little endian unsigned integer types
typedef endian< endianness::little, uint_least8_t, 8 > ulittle8_t;
typedef endian< endianness::little, uint_least16_t, 16 > ulittle16_t;
typedef endian< endianness::little, uint_least32_t, 24 > ulittle24_t;
typedef endian< endianness::little, uint_least32_t, 32 > ulittle32_t;
typedef endian< endianness::little, uint_least64_t, 40 > ulittle40_t;
typedef endian< endianness::little, uint_least64_t, 48 > ulittle48_t;
typedef endian< endianness::little, uint_least64_t, 56 > ulittle56_t;
typedef endian< endianness::little, uint_least64_t, 64 > ulittle64_t;
// unaligned native endian signed integer types
typedef endian< endianness::native, int_least8_t, 8 > native8_t;
typedef endian< endianness::native, int_least16_t, 16 > native16_t;
typedef endian< endianness::native, int_least32_t, 24 > native24_t;
typedef endian< endianness::native, int_least32_t, 32 > native32_t;
typedef endian< endianness::native, int_least64_t, 40 > native40_t;
typedef endian< endianness::native, int_least64_t, 48 > native48_t;
typedef endian< endianness::native, int_least64_t, 56 > native56_t;
typedef endian< endianness::native, int_least64_t, 64 > native64_t;
// unaligned native endian unsigned integer types
typedef endian< endianness::native, uint_least8_t, 8 > unative8_t;
typedef endian< endianness::native, uint_least16_t, 16 > unative16_t;
typedef endian< endianness::native, uint_least32_t, 24 > unative24_t;
typedef endian< endianness::native, uint_least32_t, 32 > unative32_t;
typedef endian< endianness::native, uint_least64_t, 40 > unative40_t;
typedef endian< endianness::native, uint_least64_t, 48 > unative48_t;
typedef endian< endianness::native, uint_least64_t, 56 > unative56_t;
typedef endian< endianness::native, uint_least64_t, 64 > unative64_t;
#define BOOST_HAS_INT16_T
#define BOOST_HAS_INT32_T
#define BOOST_HAS_INT64_T
// These types only present if platform has exact size integers:
// aligned big endian signed integer types
// aligned big endian unsigned integer types
// aligned little endian signed integer types
// aligned little endian unsigned integer types
// aligned native endian typedefs are not provided because
// <cstdint> types are superior for this use case
# if defined(BOOST_HAS_INT16_T)
typedef endian< endianness::big, int16_t, 16, alignment::aligned > aligned_big16_t;
typedef endian< endianness::big, uint16_t, 16, alignment::aligned > aligned_ubig16_t;
typedef endian< endianness::little, int16_t, 16, alignment::aligned > aligned_little16_t;
typedef endian< endianness::little, uint16_t, 16, alignment::aligned > aligned_ulittle16_t;
# endif
# if defined(BOOST_HAS_INT32_T)
typedef endian< endianness::big, int32_t, 32, alignment::aligned > aligned_big32_t;
typedef endian< endianness::big, uint32_t, 32, alignment::aligned > aligned_ubig32_t;
typedef endian< endianness::little, int32_t, 32, alignment::aligned > aligned_little32_t;
typedef endian< endianness::little, uint32_t, 32, alignment::aligned > aligned_ulittle32_t;
# endif
# if defined(BOOST_HAS_INT64_T)
typedef endian< endianness::big, int64_t, 64, alignment::aligned > aligned_big64_t;
typedef endian< endianness::big, uint64_t, 64, alignment::aligned > aligned_ubig64_t;
typedef endian< endianness::little, int64_t, 64, alignment::aligned > aligned_little64_t;
typedef endian< endianness::little, uint64_t, 64, alignment::aligned > aligned_ulittle64_t;
# endif
} // namespace integer
} // namespace boost
#endif // BOOST_ENDIAN_HPP

View File

@@ -0,0 +1,525 @@
<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>Boost Endian Integers</title>
</head>
<body>
<h1>Boost Endian Integers (<a href="../../../boost/integer/endian.hpp">boost/integer/endian.hpp</a>)</h1>
<p><a href="#Introduction">Introduction</a><br>
<a href="#Limitations">Limitations</a><br>
<a href="#Feature-set">Feature set</a><br>
<a href="#Types">Typedefs</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Comment-on-naming">Comment on naming</a><br>
<a href="#Class_template_endian">Class template <code>endian</code></a><br>
&nbsp;&nbsp;&nbsp;
<a href="#Synopsis">Synopsis</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Members">Members</a><br>
<a href="#FAQ">FAQ</a><br>
<a href="#Example">Example</a><br>
<a href="#Design">Design</a><br>
<a href="#Experience">Experience</a><br>
<a href="#Acknowledgements">Acknowledgements</a></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <a href="../../../boost/integer/endian.hpp">boost/integer/endian.hpp</a> header provides
integer-like byte-holder binary types with explicit 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 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">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&nbsp;as C++ standard integral types, with
the standard semantics, plus operators <code>&lt;&lt;</code> and <code>&gt;&gt;</code> for
stream insertion and extraction.</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>&amp;</code>, <code>&amp;=</code>, <code>|</code>, <code>|=</code>,
<code>^</code>, <code>^=</code>, <code>&lt;&lt;</code>, <code>&lt;&lt;=</code>, <code>&gt;&gt;</code>,
<code>&gt;&gt;=</code>. Binary relational operators are <code>==</code>, <code>!=</code>,
<code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, <code>&gt;=</code>.</p>
<p>Automatic conversion are provided to and from the underlying integer value type.</p>
<h2><a name="Limitations">Limitations</a></h2>
<p>Requires <code>&lt;climits&gt;</code> <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code>
is some other value, compilation will result in an <code>#error</code>. This
restriction is in place because the design, implementation, testing, and
documentation has only considered issues related to 8-bit bytes, and there have
been no real-world use cases presented for other sizes.</p>
<p>In C++03, <code>endian</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++0x, it will be 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++0x, <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>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>
<p>One class template is provided:</p>
<blockquote>
<pre>template &lt;<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&gt;
class endian;
</pre>
</blockquote>
<p>Sixty typedefs, such as <code>big32_t</code>, provide convenient naming
conventions for common use cases:</p>
<blockquote>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="49%">
<tr>
<td width="18%" align="center"><b><i>Name</i></b></td>
<td width="10%" align="center"><b><i>Endianness</i></b></td>
<td width="10%" align="center"><b><i>Sign</i></b></td>
<td width="15%" align="center"><b><i>Sizes in bits (n)</i></b></td>
<td width="49%" align="center"><b><i>Alignment</i></b></td>
</tr>
<tr>
<td width="18%"><code>big</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="15%">16,32,64</td>
<td width="49%"><code>aligned</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="15%">16,32,64</td>
<td width="49%"><code>aligned</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="15%">16,32,64</td>
<td width="49%"><code>aligned</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="15%">16,32,64</td>
<td width="49%"><code>aligned</code></td>
</tr>
</table>
</blockquote>
<p>The unaligned types do not cause compilers to insert padding bytes in classes
and structs. This is an important characteristic that can be exploited to minimize wasted space in
memory, files, and network transmissions. </p>
<p><font color="#FF0000"><b><i><span style="background-color: #FFFFFF">Warning:</span></i></b></font><span style="background-color: #FFFFFF">
Code that uses a</span>ligned types is 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>
<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>&lt;cstdint&gt;</code> types. Using that model, it is natural to
expect a 56-bit big-endian signed integer to be named <code>int_big56_t</code>
rather than <code>big56_t</code>.</p>
<p>As experience using these type grows, the realization creeps in that they are
lousy arithmetic integers - they are really byte holders that for convenience
support arithmetic operations - and that for use in internal interfaces or
anything more than trivial arithmetic computations it is far better to convert
values of these endian types to traditional integer types.</p>
<p>That seems to lead to formation of a new mental model specific to endian byte-holder types. In that model, the endianness
is the key feature, and the integer aspect is downplayed.
Once that mental transition is made, a name like <code>big56_t</code> is a good
reflection of the mental model</p>
<h2><a name="Class_template_endian">Class template <code>endian</code></a></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 integer
{
namespace <a name="endianness">endianness</a> { enum enum_t { big, little, native }; } // simulate C++0x scoped enum
namespace <a name="alignment">alignment</a> { enum enum_t { unaligned, aligned }; } // simulate C++0x scoped enum
template &lt;endianness::enum_t E, typename T, std::size_t n_bits,
alignment::enum_t A = alignment::unaligned&gt;
class endian : <a href="../../../boost/integer/cover_operators.hpp">integer_cover_operators</a>&lt; endian&lt;E, T, n_bits, A&gt;, T &gt;
{
public:
typedef T value_type;
endian(){}
endian(T v);
endian &amp; operator=(T v);
operator T() const;
};
// unaligned big endian signed integer types
typedef endian&lt; endianness::big, int_least8_t, 8 &gt; big8_t;
typedef endian&lt; endianness::big, int_least16_t, 16 &gt; big16_t;
typedef endian&lt; endianness::big, int_least32_t, 24 &gt; big24_t;
typedef endian&lt; endianness::big, int_least32_t, 32 &gt; big32_t;
typedef endian&lt; endianness::big, int_least64_t, 40 &gt; big40_t;
typedef endian&lt; endianness::big, int_least64_t, 48 &gt; big48_t;
typedef endian&lt; endianness::big, int_least64_t, 56 &gt; big56_t;
typedef endian&lt; endianness::big, int_least64_t, 64 &gt; big64_t;
// unaligned big endian unsigned integer types
typedef endian&lt; endianness::big, uint_least8_t, 8 &gt; ubig8_t;
typedef endian&lt; endianness::big, uint_least16_t, 16 &gt; ubig16_t;
typedef endian&lt; endianness::big, uint_least32_t, 24 &gt; ubig24_t;
typedef endian&lt; endianness::big, uint_least32_t, 32 &gt; ubig32_t;
typedef endian&lt; endianness::big, uint_least64_t, 40 &gt; ubig40_t;
typedef endian&lt; endianness::big, uint_least64_t, 48 &gt; ubig48_t;
typedef endian&lt; endianness::big, uint_least64_t, 56 &gt; ubig56_t;
typedef endian&lt; endianness::big, uint_least64_t, 64 &gt; ubig64_t;
// unaligned little endian signed integer types
typedef endian&lt; endianness::little, int_least8_t, 8 &gt; little8_t;
typedef endian&lt; endianness::little, int_least16_t, 16 &gt; little16_t;
typedef endian&lt; endianness::little, int_least32_t, 24 &gt; little24_t;
typedef endian&lt; endianness::little, int_least32_t, 32 &gt; little32_t;
typedef endian&lt; endianness::little, int_least64_t, 40 &gt; little40_t;
typedef endian&lt; endianness::little, int_least64_t, 48 &gt; little48_t;
typedef endian&lt; endianness::little, int_least64_t, 56 &gt; little56_t;
typedef endian&lt; endianness::little, int_least64_t, 64 &gt; little64_t;
// unaligned little endian unsigned integer types
typedef endian&lt; endianness::little, uint_least8_t, 8 &gt; ulittle8_t;
typedef endian&lt; endianness::little, uint_least16_t, 16 &gt; ulittle16_t;
typedef endian&lt; endianness::little, uint_least32_t, 24 &gt; ulittle24_t;
typedef endian&lt; endianness::little, uint_least32_t, 32 &gt; ulittle32_t;
typedef endian&lt; endianness::little, uint_least64_t, 40 &gt; ulittle40_t;
typedef endian&lt; endianness::little, uint_least64_t, 48 &gt; ulittle48_t;
typedef endian&lt; endianness::little, uint_least64_t, 56 &gt; ulittle56_t;
typedef endian&lt; endianness::little, uint_least64_t, 64 &gt; ulittle64_t;
// unaligned native endian signed integer types
typedef endian&lt; endianness::native, int_least8_t, 8 &gt; native8_t;
typedef endian&lt; endianness::native, int_least16_t, 16 &gt; native16_t;
typedef endian&lt; endianness::native, int_least32_t, 24 &gt; native24_t;
typedef endian&lt; endianness::native, int_least32_t, 32 &gt; native32_t;
typedef endian&lt; endianness::native, int_least64_t, 40 &gt; native40_t;
typedef endian&lt; endianness::native, int_least64_t, 48 &gt; native48_t;
typedef endian&lt; endianness::native, int_least64_t, 56 &gt; native56_t;
typedef endian&lt; endianness::native, int_least64_t, 64 &gt; native64_t;
// unaligned native endian unsigned integer types
typedef endian&lt; endianness::native, uint_least8_t, 8 &gt; unative8_t;
typedef endian&lt; endianness::native, uint_least16_t, 16 &gt; unative16_t;
typedef endian&lt; endianness::native, uint_least32_t, 24 &gt; unative24_t;
typedef endian&lt; endianness::native, uint_least32_t, 32 &gt; unative32_t;
typedef endian&lt; endianness::native, uint_least64_t, 40 &gt; unative40_t;
typedef endian&lt; endianness::native, uint_least64_t, 48 &gt; unative48_t;
typedef endian&lt; endianness::native, uint_least64_t, 56 &gt; unative56_t;
typedef endian&lt; endianness::native, uint_least64_t, 64 &gt; unative64_t;
// These types only present if platform has exact size integers:
// aligned big endian signed integer types
typedef endian&lt; endianness::big, int16_t, 16, alignment::aligned &gt; aligned_big16_t;
typedef endian&lt; endianness::big, int32_t, 32, alignment::aligned &gt; aligned_big32_t;
typedef endian&lt; endianness::big, int64_t, 64, alignment::aligned &gt; aligned_big64_t;
// aligned big endian unsigned integer types
typedef endian&lt; endianness::big, uint16_t, 16, alignment::aligned &gt; aligned_ubig16_t;
typedef endian&lt; endianness::big, uint32_t, 32, alignment::aligned &gt; aligned_ubig32_t;
typedef endian&lt; endianness::big, uint64_t, 64, alignment::aligned &gt; aligned_ubig64_t;
// aligned little endian signed integer types
typedef endian&lt; endianness::little, int16_t, 16, alignment::aligned &gt; aligned_little2_t;
typedef endian&lt; endianness::little, int32_t, 32, alignment::aligned &gt; aligned_little4_t;
typedef endian&lt; endianness::little, int64_t, 64, alignment::aligned &gt; aligned_little8_t;
// aligned little endian unsigned integer types
typedef endian&lt; endianness::little, uint16_t, 16, alignment::aligned &gt; aligned_ulittle2_t;
typedef endian&lt; endianness::little, uint32_t, 32, alignment::aligned &gt; aligned_ulittle4_t;
typedef endian&lt; endianness::little, uint64_t, 64, alignment::aligned &gt; aligned_ulittle8_t;
// aligned native endian typedefs are not provided because
// &lt;cstdint&gt; types are superior for this use case
} // namespace integer
} // namespace boost</pre>
<h3><a name="Members">Members</a></h3>
<p><code>endian(){}</code></p>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>endian&lt;E, T, n_bits, A&gt;</code>.</p>
</blockquote>
<p><code>endian(T v);</code></p>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>endian&lt;E, T, n_bits, A&gt;</code>.</p>
<p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the
constructed object.</p>
</blockquote>
<p><code>endian &amp; operator=(T v);</code></p>
<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>
<p><code>operator T() const;</code></p>
<blockquote>
<p><i>Returns:</i> The current value stored in <code>*this</code>, converted to
<code>value_type</code>.</p>
</blockquote>
<h3>Other operators</h3>
<p>All other operators on endian objects are forwarded to the equivalent
operator on <code>value_type</code>.</p>
<h2><a name="FAQ">FAQ</a></h2>
<p><b>Why bother with endian types?</b> External data portability and both speed
and space efficiency. Availability
of additional binary integer sizes and alignments is important in some
applications.</p>
<p><b>Why not just use Boost.Serialization?</b> Serialization involves a
conversion for every object involved in I/O. Endian objects 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>Why bother with binary I/O? Why not just use C++ Standard Library stream
inserters and extractors?</b> Using binary rather than character representations
can be more space efficient, with a side benefit of faster I/O. CPU time is
minimized because conversions to and from string are eliminated.
Furthermore, binary integers are fixed size, and so fixed-size disk records
are possible, easing sorting and allowing direct access. Disadvantages, such as the inability to use
text utilities on the resulting files, limit usefulness to applications where
the
binary I/O advantages are paramount.</p>
<p><b>Do these types have any uses outside of I/O?</b> Probably not, except for
native endianness which can be used for fine grained control over size and
alignment.</p>
<p><b>Is there is a performance hit when doing arithmetic using these types?</b> Yes, for sure,
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
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>
<p><b>Which is better, big-endian or little-endian?</b> Big-endian tends to be a
bit more of an industry standard, but little-endian may be preferred for
applications that run primarily on x86 (Intel/AMD) and other little-endian
CPU's. The <a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> article
gives more pros and cons.</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 (20 times, in one measurement) if the endianness and alignment of
the type matches the endianness and alignment requirements of the machine. On
common CPU architectures, that optimization is only available for aligned types.
That allows I/O of maximally efficient types on an application's primary
platform, yet produces data files are portable to all platforms. The code,
however, is
likely to be more fragile and less portable than with the unaligned types.</p>
<p><b>These types are really just byte-holders. Why provide the arithmetic
operations at all?</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="Example">Example</a></h2>
<p>The <a href="../example/endian_example.cpp">endian_example.cpp</a> program writes a
binary file containing four byte big-endian and little-endian integers:</p>
<blockquote>
<pre>#include &lt;iostream&gt;
#include &lt;cassert&gt;
#include &lt;cstdio&gt;
#include &lt;boost/integer/endian.hpp&gt;
using boost::integer::big32_t;
using boost::integer::little32_t;
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.
struct header
{
big32_t file_code;
big32_t file_length;
little32_t version;
little32_t shape_type;
};
const char * filename = &quot;test.dat&quot;;
}
int main()
{
assert( sizeof( header ) == 16 );
header h;
h.file_code = 0x04030201;
h.file_length = sizeof( header );
h.version = -1;
h.shape_type = 0x04030201;
// Low-level I/O such as POSIX read/write or &lt;cstdio&gt; 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, &lt;cstdio&gt; fopen/fwrite is used
// for I/O in this example.
std::FILE * fi;
if ( !(fi = std::fopen( filename, &quot;wb&quot; )) )
{
std::cout &lt;&lt; &quot;could not open &quot; &lt;&lt; filename &lt;&lt; '\n';
return 1;
}
if ( std::fwrite( &amp;h, sizeof( header ), 1, fi ) != 1 )
{
std::cout &lt;&lt; &quot;write failure for &quot; &lt;&lt; filename &lt;&lt; '\n';
return 1;
}
std::fclose( fi );
std::cout &lt;&lt; &quot;created file &quot; &lt;&lt; filename &lt;&lt; '\n';
return 0;
}</pre>
</blockquote>
<p>After compiling and executing <a href="endian_example.cpp">endian_example.cpp</a>, a hex dump of <code>test.dat</code> shows:</p>
<blockquote>
<pre>0403 0201 0000 0010 ffff ffff 0102 0304</pre>
</blockquote>
<h2><a name="Design">Design</a> considerations for Boost.Endian</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 only in very limited
circumstances. Experience has shown that optimizations of endian
integers often become pessimizations. While this may be obvious when changing
machines or compilers, it also happens when changing compiler switches,
compiler versions, or CPU models of the same architecture.</li>
<li>It is better software engineering if the same implementation works regardless
of the CPU endianness. In other words, #ifdefs should be avoided where
possible.</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 integers have proven widely useful across a wide
range of computer architectures and applications.</p>
<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, and added the typedefs. He 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.</p>
<p>Comments and suggestions were
received from
Benaka Moorthi,
Christopher Kohlhoff,
Cliff Green,
Gennaro Proto,
Jeff Flinn,
John Maddock,
Kim Barrett,
Marsh Ray,
Martin Bonner,
Matias Capeletto,
Rene Rivera,
Scott McMurray,
Sebastian Redl,
Tomas Puverle, and
Yuval Ronen.</p>
<hr>
<p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->26 May, 2008<!--webbot bot="Timestamp" endspan i-checksum="14024" --></p>
<p><EFBFBD> Copyright Beman Dawes, 2006</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>
</body>
</html>

View File

@@ -0,0 +1,75 @@
// endian_example.cpp -------------------------------------------------------//
// 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)
// See library home page at http://www.boost.org/libs/endian
//----------------------------------------------------------------------------//
#define _CRT_SECURE_NO_DEPRECATE // quiet VC++ 8.0 foolishness
#include <iostream>
#include <cassert>
#include <cstdio>
#include <boost/integer/endian.hpp>
using boost::integer::big32_t;
using boost::integer::little32_t;
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
// 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;
};
const char * filename = "test.dat";
}
int main()
{
assert( sizeof( header ) == 16 );
header h;
h.file_code = 0x04030201;
h.file_length = sizeof( header );
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.
std::FILE * fi;
if ( !(fi = std::fopen( filename, "wb" )) )
{
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;
}

View File

@@ -0,0 +1,13 @@
# Boost Endian Library test Jamfile
# 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)
# See library home page at http://www.boost.org/libs/endian
test-suite "endian"
: [ run libs/integer/test/endian_test.cpp ]
;

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="common"
OutputDirectory="$(TEMP)\$(SolutionName)\$(ConfigurationName)"
IntermediateDirectory="$(TEMP)\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(BOOST_SANDBOX)\endian&quot;;&quot;$(BOOST_TRUNK)&quot;"
/>
</VisualStudioPropertySheet>

View File

@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endian_test", "endian_test\endian_test.vcproj", "{74C201F3-8308-40BE-BC0F-24974DEAF405}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{74C201F3-8308-40BE-BC0F-24974DEAF405}.Debug|Win32.ActiveCfg = Debug|Win32
{74C201F3-8308-40BE-BC0F-24974DEAF405}.Debug|Win32.Build.0 = Debug|Win32
{74C201F3-8308-40BE-BC0F-24974DEAF405}.Release|Win32.ActiveCfg = Release|Win32
{74C201F3-8308-40BE-BC0F-24974DEAF405}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,193 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="endian_test"
ProjectGUID="{74C201F3-8308-40BE-BC0F-24974DEAF405}"
RootNamespace="endian_test"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
ConfigurationType="1"
InheritedPropertySheets="..\common.vsprops"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="..\common.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\..\endian_test.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,593 @@
// endian_test.cpp ---------------------------------------------------------//
// Copyright Beman Dawes, 1999-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)
// See library home page at http://www.boost.org/libs/endian
//----------------------------------------------------------------------------//
#include <boost/integer/endian.hpp>
#include <boost/cstdint.hpp>
#include <boost/progress.hpp>
#include <iostream>
#include <limits>
#include <climits>
#include <cstdlib> // for atoi(), exit()
#include <cstring> // for memcmp()
using namespace std; // not the best programming practice, but I
using namespace boost; // want to verify this combination of using
using namespace boost::integer; // namespaces works.
#define VERIFY(predicate) verify( predicate, __LINE__ )
#define VERIFY_SIZE(actual, expected) verify_size( actual, expected, __LINE__ )
#define VERIFY_VALUE_AND_OPS(endian_t,expected_t,expected) verify_value_and_ops<endian_t, expected_t>( expected, __LINE__ )
#define VERIFY_BIG_REPRESENTATION(t) verify_representation<t>( true, __LINE__ )
#define VERIFY_LITTLE_REPRESENTATION(t) verify_representation<t>( false, __LINE__ )
#define VERIFY_NATIVE_REPRESENTATION(t) verify_native_representation<t>( __LINE__ )
namespace
{
int err_count;
void verify( bool x, int line )
{
if ( x ) return;
++err_count;
cout << "Error: verify failed on line " << line << endl;
}
void verify_size( size_t actual, size_t expected, int line )
{
if ( actual == expected ) return;
++err_count;
cout << "Error: verify failed on line " << line << endl;
cout << " A structure with an expected sizeof() " << expected
<< " had an actual sizeof() " << actual
<< "\n This will cause common uses of <boost/endian.hpp> to fail\n";
}
template <class Endian, class Base>
void verify_value_and_ops( const Base & expected, int line )
{
Endian v( expected );
verify( v == expected, line );
Endian v2;
v2.operator=( expected );
verify( v2 == expected, line );
++v; // verify integer_cover_operators being applied to this type -
// will fail to compile if no endian<> specialization is present
}
const char * big_rep = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0";
const char * little_rep = "\xF0\xDE\xBC\x9A\x78\x56\x34\x12";
template <class Endian>
void verify_representation( bool is_big, int line )
{
int silence = 0;
Endian x = static_cast<typename Endian::value_type>
(0x123456789abcdef0LL + silence); // will truncate
if ( is_big )
verify( memcmp( &x,
reinterpret_cast<const char*>(big_rep)+8-sizeof(Endian),
sizeof(Endian) ) == 0, line );
else
verify( memcmp( &x, little_rep, sizeof(Endian) ) == 0, line );
}
template <class Endian>
inline void verify_native_representation( int line )
{
# ifdef BOOST_BIG_ENDIAN
verify_representation<Endian>( true, line );
# else
verify_representation<Endian>( false, line );
# endif
}
// detect_endianness -----------------------------------------------------//
void detect_endianness()
{
union View
{
long long i;
unsigned char c[8];
};
View v = { 0x0102030405060708LL }; // initialize v.i
if ( memcmp( v.c, "\10\7\6\5\4\3\2\1", 8) == 0 )
{
cout << "This machine is little-endian.\n";
# ifdef BOOST_BIG_INTEGER_OPERATORS
cout << "yet boost/detail/endian.hpp defines BOOST_BIG_INTEGER_OPERATORS.\n"
"You must fix boost/detail/endian.hpp for boost/endian.hpp to work correctly.\n"
"Please report the fix to the Boost mailing list.\n";
exit(1);
# endif
}
else if ( memcmp( v.c, "\1\2\3\4\5\6\7\10", 8) == 0 )
{
cout << "This machine is big-endian.\n";
# ifdef BOOST_LITTLE_INTEGER_OPERATORS
cout << "yet boost/detail/endian.hpp defines BOOST__LITTLE_INTEGER_OPERATORS.\n"
"You must fix boost/detail/endian.hpp for boost/endian.hpp to work correctly.\n"
"Please report the fix to the Boost mailing list.\n";
exit(1);
# endif
}
else
{
cout << "This machine is neither strict big-endian nor strict little-endian\n"
"You must modify boost/endian.hpp for it to work correctly.\n";
exit(1);
}
cout << "That should not matter and is presented for your information only.\n";
} // detect_endianness
// check_size ------------------------------------------------------------//
void check_size()
{
VERIFY( numeric_limits<signed char>::digits == 7 );
VERIFY( numeric_limits<unsigned char>::digits == 8 );
VERIFY( sizeof( big8_t ) == 1 );
VERIFY( sizeof( big16_t ) == 2 );
VERIFY( sizeof( big24_t ) == 3 );
VERIFY( sizeof( big32_t ) == 4 );
VERIFY( sizeof( big40_t ) == 5 );
VERIFY( sizeof( big48_t ) == 6 );
VERIFY( sizeof( big56_t ) == 7 );
VERIFY( sizeof( big64_t ) == 8 );
VERIFY( sizeof( ubig8_t ) == 1 );
VERIFY( sizeof( ubig16_t ) == 2 );
VERIFY( sizeof( ubig24_t ) == 3 );
VERIFY( sizeof( ubig32_t ) == 4 );
VERIFY( sizeof( ubig40_t ) == 5 );
VERIFY( sizeof( ubig48_t ) == 6 );
VERIFY( sizeof( ubig56_t ) == 7 );
VERIFY( sizeof( ubig64_t ) == 8 );
VERIFY( sizeof( little8_t ) == 1 );
VERIFY( sizeof( little16_t ) == 2 );
VERIFY( sizeof( little24_t ) == 3 );
VERIFY( sizeof( little32_t ) == 4 );
VERIFY( sizeof( little40_t ) == 5 );
VERIFY( sizeof( little48_t ) == 6 );
VERIFY( sizeof( little56_t ) == 7 );
VERIFY( sizeof( little64_t ) == 8 );
VERIFY( sizeof( ulittle8_t ) == 1 );
VERIFY( sizeof( ulittle16_t ) == 2 );
VERIFY( sizeof( ulittle24_t ) == 3 );
VERIFY( sizeof( ulittle32_t ) == 4 );
VERIFY( sizeof( ulittle40_t ) == 5 );
VERIFY( sizeof( ulittle48_t ) == 6 );
VERIFY( sizeof( ulittle56_t ) == 7 );
VERIFY( sizeof( ulittle64_t ) == 8 );
VERIFY( sizeof( native8_t ) == 1 );
VERIFY( sizeof( native16_t ) == 2 );
VERIFY( sizeof( native24_t ) == 3 );
VERIFY( sizeof( native32_t ) == 4 );
VERIFY( sizeof( native40_t ) == 5 );
VERIFY( sizeof( native48_t ) == 6 );
VERIFY( sizeof( native56_t ) == 7 );
VERIFY( sizeof( native64_t ) == 8 );
VERIFY( sizeof( unative8_t ) == 1 );
VERIFY( sizeof( unative16_t ) == 2 );
VERIFY( sizeof( unative24_t ) == 3 );
VERIFY( sizeof( unative32_t ) == 4 );
VERIFY( sizeof( unative40_t ) == 5 );
VERIFY( sizeof( unative48_t ) == 6 );
VERIFY( sizeof( unative56_t ) == 7 );
VERIFY( sizeof( unative64_t ) == 8 );
VERIFY( sizeof( aligned_big16_t ) == 2 );
VERIFY( sizeof( aligned_big32_t ) == 4 );
VERIFY( sizeof( aligned_big64_t ) == 8 );
VERIFY( sizeof( aligned_ubig16_t ) == 2 );
VERIFY( sizeof( aligned_ubig32_t ) == 4 );
VERIFY( sizeof( aligned_ubig64_t ) == 8 );
VERIFY( sizeof( aligned_little16_t ) == 2 );
VERIFY( sizeof( aligned_little32_t ) == 4 );
VERIFY( sizeof( aligned_little64_t ) == 8 );
VERIFY( sizeof( aligned_ulittle16_t ) == 2 );
VERIFY( sizeof( aligned_ulittle32_t ) == 4 );
VERIFY( sizeof( aligned_ulittle64_t ) == 8 );
} // check_size
// check_alignment -------------------------------------------------------//
void check_alignment()
{
// structs with offsets % 2 == 1 for type of size > 1 to ensure no alignment
// bytes added for any size > 1
struct big_struct
{
big8_t v0;
big16_t v1;
big24_t v3;
char v6;
big32_t v7;
big40_t v11;
char v16;
big48_t v17;
big56_t v23;
char v30;
big64_t v31;
};
struct ubig_struct
{
ubig8_t v0;
ubig16_t v1;
ubig24_t v3;
char v6;
ubig32_t v7;
ubig40_t v11;
char v16;
ubig48_t v17;
ubig56_t v23;
char v30;
ubig64_t v31;
};
struct little_struct
{
little8_t v0;
little16_t v1;
little24_t v3;
char v6;
little32_t v7;
little40_t v11;
char v16;
little48_t v17;
little56_t v23;
char v30;
little64_t v31;
};
struct ulittle_struct
{
ulittle8_t v0;
ulittle16_t v1;
ulittle24_t v3;
char v6;
ulittle32_t v7;
ulittle40_t v11;
char v16;
ulittle48_t v17;
ulittle56_t v23;
char v30;
ulittle64_t v31;
};
struct native_struct
{
native8_t v0;
native16_t v1;
native24_t v3;
char v6;
native32_t v7;
native40_t v11;
char v16;
native48_t v17;
native56_t v23;
char v30;
native64_t v31;
};
struct unative_struct
{
unative8_t v0;
unative16_t v1;
unative24_t v3;
char v6;
unative32_t v7;
unative40_t v11;
char v16;
unative48_t v17;
unative56_t v23;
char v30;
unative64_t v31;
};
int saved_err_count = err_count;
VERIFY_SIZE( sizeof(big_struct), 39 );
VERIFY_SIZE( sizeof(ubig_struct), 39 );
VERIFY_SIZE( sizeof(little_struct), 39 );
VERIFY_SIZE( sizeof(ulittle_struct), 39 );
VERIFY_SIZE( sizeof(native_struct), 39 );
VERIFY_SIZE( sizeof(unative_struct), 39 );
if ( saved_err_count == err_count )
{
cout <<
"Size and alignment for structures of endian types are as expected.\n";
}
} // check_alignment
// check_representation_and_range_and_ops --------------------------------//
void check_representation_and_range_and_ops()
{
VERIFY_BIG_REPRESENTATION( big8_t );
VERIFY_VALUE_AND_OPS( big8_t, int_least8_t, 0x7f );
VERIFY_VALUE_AND_OPS( big8_t, int_least8_t, -0x80 );
VERIFY_BIG_REPRESENTATION( big16_t );
VERIFY_VALUE_AND_OPS( big16_t, int_least16_t, 0x7fff );
VERIFY_VALUE_AND_OPS( big16_t, int_least16_t, -0x8000 );
VERIFY_BIG_REPRESENTATION( big24_t );
VERIFY_VALUE_AND_OPS( big24_t, int_least32_t, 0x7fffff );
VERIFY_VALUE_AND_OPS( big24_t, int_least32_t, -0x800000 );
VERIFY_BIG_REPRESENTATION( big32_t );
VERIFY_VALUE_AND_OPS( big32_t, int_least32_t, 0x7fffffff );
VERIFY_VALUE_AND_OPS( big32_t, int_least32_t, -0x7fffffff-1 );
VERIFY_BIG_REPRESENTATION( big40_t );
VERIFY_VALUE_AND_OPS( big40_t, int_least64_t, 0x7fffffffffLL );
VERIFY_VALUE_AND_OPS( big40_t, int_least64_t, -0x8000000000LL );
VERIFY_BIG_REPRESENTATION( big48_t );
VERIFY_VALUE_AND_OPS( big48_t, int_least64_t, 0x7fffffffffffLL );
VERIFY_VALUE_AND_OPS( big48_t, int_least64_t, -0x800000000000LL );
VERIFY_BIG_REPRESENTATION( big56_t );
VERIFY_VALUE_AND_OPS( big56_t, int_least64_t, 0x7fffffffffffffLL );
VERIFY_VALUE_AND_OPS( big56_t, int_least64_t, -0x80000000000000LL );
VERIFY_BIG_REPRESENTATION( big64_t );
VERIFY_VALUE_AND_OPS( big64_t, int_least64_t, 0x7fffffffffffffffLL );
VERIFY_VALUE_AND_OPS( big64_t, int_least64_t, -0x7fffffffffffffffLL-1 );
VERIFY_BIG_REPRESENTATION( ubig8_t );
VERIFY_VALUE_AND_OPS( ubig8_t, uint_least8_t, 0xff );
VERIFY_BIG_REPRESENTATION( ubig16_t );
VERIFY_VALUE_AND_OPS( ubig16_t, uint_least16_t, 0xffff );
VERIFY_BIG_REPRESENTATION( ubig24_t );
VERIFY_VALUE_AND_OPS( ubig24_t, uint_least32_t, 0xffffff );
VERIFY_BIG_REPRESENTATION( ubig32_t );
VERIFY_VALUE_AND_OPS( ubig32_t, uint_least32_t, 0xffffffff );
VERIFY_BIG_REPRESENTATION( ubig40_t );
VERIFY_VALUE_AND_OPS( ubig40_t, uint_least64_t, 0xffffffffffLL );
VERIFY_BIG_REPRESENTATION( ubig48_t );
VERIFY_VALUE_AND_OPS( ubig48_t, uint_least64_t, 0xffffffffffffLL );
VERIFY_BIG_REPRESENTATION( ubig56_t );
VERIFY_VALUE_AND_OPS( ubig56_t, uint_least64_t, 0xffffffffffffffLL );
VERIFY_BIG_REPRESENTATION( ubig64_t );
VERIFY_VALUE_AND_OPS( ubig64_t, uint_least64_t, 0xffffffffffffffffLL );
VERIFY_LITTLE_REPRESENTATION( little8_t );
VERIFY_VALUE_AND_OPS( little8_t, int_least8_t, 0x7f );
VERIFY_VALUE_AND_OPS( little8_t, int_least8_t, -0x80 );
VERIFY_LITTLE_REPRESENTATION( little16_t );
VERIFY_VALUE_AND_OPS( little16_t, int_least16_t, 0x7fff );
VERIFY_VALUE_AND_OPS( little16_t, int_least16_t, -0x8000 );
VERIFY_LITTLE_REPRESENTATION( little24_t );
VERIFY_VALUE_AND_OPS( little24_t, int_least32_t, 0x7fffff );
VERIFY_VALUE_AND_OPS( little24_t, int_least32_t, -0x800000 );
VERIFY_LITTLE_REPRESENTATION( little32_t );
VERIFY_VALUE_AND_OPS( little32_t, int_least32_t, 0x7fffffff );
VERIFY_VALUE_AND_OPS( little32_t, int_least32_t, -0x7fffffff-1 );
VERIFY_LITTLE_REPRESENTATION( little40_t );
VERIFY_VALUE_AND_OPS( little40_t, int_least64_t, 0x7fffffffffLL );
VERIFY_VALUE_AND_OPS( little40_t, int_least64_t, -0x8000000000LL );
VERIFY_LITTLE_REPRESENTATION( little48_t );
VERIFY_VALUE_AND_OPS( little48_t, int_least64_t, 0x7fffffffffffLL );
VERIFY_VALUE_AND_OPS( little48_t, int_least64_t, -0x800000000000LL );
VERIFY_LITTLE_REPRESENTATION( little56_t );
VERIFY_VALUE_AND_OPS( little56_t, int_least64_t, 0x7fffffffffffffLL );
VERIFY_VALUE_AND_OPS( little56_t, int_least64_t, -0x80000000000000LL );
VERIFY_LITTLE_REPRESENTATION( little64_t );
VERIFY_VALUE_AND_OPS( little64_t, int_least64_t, 0x7fffffffffffffffLL );
VERIFY_VALUE_AND_OPS( little64_t, int_least64_t, -0x7fffffffffffffffLL-1 );
VERIFY_LITTLE_REPRESENTATION( ulittle8_t );
VERIFY_VALUE_AND_OPS( ulittle8_t, uint_least8_t, 0xff );
VERIFY_LITTLE_REPRESENTATION( ulittle16_t );
VERIFY_VALUE_AND_OPS( ulittle16_t, uint_least16_t, 0xffff );
VERIFY_LITTLE_REPRESENTATION( ulittle24_t );
VERIFY_VALUE_AND_OPS( ulittle24_t, uint_least32_t, 0xffffff );
VERIFY_LITTLE_REPRESENTATION( ulittle32_t );
VERIFY_VALUE_AND_OPS( ulittle32_t, uint_least32_t, 0xffffffff );
VERIFY_LITTLE_REPRESENTATION( ulittle40_t );
VERIFY_VALUE_AND_OPS( ulittle40_t, uint_least64_t, 0xffffffffffLL );
VERIFY_LITTLE_REPRESENTATION( ulittle48_t );
VERIFY_VALUE_AND_OPS( ulittle48_t, uint_least64_t, 0xffffffffffffLL );
VERIFY_LITTLE_REPRESENTATION( ulittle56_t );
VERIFY_VALUE_AND_OPS( ulittle56_t, uint_least64_t, 0xffffffffffffffLL );
VERIFY_LITTLE_REPRESENTATION( ulittle64_t );
VERIFY_VALUE_AND_OPS( ulittle64_t, uint_least64_t, 0xffffffffffffffffLL );
VERIFY_NATIVE_REPRESENTATION( native8_t );
VERIFY_VALUE_AND_OPS( native8_t, int_least8_t, 0x7f );
VERIFY_VALUE_AND_OPS( native8_t, int_least8_t, -0x80 );
VERIFY_NATIVE_REPRESENTATION( native16_t );
VERIFY_VALUE_AND_OPS( native16_t, int_least16_t, 0x7fff );
VERIFY_VALUE_AND_OPS( native16_t, int_least16_t, -0x8000 );
VERIFY_NATIVE_REPRESENTATION( native24_t );
VERIFY_VALUE_AND_OPS( native24_t, int_least32_t, 0x7fffff );
VERIFY_VALUE_AND_OPS( native24_t, int_least32_t, -0x800000 );
VERIFY_NATIVE_REPRESENTATION( native32_t );
VERIFY_VALUE_AND_OPS( native32_t, int_least32_t, 0x7fffffff );
VERIFY_VALUE_AND_OPS( native32_t, int_least32_t, -0x7fffffff-1 );
VERIFY_NATIVE_REPRESENTATION( native40_t );
VERIFY_VALUE_AND_OPS( native40_t, int_least64_t, 0x7fffffffffLL );
VERIFY_VALUE_AND_OPS( native40_t, int_least64_t, -0x8000000000LL );
VERIFY_NATIVE_REPRESENTATION( native48_t );
VERIFY_VALUE_AND_OPS( native48_t, int_least64_t, 0x7fffffffffffLL );
VERIFY_VALUE_AND_OPS( native48_t, int_least64_t, -0x800000000000LL );
VERIFY_NATIVE_REPRESENTATION( native56_t );
VERIFY_VALUE_AND_OPS( native56_t, int_least64_t, 0x7fffffffffffffLL );
VERIFY_VALUE_AND_OPS( native56_t, int_least64_t, -0x80000000000000LL );
VERIFY_NATIVE_REPRESENTATION( native64_t );
VERIFY_VALUE_AND_OPS( native64_t, int_least64_t, 0x7fffffffffffffffLL );
VERIFY_VALUE_AND_OPS( native64_t, int_least64_t, -0x7fffffffffffffffLL-1 );
VERIFY_NATIVE_REPRESENTATION( unative8_t );
VERIFY_VALUE_AND_OPS( unative8_t, uint_least8_t, 0xff );
VERIFY_NATIVE_REPRESENTATION( unative16_t );
VERIFY_VALUE_AND_OPS( unative16_t, uint_least16_t, 0xffff );
VERIFY_NATIVE_REPRESENTATION( unative24_t );
VERIFY_VALUE_AND_OPS( unative24_t, uint_least32_t, 0xffffff );
VERIFY_NATIVE_REPRESENTATION( unative32_t );
VERIFY_VALUE_AND_OPS( unative32_t, uint_least32_t, 0xffffffff );
VERIFY_NATIVE_REPRESENTATION( unative40_t );
VERIFY_VALUE_AND_OPS( unative40_t, uint_least64_t, 0xffffffffffLL );
VERIFY_NATIVE_REPRESENTATION( unative48_t );
VERIFY_VALUE_AND_OPS( unative48_t, uint_least64_t, 0xffffffffffffLL );
VERIFY_NATIVE_REPRESENTATION( unative56_t );
VERIFY_VALUE_AND_OPS( unative56_t, uint_least64_t, 0xffffffffffffffLL );
VERIFY_NATIVE_REPRESENTATION( unative64_t );
VERIFY_VALUE_AND_OPS( unative64_t, uint_least64_t, 0xffffffffffffffffLL );
VERIFY_BIG_REPRESENTATION( aligned_big16_t );
VERIFY_VALUE_AND_OPS( aligned_big16_t, int_least16_t, 0x7fff );
VERIFY_VALUE_AND_OPS( aligned_big16_t, int_least16_t, -0x8000 );
VERIFY_BIG_REPRESENTATION( aligned_big32_t );
VERIFY_VALUE_AND_OPS( aligned_big32_t, int_least32_t, 0x7fffffff );
VERIFY_VALUE_AND_OPS( aligned_big32_t, int_least32_t, -0x7fffffff-1 );
VERIFY_BIG_REPRESENTATION( aligned_big64_t );
VERIFY_VALUE_AND_OPS( aligned_big64_t, int_least64_t, 0x7fffffffffffffffLL );
VERIFY_VALUE_AND_OPS( aligned_big64_t, int_least64_t, -0x7fffffffffffffffLL-1 );
VERIFY_BIG_REPRESENTATION( aligned_ubig16_t );
VERIFY_VALUE_AND_OPS( aligned_ubig16_t, uint_least16_t, 0xffff );
VERIFY_BIG_REPRESENTATION( aligned_ubig32_t );
VERIFY_VALUE_AND_OPS( aligned_ubig32_t, uint_least32_t, 0xffffffff );
VERIFY_BIG_REPRESENTATION( aligned_ubig64_t );
VERIFY_VALUE_AND_OPS( aligned_ubig64_t, uint_least64_t, 0xffffffffffffffffLL );
VERIFY_LITTLE_REPRESENTATION( aligned_little16_t );
VERIFY_VALUE_AND_OPS( aligned_little16_t, int_least16_t, 0x7fff );
VERIFY_VALUE_AND_OPS( aligned_little16_t, int_least16_t, -0x8000 );
VERIFY_LITTLE_REPRESENTATION( aligned_little32_t );
VERIFY_VALUE_AND_OPS( aligned_little32_t, int_least32_t, 0x7fffffff );
VERIFY_VALUE_AND_OPS( aligned_little32_t, int_least32_t, -0x7fffffff-1 );
VERIFY_LITTLE_REPRESENTATION( aligned_little64_t );
VERIFY_VALUE_AND_OPS( aligned_little64_t, int_least64_t, 0x7fffffffffffffffLL );
VERIFY_VALUE_AND_OPS( aligned_little64_t, int_least64_t, -0x7fffffffffffffffLL-1 );
VERIFY_LITTLE_REPRESENTATION( aligned_ulittle16_t );
VERIFY_VALUE_AND_OPS( aligned_ulittle16_t, uint_least16_t, 0xffff );
VERIFY_LITTLE_REPRESENTATION( aligned_ulittle32_t );
VERIFY_VALUE_AND_OPS( aligned_ulittle32_t, uint_least32_t, 0xffffffff );
VERIFY_LITTLE_REPRESENTATION( aligned_ulittle64_t );
VERIFY_VALUE_AND_OPS( aligned_ulittle64_t, uint_least64_t, 0xffffffffffffffffLL );
} // check_representation_and_range
long iterations = 10000000;
template< class Endian >
Endian timing_test( const char * s)
{
cout << s << " timing test, " << iterations << " iterations: ";
progress_timer t;
Endian v = 1;
for ( long i = 0; i < iterations; ++i )
{
v += 1;
v *= 3;
++v;
v *= i;
if ( i == 0 ) VERIFY_VALUE_AND_OPS( Endian, typename Endian::value_type, 21 );
}
return v;
}
} // unnamed namespace
int main( int argc, char * argv[] )
{
cout << "Usage: "
<< argv[0] << " [#],\n where # specifies iteration count\n"
" default iteration count is 1000000" << endl;
if ( argc > 1 )
iterations = atol( argv[1] );
if ( iterations < 1 ) iterations = 1;
detect_endianness();
check_size();
check_alignment();
check_representation_and_range_and_ops();
//timing_test<big32_t> ( "big32_t" );
//timing_test<aligned_big32_t>( "aligned_big32_t" );
//timing_test<little32_t> ( "little32_t" );
//timing_test<aligned_little32_t>( "aligned_little32_t" );
cout << "\n" << err_count << " errors detected\nTest "
<< (err_count==0 ? "passed\n\n" : "failed\n\n");
return err_count ? 1 : 0;
} // main

View File

@@ -0,0 +1,11 @@
set ENDIAN_LOCATE_ROOT=%temp%\endian-regr
md %ENDIAN_LOCATE_ROOT% 2>nul
echo Begin test processing...
bjam --dump-tests "-sALL_LOCATE_TARGET=%ENDIAN_LOCATE_ROOT%" %* >bjam.log 2>&1
echo Begin log processing...
process_jam_log %ENDIAN_LOCATE_ROOT% <bjam.log
start bjam.log
echo Begin compiler status processing...
compiler_status --locate-root %ENDIAN_LOCATE_ROOT% ..\..\.. test_status.html test_links.html
start test_status.html

View File

@@ -0,0 +1,33 @@
echo create zip file...
if $%1 == $ goto error
rmdir /s \tmp\%1 2>nul
pushd .
mkdir \tmp\%1
cd \tmp\%1
md boost\integer
md libs\integer\doc
md libs\integer\example
md libs\integer\test
popd
copy ..\..\boost\integer\endian.hpp \tmp\%1\boost\integer
copy ..\..\boost\integer\cover_operators.hpp \tmp\%1\boost\integer
copy ..\..\libs\integer\doc\endian.html \tmp\%1\libs\integer\doc
copy ..\..\libs\integer\example\endian_example.cpp \tmp\%1\libs\integer\example
copy ..\..\libs\integer\test\endian_test.cpp \tmp\%1\libs\integer\test
copy ..\..\libs\integer\test\Jamfile.* \tmp\%1\libs\integer\test
pushd \tmp
zip -r %1.zip %1
popd
move \tmp\%1.zip .
goto done
:error
echo usage: zip-endian version
echo version will be used for both the .zip name and the highest level directory name
echo example: zip-endian endian-1.0
:done