mirror of
https://github.com/boostorg/endian.git
synced 2025-07-31 04:57:21 +02:00
Re-implement the endian types by inheriting from endian_buffer.
This commit is contained in:
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ]
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user