mirror of
https://github.com/boostorg/endian.git
synced 2025-08-01 05:24:39 +02:00
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:
77
boost/integer/cover_operators.hpp
Normal file
77
boost/integer/cover_operators.hpp
Normal 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
346
boost/integer/endian.hpp
Normal 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
|
525
libs/integer/doc/endian.html
Normal file
525
libs/integer/doc/endian.html
Normal 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>
|
||||
<a href="#Comment-on-naming">Comment on naming</a><br>
|
||||
<a href="#Class_template_endian">Class template <code>endian</code></a><br>
|
||||
|
||||
<a href="#Synopsis">Synopsis</a><br>
|
||||
<a href="#Members">Members</a><br>
|
||||
<a href="#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 as C++ standard integral types, with
|
||||
the standard semantics, plus operators <code><<</code> and <code>>></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>&</code>, <code>&=</code>, <code>|</code>, <code>|=</code>,
|
||||
<code>^</code>, <code>^=</code>, <code><<</code>, <code><<=</code>, <code>>></code>,
|
||||
<code>>>=</code>. Binary relational operators are <code>==</code>, <code>!=</code>,
|
||||
<code><</code>, <code><=</code>, <code>></code>, <code>>=</code>.</p>
|
||||
<p>Automatic conversion are provided to and from the underlying integer value type.</p>
|
||||
<h2><a name="Limitations">Limitations</a></h2>
|
||||
<p>Requires <code><climits></code> <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code>
|
||||
is some other value, compilation will result in an <code>#error</code>. This
|
||||
restriction is in place because the design, implementation, testing, and
|
||||
documentation has only considered issues related to 8-bit bytes, and there have
|
||||
been no real-world use cases presented for other sizes.</p>
|
||||
<p>In C++03, <code>endian</code> does not meet the requirements for POD types
|
||||
because it has constructors, private data members, and a base class. This means
|
||||
that common use cases are relying on unspecified behavior in that the C++
|
||||
Standard does not guarantee memory layout for non-POD types. This has not been a
|
||||
problem in practice since all known C++ compilers do layout memory as if <code>
|
||||
endian</code> were a POD type. In C++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 <<a href="#endianness">endianness</a>::enum_t E, typename T, std::size_t n_bytes,
|
||||
<a href="#alignment">alignment</a>::enum_t A = alignment::unaligned>
|
||||
class endian;
|
||||
</pre>
|
||||
</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><cstdint></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 <endianness::enum_t E, typename T, std::size_t n_bits,
|
||||
alignment::enum_t A = alignment::unaligned>
|
||||
class endian : <a href="../../../boost/integer/cover_operators.hpp">integer_cover_operators</a>< endian<E, T, n_bits, A>, T >
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
endian(){}
|
||||
endian(T v);
|
||||
endian & operator=(T v);
|
||||
operator T() const;
|
||||
};
|
||||
|
||||
// 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;
|
||||
|
||||
// These types only present if platform has exact size integers:
|
||||
|
||||
// aligned big endian signed integer types
|
||||
typedef endian< endianness::big, int16_t, 16, alignment::aligned > aligned_big16_t;
|
||||
typedef endian< endianness::big, int32_t, 32, alignment::aligned > aligned_big32_t;
|
||||
typedef endian< endianness::big, int64_t, 64, alignment::aligned > aligned_big64_t;
|
||||
|
||||
// aligned big endian unsigned integer types
|
||||
typedef endian< endianness::big, uint16_t, 16, alignment::aligned > aligned_ubig16_t;
|
||||
typedef endian< endianness::big, uint32_t, 32, alignment::aligned > aligned_ubig32_t;
|
||||
typedef endian< endianness::big, uint64_t, 64, alignment::aligned > aligned_ubig64_t;
|
||||
|
||||
// aligned little endian signed integer types
|
||||
typedef endian< endianness::little, int16_t, 16, alignment::aligned > aligned_little2_t;
|
||||
typedef endian< endianness::little, int32_t, 32, alignment::aligned > aligned_little4_t;
|
||||
typedef endian< endianness::little, int64_t, 64, alignment::aligned > aligned_little8_t;
|
||||
|
||||
// aligned little endian unsigned integer types
|
||||
typedef endian< endianness::little, uint16_t, 16, alignment::aligned > aligned_ulittle2_t;
|
||||
typedef endian< endianness::little, uint32_t, 32, alignment::aligned > aligned_ulittle4_t;
|
||||
typedef endian< endianness::little, uint64_t, 64, alignment::aligned > aligned_ulittle8_t;
|
||||
|
||||
|
||||
// aligned native endian typedefs are not provided because
|
||||
// <cstdint> 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<E, T, n_bits, A></code>.</p>
|
||||
</blockquote>
|
||||
<p><code>endian(T v);</code></p>
|
||||
<blockquote>
|
||||
<p><i>Effects:</i> Constructs an object of type <code>endian<E, T, n_bits, A></code>.</p>
|
||||
<p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the
|
||||
constructed object.</p>
|
||||
</blockquote>
|
||||
<p><code>endian & 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 <iostream>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <boost/integer/endian.hpp>
|
||||
|
||||
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 = "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;
|
||||
}</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>
|
75
libs/integer/example/endian_example.cpp
Normal file
75
libs/integer/example/endian_example.cpp
Normal 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;
|
||||
}
|
13
libs/integer/test/Jamfile.v2
Normal file
13
libs/integer/test/Jamfile.v2
Normal 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 ]
|
||||
;
|
13
libs/integer/test/endian-in-sandbox/common.vsprops
Normal file
13
libs/integer/test/endian-in-sandbox/common.vsprops
Normal 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=""$(BOOST_SANDBOX)\endian";"$(BOOST_TRUNK)""
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
20
libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln
Normal file
20
libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln
Normal 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
|
@@ -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>
|
593
libs/integer/test/endian_test.cpp
Normal file
593
libs/integer/test/endian_test.cpp
Normal 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
|
11
libs/integer/test/test.bat
Normal file
11
libs/integer/test/test.bat
Normal 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
|
33
libs/integer/zip-endian.bat
Normal file
33
libs/integer/zip-endian.bat
Normal 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
|
Reference in New Issue
Block a user