Re-implement the endian types by inheriting from endian_buffer.

This commit is contained in:
Beman
2014-11-15 21:04:19 -05:00
parent 561d8f7070
commit e9f6d2c37c
6 changed files with 118 additions and 280 deletions

View File

@ -1,7 +1,7 @@
// boost/endian/types.hpp ------------------------------------------------------------//
// boost/endian/buffers.hpp ----------------------------------------------------------//
// (C) Copyright Darin Adler 2000
// (C) Copyright Beman Dawes 2006, 2009
// (C) Copyright Beman Dawes 2006, 2009, 2014
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
@ -37,9 +37,9 @@
#include <boost/config.hpp>
#include <boost/predef/detail/endian_compat.h>
#include <boost/endian/conversion.hpp>
#define BOOST_MINIMAL_INTEGER_COVER_OPERATORS
#define BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
#include <boost/endian/detail/cover_operators.hpp>
#undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
#undef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
#include <boost/type_traits/is_signed.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
@ -371,7 +371,7 @@ namespace endian
return detail::load_big_endian<T, n_bits/8>(m_value);
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
protected:
char m_value[n_bits/8];
};
@ -395,7 +395,7 @@ namespace endian
return tmp;
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
protected:
char m_value[sizeof(value_type)];
};
@ -419,7 +419,7 @@ namespace endian
return tmp;
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
protected:
char m_value[sizeof(value_type)];
};
@ -443,7 +443,7 @@ namespace endian
return tmp;
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
protected:
char m_value[sizeof(value_type)];
};
@ -467,7 +467,7 @@ namespace endian
return tmp;
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
protected:
char m_value[sizeof(value_type)];
};
@ -502,7 +502,7 @@ namespace endian
return detail::load_little_endian<T, n_bits/8>(m_value);
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
protected:
char m_value[n_bits/8];
};
@ -525,13 +525,13 @@ namespace endian
std::cout << "big, aligned, " << n_bits
<< "-bits, construct(" << val << ")\n";
# endif
m_value = ::boost::endian_buffer::big_endian_value(val);
m_value = ::boost::endian::big_endian_value(val);
}
# endif
endian_buffer& operator=(T val) BOOST_NOEXCEPT
{
m_value = ::boost::endian_buffer::big_endian_value(val);
m_value = ::boost::endian::big_endian_value(val);
return *this;
}
operator T() const BOOST_NOEXCEPT
@ -539,12 +539,13 @@ namespace endian
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::cout << "big, aligned, " << n_bits << "-bits, convert("
<< ::boost::endian_buffer::big_endian_value(m_value) << ")\n";
<< ::boost::endian::big_endian_value(m_value) << ")\n";
# endif
return ::boost::endian_buffer::big_endian_value(m_value);
return ::boost::endian::big_endian_value(m_value);
}
const char* data() const BOOST_NOEXCEPT {return reinterpret_cast<const char*>(&m_value);}
private:
const char* data() const BOOST_NOEXCEPT
{return reinterpret_cast<const char*>(&m_value);}
protected:
T m_value;
};
@ -565,13 +566,13 @@ namespace endian
std::cout << "little, aligned, " << n_bits
<< "-bits, construct(" << val << ")\n";
# endif
m_value = ::boost::endian_buffer::little_endian_value(val);
m_value = ::boost::endian::little_endian_value(val);
}
# endif
endian_buffer& operator=(T val) BOOST_NOEXCEPT
{
m_value = ::boost::endian_buffer::little_endian_value(val);
m_value = ::boost::endian::little_endian_value(val);
return *this;
}
operator T() const BOOST_NOEXCEPT
@ -579,12 +580,13 @@ namespace endian
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::cout << "little, aligned, " << n_bits << "-bits, convert("
<< ::boost::endian_buffer::little_endian_value(m_value) << ")\n";
<< ::boost::endian::little_endian_value(m_value) << ")\n";
# endif
return ::boost::endian_buffer::little_endian_value(m_value);
return ::boost::endian::little_endian_value(m_value);
}
const char* data() const BOOST_NOEXCEPT {return reinterpret_cast<const char*>(&m_value);}
private:
const char* data() const BOOST_NOEXCEPT
{return reinterpret_cast<const char*>(&m_value);}
protected:
T m_value;
};

View File

