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

View File

@@ -311,7 +311,7 @@ namespace endian
std::reverse_copy(from, from+sizeof(T), reinterpret_cast<char*>(&to)); std::reverse_copy(from, from+sizeof(T), reinterpret_cast<char*>(&to));
# endif # endif
} }
} } // namespace detail
template <class ReversibleValue > template <class ReversibleValue >
inline ReversibleValue big_endian_value(ReversibleValue x) BOOST_NOEXCEPT 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 // 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) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//----------------------------------------------------------------------------// #ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP
#define BOOST_ENDIAN_COVER_OPERATORS_HPP
// 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
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)
# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch # pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
#endif #endif
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
# include <boost/operators.hpp> # include <boost/operators.hpp>
# endif # endif
@@ -36,60 +26,72 @@ namespace boost
namespace endian 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 class cover_operators
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
: boost::operators<T> : boost::operators<D>
# endif # endif
{ {
// The other operations take advantage of the type conversion that's // The other operations take advantage of the type conversion that's
// built into unary +. // built into unary +.
// Unary operations. // Unary operations.
friend IntegerType operator+(const T& x) BOOST_NOEXCEPT { return x; } friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; }
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
friend IntegerType operator-(const T& x) BOOST_NOEXCEPT { return -+x; } friend ArithmeticT operator-(const D& 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; }
friend IntegerType operator!(const T& x) BOOST_NOEXCEPT { return !+x; } friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; }
// The basic ordering operations. // The basic ordering operations.
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 T& x, IntegerType y) BOOST_NOEXCEPT { return +x < y; } friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; }
# endif # endif
// The basic arithmetic operations. // The basic arithmetic operations.
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 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 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 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 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 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 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 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 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 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; }
// A few binary arithmetic operations not covered by operators base class. // 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 ArithmeticT operator<<(const D& x, ArithmeticT 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; }
// Auto-increment and auto-decrement can be defined in terms of the // Auto-increment and auto-decrement can be defined in terms of the
// arithmetic operations. // arithmetic operations.
friend T& operator++(T& x) BOOST_NOEXCEPT { return x += 1; } friend D& operator++(D& 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; }
# ifdef BOOST_MINIMAL_INTEGER_COVER_OPERATORS # ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
friend T operator++(T& x, int) BOOST_NOEXCEPT friend D operator++(D& x, int) BOOST_NOEXCEPT
{ {
T tmp(x); D tmp(x);
x += 1; x += 1;
return tmp; 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; x -= 1;
return tmp; return tmp;
} }
@@ -100,7 +102,7 @@ namespace boost
// Stream inserter // Stream inserter
template <class charT, class traits> template <class charT, class traits>
friend std::basic_ostream<charT, 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; return os << +x;
} }
@@ -108,9 +110,9 @@ namespace boost
// Stream extractor // Stream extractor
template <class charT, class traits> template <class charT, class traits>
friend std::basic_istream<charT, 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) if (is >> i)
x = i; x = i;
return is; return is;
@@ -124,4 +126,4 @@ namespace boost
# pragma warning(pop) # pragma warning(pop)
#endif #endif
#endif // BOOST_INTEGER_COVER_OPERATORS_HPP #endif // BOOST_ENDIAN_COVER_OPERATORS_HPP

View File

