mirror of
https://github.com/boostorg/endian.git
synced 2025-08-02 22:14:29 +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