@ -311,7 +311,7 @@ namespace endian
std::reverse_copy(from, from+sizeof(T), reinterpret_cast<char*>(&to));
# endif
}
}
} // namespace detail
template <class ReversibleValue >
inline ReversibleValue big_endian_value(ReversibleValue x) BOOST_NOEXCEPT

View File

@ -6,25 +6,15 @@
// 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)
//----------------------------------------------------------------------------//
// If the class being covered has a non-explicit conversion to an integer type
// then a smaller number of cover operations are needed. Define the macro
// BOOST_MINIMAL_INTEGER_COVER_OPERATORS to indicate this.
// Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired.
//----------------------------------------------------------------------------//
#ifndef BOOST_INTEGER_COVER_OPERATORS_HPP
#define BOOST_INTEGER_COVER_OPERATORS_HPP
#ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP
#define BOOST_ENDIAN_COVER_OPERATORS_HPP
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
#endif
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
# include <boost/operators.hpp>
# endif
@ -36,60 +26,72 @@ namespace boost
namespace endian
{
// A class that adds integer operators to an integer cover class
//--------------------------------------------------------------------------------------//
template <typename T, typename IntegerType>
// A class that adds arithmetic operators to an arithmetic cover class
//
// Uses the curiously recurring template pattern (CRTP).
//
// If the class being covered has a non-explicit conversion to an integer type
// then a smaller number of cover operations are needed. Define the macro
// BOOST_ENDIAN_MINIMAL_COVER_OPERATORS to indicate this.
//
// Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired.
//--------------------------------------------------------------------------------------//
template <class D, // D is the CRTP derived type, i.e. the cover class
class ArithmeticT>
class cover_operators
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
: boost::operators<T>
# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
: boost::operators<D>
# endif
{
// The other operations take advantage of the type conversion that's
// built into unary +.
// Unary operations.
friend IntegerType operator+(const T& x) BOOST_NOEXCEPT { return x; }
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
friend IntegerType operator-(const T& x) BOOST_NOEXCEPT { return -+x; }
friend IntegerType operator~(const T& x) BOOST_NOEXCEPT { return ~+x; }
friend IntegerType operator!(const T& x) BOOST_NOEXCEPT { return !+x; }
friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; }
# ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
friend ArithmeticT operator-(const D& x) BOOST_NOEXCEPT { return -+x; }
friend ArithmeticT operator~(const D& x) BOOST_NOEXCEPT { return ~+x; }
friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; }
// The basic ordering operations.
friend bool operator==(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x == y; }
friend bool operator<(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x < y; }
friend bool operator==(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x == y; }
friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; }
# endif
// The basic arithmetic operations.
friend T& operator+=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x + y; }
friend T& operator-=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x - y; }
friend T& operator*=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x * y; }
friend T& operator/=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x / y; }
friend T& operator%=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x % y; }
friend T& operator&=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x & y; }
friend T& operator|=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x | y; }
friend T& operator^=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x ^ y; }
friend T& operator<<=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x << y; }
friend T& operator>>=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x >> y; }
friend D& operator+=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x + y; }
friend D& operator-=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x - y; }
friend D& operator*=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x * y; }
friend D& operator/=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x / y; }
friend D& operator%=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x % y; }
friend D& operator&=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x & y; }
friend D& operator|=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x | y; }
friend D& operator^=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x ^ y; }
friend D& operator<<=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x << y; }
friend D& operator>>=(D& x, ArithmeticT y) BOOST_NOEXCEPT { return x = +x >> y; }
// A few binary arithmetic operations not covered by operators base class.
friend IntegerType operator<<(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x << y; }
friend IntegerType operator>>(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x >> y; }
friend ArithmeticT operator<<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x << y; }
friend ArithmeticT operator>>(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x >> y; }
// Auto-increment and auto-decrement can be defined in terms of the
// arithmetic operations.
friend T& operator++(T& x) BOOST_NOEXCEPT { return x += 1; }
friend T& operator--(T& x) BOOST_NOEXCEPT { return x -= 1; }
friend D& operator++(D& x) BOOST_NOEXCEPT { return x += 1; }
friend D& operator--(D& x) BOOST_NOEXCEPT { return x -= 1; }
# ifdef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
friend T operator++(T& x, int) BOOST_NOEXCEPT
# ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
friend D operator++(D& x, int) BOOST_NOEXCEPT
{
T tmp(x);
D tmp(x);
x += 1;
return tmp;
}
friend T operator--(T& x, int) BOOST_NOEXCEPT
friend D operator--(D& x, int) BOOST_NOEXCEPT
{
T tmp(x);
D tmp(x);
x -= 1;
return tmp;
}
@ -100,7 +102,7 @@ namespace boost
// Stream inserter
template <class charT, class traits>
friend std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const T& x)
operator<<(std::basic_ostream<charT, traits>& os, const D& x)
{
return os << +x;
}
@ -108,9 +110,9 @@ namespace boost
// Stream extractor
template <class charT, class traits>
friend std::basic_istream<charT, traits>&
operator>>(std::basic_istream<charT, traits>& is, T& x)
operator>>(std::basic_istream<charT, traits>& is, D& x)
{
IntegerType i;
ArithmeticT i;
if (is >> i)
x = i;
return is;
@ -124,4 +126,4 @@ namespace boost
# pragma warning(pop)
#endif
#endif // BOOST_INTEGER_COVER_OPERATORS_HPP
#endif // BOOST_ENDIAN_COVER_OPERATORS_HPP

View File

@ -1,7 +1,7 @@
// boost/endian/types.hpp ------------------------------------------------------------//
// (C) Copyright Darin Adler 2000
// (C) Copyright Beman Dawes 2006, 2009
// (C) Copyright Beman Dawes 2006, 2009, 2014
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
@ -37,11 +37,10 @@
#include <boost/config.hpp>
#include <boost/predef/detail/endian_compat.h>
#include <boost/endian/conversion.hpp>
#define BOOST_MINIMAL_INTEGER_COVER_OPERATORS
//#define BOOST_NO_IO_COVER_OPERATORS
#define BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
#include <boost/endian/buffers.hpp>
#include <boost/endian/detail/cover_operators.hpp>
//#undef BOOST_NO_IO_COVER_OPERATORS
#undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
#undef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
#include <boost/type_traits/is_signed.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
@ -88,7 +87,6 @@ namespace endian
}; BOOST_SCOPED_ENUM_END
# define BOOST_ENDIAN_ORDER_ENUM_DEFINED
#endif
BOOST_SCOPED_ENUM_START(align) {no, yes}; BOOST_SCOPED_ENUM_END
template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
BOOST_SCOPED_ENUM(align) A = align::no>
@ -235,110 +233,19 @@ namespace boost
{
namespace endian
{
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) BOOST_NOEXCEPT
{ return *(bytes - 1) | (next::load_big(bytes - 1) << 8); }
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *bytes | (next::load_little(bytes + 1) << 8); }
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
{
*(bytes - 1) = static_cast<char>(value);
next::store_big(bytes - 1, value >> 8);
}
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
{
*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) BOOST_NOEXCEPT
{ return *(bytes - 1); }
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *bytes; }
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
{ *(bytes - 1) = static_cast<char>(value); }
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
{ *bytes = static_cast<char>(value); }
};
template <typename T>
struct unrolled_byte_loops<T, 1, true>
{
static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *reinterpret_cast<const signed char*>(bytes - 1); }
static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *reinterpret_cast<const signed char*>(bytes); }
static void store_big(char* bytes, T value) BOOST_NOEXCEPT
{ *(bytes - 1) = static_cast<char>(value); }
static void store_little(char* bytes, T value) BOOST_NOEXCEPT
{ *bytes = static_cast<char>(value); }
};
template <typename T, std::size_t n_bytes>
inline
T load_big_endian(const void* bytes) BOOST_NOEXCEPT
{
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) BOOST_NOEXCEPT
{
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) BOOST_NOEXCEPT
{
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) BOOST_NOEXCEPT
{
unrolled_byte_loops<T, n_bytes>::store_little
(static_cast<char*>(bytes), value);
}
} // namespace detail
# ifdef BOOST_ENDIAN_LOG
bool endian_log(true);
# endif
// endian class template specializations -------------------------------------------//
// endian class template specializations ---------------------------------------------//
// 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
// the size and signness of the desired integer and get the appropriate
// corresponding integer type for the interface.
// unaligned big endian specialization
// unaligned integer big endian specialization
template <typename T, std::size_t n_bits>
class endian< order::big, T, n_bits, align::no >
: cover_operators< endian< order::big, T, n_bits >, T >
: public endian_buffer< order::big, T, n_bits, align::no >,
cover_operators<endian<order::big, T, n_bits>, T>
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
@ -351,128 +258,86 @@ namespace endian
if ( endian_log )
std::cout << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif
detail::store_big_endian<T, n_bits/8>(m_value, val);
detail::store_big_endian<T, n_bits/8>(this->m_value, val);
}
# endif
endian & operator=(T val) BOOST_NOEXCEPT
{ detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::cout << "big, unaligned, " << n_bits << "-bits, convert(" << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n";
# endif
return detail::load_big_endian<T, n_bits/8>(m_value);
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[n_bits/8];
{ detail::store_big_endian<T, n_bits/8>(this->m_value, val); return *this; }
};
// unaligned float big endian specialization
template <>
class endian< order::big, float, 32, align::no >
: cover_operators< endian< order::big, float, 32 >, float >
: public endian_buffer< order::big, float, 32, align::no >,
cover_operators< endian< order::big, float, 32 >, float >
{
public:
typedef float value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
BOOST_ENDIAN_EXPLICIT_OPT endian(value_type val) BOOST_NOEXCEPT
{ detail::big_reverse_copy(val, m_value); }
{ detail::big_reverse_copy(val, this->m_value); }
# endif
endian & operator=(value_type val) BOOST_NOEXCEPT
{ detail::big_reverse_copy(val, m_value); return *this; }
operator value_type() const BOOST_NOEXCEPT
{
value_type tmp;
detail::big_reverse_copy(m_value, tmp);
return tmp;
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[sizeof(value_type)];
{ detail::big_reverse_copy(val, this->m_value); return *this; }
};
// unaligned double big endian specialization
template <>
class endian< order::big, double, 64, align::no >
: cover_operators< endian< order::big, double, 64 >, double >
: public endian_buffer< order::big, double, 64, align::no >,
cover_operators< endian< order::big, double, 64 >, double >
{
public:
typedef double value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
BOOST_ENDIAN_EXPLICIT_OPT endian(value_type val) BOOST_NOEXCEPT
{ detail::big_reverse_copy(val, m_value); }
{ detail::big_reverse_copy(val, this->m_value); }
# endif
endian & operator=(value_type val) BOOST_NOEXCEPT
{ detail::big_reverse_copy(val, m_value); return *this; }
operator value_type() const BOOST_NOEXCEPT
{
value_type tmp;
detail::big_reverse_copy(m_value, tmp);
return tmp;
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[sizeof(value_type)];
{ detail::big_reverse_copy(val, this->m_value); return *this; }
};
// unaligned float little endian specialization
template <>
class endian< order::little, float, 32, align::no >
: cover_operators< endian< order::little, float, 32 >, float >
: public endian_buffer< order::little, float, 32, align::no >,
cover_operators< endian< order::little, float, 32 >, float >
{
public:
typedef float value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
BOOST_ENDIAN_EXPLICIT_OPT endian(value_type val) BOOST_NOEXCEPT
{ detail::little_reverse_copy(val, m_value); }
{ detail::little_reverse_copy(val, this->m_value); }
# endif
endian & operator=(value_type val) BOOST_NOEXCEPT
{ detail::little_reverse_copy(val, m_value); return *this; }
operator value_type() const BOOST_NOEXCEPT
{
value_type tmp;
detail::little_reverse_copy(m_value, tmp);
return tmp;
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[sizeof(value_type)];
{ detail::little_reverse_copy(val, this->m_value); return *this; }
};
// unaligned double little endian specialization
template <>
class endian< order::little, double, 64, align::no >
: cover_operators< endian< order::little, double, 64 >, double >
: public endian_buffer< order::little, double, 64, align::no >,
cover_operators< endian< order::little, double, 64 >, double >
{
public:
typedef double value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
BOOST_ENDIAN_EXPLICIT_OPT endian(value_type val) BOOST_NOEXCEPT
{ detail::little_reverse_copy(val, m_value); }
{ detail::little_reverse_copy(val, this->m_value); }
# endif
endian & operator=(value_type val) BOOST_NOEXCEPT
{ detail::little_reverse_copy(val, m_value); return *this; }
operator value_type() const BOOST_NOEXCEPT
{
value_type tmp;
detail::little_reverse_copy(m_value, tmp);
return tmp;
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[sizeof(value_type)];
{ detail::little_reverse_copy(val, this->m_value); return *this; }
};
// unaligned little endian specialization
template <typename T, std::size_t n_bits>
class endian< order::little, T, n_bits, align::no >
: cover_operators< endian< order::little, T, n_bits >, T >
: public endian_buffer< order::little, T, n_bits, align::no >,
cover_operators< endian< order::little, T, n_bits >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
@ -485,22 +350,11 @@ namespace endian
if ( endian_log )
std::cout << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif
detail::store_little_endian<T, n_bits/8>(m_value, val);
detail::store_little_endian<T, n_bits/8>(this->m_value, val);
}
# endif
endian & operator=(T val) BOOST_NOEXCEPT
{ detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::cout << "little, unaligned, " << n_bits << "-bits, convert(" << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n";
# endif
return detail::load_little_endian<T, n_bits/8>(m_value);
}
const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[n_bits/8];
{ detail::store_little_endian<T, n_bits/8>(this->m_value, val); return *this; }
};
// align::yes specializations; only n_bits == 16/32/64 supported
@ -508,7 +362,8 @@ namespace endian
// aligned big endian specialization
template <typename T, std::size_t n_bits>
class endian<order::big, T, n_bits, align::yes>
: cover_operators<endian<order::big, T, n_bits, align::yes>, T>
: public endian_buffer< order::big, T, n_bits, align::yes >,
cover_operators<endian<order::big, T, n_bits, align::yes>, T>
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
@ -522,32 +377,22 @@ namespace endian
if ( endian_log )
std::cout << "big, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif
m_value = ::boost::endian::big_endian_value(val);
this->m_value = ::boost::endian::big_endian_value(val);
}
# endif
endian& operator=(T val) BOOST_NOEXCEPT
{
m_value = ::boost::endian::big_endian_value(val);
this->m_value = ::boost::endian::big_endian_value(val);
return *this;
}
operator T() const BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::cout << "big, aligned, " << n_bits << "-bits, convert(" << ::boost::endian::big_endian_value(m_value) << ")\n";
# endif
return ::boost::endian::big_endian_value(m_value);
}
const char* data() const BOOST_NOEXCEPT {return reinterpret_cast<const char*>(&m_value);}
private:
T m_value;
};
// aligned little endian specialization
template <typename T, std::size_t n_bits>
class endian<order::little, T, n_bits, align::yes>
: cover_operators<endian<order::little, T, n_bits, align::yes>, T>
: public endian_buffer< order::little, T, n_bits, align::yes >,
cover_operators<endian<order::little, T, n_bits, align::yes>, T>
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
@ -561,26 +406,14 @@ namespace endian
if ( endian_log )
std::cout << "little, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif
m_value = ::boost::endian::little_endian_value(val);
this->m_value = ::boost::endian::little_endian_value(val);
}
# endif
endian& operator=(T val) BOOST_NOEXCEPT
{
m_value = ::boost::endian::little_endian_value(val);
this->m_value = ::boost::endian::little_endian_value(val);
return *this;
}
operator T() const BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::cout << "little, aligned, " << n_bits << "-bits, convert(" << ::boost::endian::little_endian_value(m_value) << ")\n";
# endif
return ::boost::endian::little_endian_value(m_value);
}
const char* data() const BOOST_NOEXCEPT {return reinterpret_cast<const char*>(&m_value);}
private:
T m_value;
};
} // namespace endian

View File

@ -14,12 +14,13 @@ project
test-suite "endian"
:
[ run endian_test.cpp # sources
[ run buffer_test.cpp # sources
: # command line
: # input files
: # requirements
: # target name
]
[ run endian_test.cpp ]
[ run endian_operations_test.cpp ]
[ run endian_in_union_test.cpp ]
[ run converter_test.cpp ]

View File

@ -1,4 +1,4 @@
// endian_operations_test.cpp ----------------------------------------------//
// endian_operations_test.cpp --------------------------------------------------------//
// Copyright Beman Dawes 2008
@ -7,7 +7,7 @@
// See library home page at http://www.boost.org/libs/endian
//----------------------------------------------------------------------------//
//--------------------------------------------------------------------------------------//
// This test probes operator overloading, including interaction between
// operand types.
@ -468,7 +468,7 @@ int cpp_main(int, char * [])
std::clog << "\n";
// test from Roland Schwarz that detected ambiguities; these ambiguities
// were eliminated by BOOST_MINIMAL_INTEGER_COVER_OPERATORS
// were eliminated by BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
unsigned u;
be::little_uint32_t u1;
be::little_uint32_t u2;