@@ -1,7 +1,7 @@
// boost/endian/types.hpp ------------------------------------------------------------// // boost/endian/types.hpp ------------------------------------------------------------//
// (C) Copyright Darin Adler 2000 // (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. // Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt // See http://www.boost.org/LICENSE_1_0.txt
@@ -37,11 +37,10 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/predef/detail/endian_compat.h> #include <boost/predef/detail/endian_compat.h>
#include <boost/endian/conversion.hpp> #include <boost/endian/conversion.hpp>
#define BOOST_MINIMAL_INTEGER_COVER_OPERATORS #define BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
//#define BOOST_NO_IO_COVER_OPERATORS #include <boost/endian/buffers.hpp>
#include <boost/endian/detail/cover_operators.hpp> #include <boost/endian/detail/cover_operators.hpp>
//#undef BOOST_NO_IO_COVER_OPERATORS #undef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
#undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
#include <boost/type_traits/is_signed.hpp> #include <boost/type_traits/is_signed.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
@@ -88,7 +87,6 @@ namespace endian
}; BOOST_SCOPED_ENUM_END }; BOOST_SCOPED_ENUM_END
# define BOOST_ENDIAN_ORDER_ENUM_DEFINED # define BOOST_ENDIAN_ORDER_ENUM_DEFINED
#endif #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, template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
BOOST_SCOPED_ENUM(align) A = align::no> BOOST_SCOPED_ENUM(align) A = align::no>
@@ -235,110 +233,19 @@ namespace boost
{ {
namespace endian namespace endian
{ {
namespace detail
{
// Unrolled loops for loading and storing streams of bytes. // endian class template specializations ---------------------------------------------//
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 -------------------------------------------//
// Specializations that represent unaligned bytes. // Specializations that represent unaligned bytes.
// Taking an integer type as a parameter provides a nice way to pass both // 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. // corresponding integer type for the interface.
// unaligned big endian specialization // unaligned integer big endian specialization
template <typename T, std::size_t n_bits> template <typename T, std::size_t n_bits>
class endian< order::big, T, n_bits, align::no > 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 ); BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public: public:
@@ -351,128 +258,86 @@ namespace endian
if ( endian_log ) if ( endian_log )
std::cout << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n"; std::cout << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif # 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 # endif
endian & operator=(T val) BOOST_NOEXCEPT endian & operator=(T val) BOOST_NOEXCEPT
{ detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; } { detail::store_big_endian<T, n_bits/8>(this->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];
}; };
// unaligned float big endian specialization // unaligned float big endian specialization
template <> template <>
class endian< order::big, float, 32, align::no > 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: public:
typedef float value_type; typedef float value_type;
# ifndef BOOST_ENDIAN_NO_CTORS # ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
BOOST_ENDIAN_EXPLICIT_OPT endian(value_type val) BOOST_NOEXCEPT 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 # endif
endian & operator=(value_type val) BOOST_NOEXCEPT endian & operator=(value_type val) BOOST_NOEXCEPT
{ detail::big_reverse_copy(val, m_value); return *this; } { detail::big_reverse_copy(val, this->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)];
}; };
// unaligned double big endian specialization // unaligned double big endian specialization
template <> template <>
class endian< order::big, double, 64, align::no > 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: public:
typedef double value_type; typedef double value_type;
# ifndef BOOST_ENDIAN_NO_CTORS # ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
BOOST_ENDIAN_EXPLICIT_OPT endian(value_type val) BOOST_NOEXCEPT 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 # endif
endian & operator=(value_type val) BOOST_NOEXCEPT endian & operator=(value_type val) BOOST_NOEXCEPT
{ detail::big_reverse_copy(val, m_value); return *this; } { detail::big_reverse_copy(val, this->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)];
}; };
// unaligned float little endian specialization // unaligned float little endian specialization
template <> template <>
class endian< order::little, float, 32, align::no > 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: public:
typedef float value_type; typedef float value_type;
# ifndef BOOST_ENDIAN_NO_CTORS # ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
BOOST_ENDIAN_EXPLICIT_OPT endian(value_type val) BOOST_NOEXCEPT 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 # endif
endian & operator=(value_type val) BOOST_NOEXCEPT endian & operator=(value_type val) BOOST_NOEXCEPT
{ detail::little_reverse_copy(val, m_value); return *this; } { detail::little_reverse_copy(val, this->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)];
}; };
// unaligned double little endian specialization // unaligned double little endian specialization
template <> template <>
class endian< order::little, double, 64, align::no > 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: public:
typedef double value_type; typedef double value_type;
# ifndef BOOST_ENDIAN_NO_CTORS # ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
BOOST_ENDIAN_EXPLICIT_OPT endian(value_type val) BOOST_NOEXCEPT 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 # endif
endian & operator=(value_type val) BOOST_NOEXCEPT endian & operator=(value_type val) BOOST_NOEXCEPT
{ detail::little_reverse_copy(val, m_value); return *this; } { detail::little_reverse_copy(val, this->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)];
}; };
// unaligned little endian specialization // unaligned little endian specialization
template <typename T, std::size_t n_bits> template <typename T, std::size_t n_bits>
class endian< order::little, T, n_bits, align::no > 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 ); BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public: public:
@@ -485,22 +350,11 @@ namespace endian
if ( endian_log ) if ( endian_log )
std::cout << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n"; std::cout << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif # 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 # endif
endian & operator=(T val) BOOST_NOEXCEPT endian & operator=(T val) BOOST_NOEXCEPT
{ detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; } { detail::store_little_endian<T, n_bits/8>(this->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];
}; };
// align::yes specializations; only n_bits == 16/32/64 supported // align::yes specializations; only n_bits == 16/32/64 supported
@@ -508,7 +362,8 @@ namespace endian
// aligned big endian specialization // aligned big endian specialization
template <typename T, std::size_t n_bits> template <typename T, std::size_t n_bits>
class endian<order::big, T, n_bits, align::yes> 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( (n_bits/8)*8 == n_bits );
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
@@ -522,32 +377,22 @@ namespace endian
if ( endian_log ) if ( endian_log )
std::cout << "big, aligned, " << n_bits << "-bits, construct(" << val << ")\n"; std::cout << "big, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif # endif
m_value = ::boost::endian::big_endian_value(val); this->m_value = ::boost::endian::big_endian_value(val);
} }
# endif # endif
endian& operator=(T val) BOOST_NOEXCEPT 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; 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 // aligned little endian specialization
template <typename T, std::size_t n_bits> template <typename T, std::size_t n_bits>
class endian<order::little, T, n_bits, align::yes> 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( (n_bits/8)*8 == n_bits );
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
@@ -561,26 +406,14 @@ namespace endian
if ( endian_log ) if ( endian_log )
std::cout << "little, aligned, " << n_bits << "-bits, construct(" << val << ")\n"; std::cout << "little, aligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif # endif
m_value = ::boost::endian::little_endian_value(val); this->m_value = ::boost::endian::little_endian_value(val);
} }
# endif # endif
endian& operator=(T val) BOOST_NOEXCEPT 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; 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 } // namespace endian

View File

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

View File

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