mirror of
https://github.com/boostorg/endian.git
synced 2025-08-02 05:54:31 +02:00
Add unaligned floating point types and supporting infrastructure.
This commit is contained in:
@@ -133,12 +133,12 @@ requirements. Floating point types are not currently supported.</p>
|
|||||||
<h2><a name="Choosing">Choosing</a> between endian types and endian
|
<h2><a name="Choosing">Choosing</a> between endian types and endian
|
||||||
conversion functions</h2>
|
conversion functions</h2>
|
||||||
|
|
||||||
<p>Which approach is best for dealing with endianness depends on the
|
<p>Which approach is best for dealing with endianness depends on
|
||||||
application.</p>
|
application concerns.</p>
|
||||||
|
|
||||||
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="2">Advantages</th>
|
<th colspan="2">Needs that favor one approach over the other</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="50%"><b><a href="types.html">Endian types</a></b></th>
|
<th width="50%"><b><a href="types.html">Endian types</a></b></th>
|
||||||
@@ -147,31 +147,37 @@ application.</p>
|
|||||||
<tr>
|
<tr>
|
||||||
<td valign="top">
|
<td valign="top">
|
||||||
<ul>
|
<ul>
|
||||||
<li>Mimic the built-in types. This can simplify use and eliminate logic
|
<li>A need to simplify program logic and eliminate logic
|
||||||
errors since there is no need to reason about the current endianness of
|
errors. Since the endian types mimic the built-in types, there is no need to reason about the current endianness of variables
|
||||||
variables.<br>
|
and that can simplify program logic and eliminate logic errors.<br>
|
||||||
</li>
|
</li>
|
||||||
<li>1, 2, 3, 4, 5, 6, 7, and 8 byte integers are supported. Use of 3, 5,
|
<li>A need to use unusual integer sizes (i.e. 3, 5,
|
||||||
6, or 7 byte integers can reduce internal and external space usage and
|
6, or 7 bytes) to reduce internal and external space usage and
|
||||||
save I/O time.<br>
|
save I/O time.<br>
|
||||||
</li>
|
</li>
|
||||||
<li>Alignment is not required. This can eliminate padding bytes in
|
<li>A need to use unaligned variables. Endian types can eliminate padding bytes in
|
||||||
structures, reducing internal and external space usage and saving I/O
|
structures, reducing internal and external space usage and saving I/O
|
||||||
time.</li>
|
time. They can deals with structures defined like this:</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<blockquote>
|
||||||
|
<p><code>struct S {<br>
|
||||||
|
uint16_t a;<br>
|
||||||
|
uint32_t b;<br>
|
||||||
|
} __attribute__ ((packed));</code></p>
|
||||||
|
</blockquote>
|
||||||
</td>
|
</td>
|
||||||
<td valign="top">
|
<td valign="top">
|
||||||
<ul>
|
<ul>
|
||||||
<li>Already familiar to developers who have been using C conversion
|
<li>A need to leverage knowledge of developers who have been using C byte
|
||||||
|
swapping
|
||||||
functions for years.<br>
|
functions for years.<br>
|
||||||
</li>
|
</li>
|
||||||
<li>Uses less CPU time, particularly if each variable is used many times
|
<li>A need to save CPU time when a variable is used many times
|
||||||
relative to I/O of the variable.<br>
|
relative to its I/O.<br>
|
||||||
</li>
|
</li>
|
||||||
<li>Easier to pass structures to third-party libraries expecting a
|
<li>A need to pass structures to third-party libraries expecting a
|
||||||
specific structure format.<br>
|
specific structure format.<br>
|
||||||
</li>
|
</li>
|
||||||
<li>Supports <code>float</code> and <code>double</code>.</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_DEPRECATE // quiet VC++ 8.0 foolishness
|
#define _CRT_SECURE_NO_DEPRECATE // quiet VC++ 8.0 foolishness
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include <boost/endian/detail/disable_warnings.hpp>
|
#include <boost/endian/detail/disable_warnings.hpp>
|
||||||
|
|
||||||
|
@@ -126,13 +126,23 @@ namespace endian
|
|||||||
//----------------------------------- end synopsis -------------------------------------//
|
//----------------------------------- end synopsis -------------------------------------//
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
// This function is unsafe for general use, so is placed in namespace detail.
|
// These functions are unsafe for general use, so is placed in namespace detail.
|
||||||
// Think of what happens if you reverse_value a std::pair<int16_t, int_16_t>; the bytes
|
// Think of what happens if you reverse_value a std::pair<int16_t, int_16_t>; the bytes
|
||||||
// from first end up in second and the bytes from second end up in first. Not good!
|
// from first end up in second and the bytes from second end up in first. Not good!
|
||||||
{
|
{
|
||||||
// general reverse_value function template useful in testing
|
// general reverse_value function template useful in testing
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T reverse_value(T x) BOOST_NOEXCEPT; // convert little to big or visa versa
|
inline T reverse_value(T x) BOOST_NOEXCEPT; // convert little to big or visa versa
|
||||||
|
|
||||||
|
// conditional unaligned reverse copy, patterned after std::reverse_copy
|
||||||
|
template <class T>
|
||||||
|
inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT;
|
||||||
|
template <class T>
|
||||||
|
inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT;
|
||||||
|
template <class T>
|
||||||
|
inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT;
|
||||||
|
template <class T>
|
||||||
|
inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------------------//
|
||||||
@@ -237,7 +247,7 @@ namespace endian
|
|||||||
return *(const double*)&tmp;
|
return *(const double*)&tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail // this function is unsafe for general use, so placed in namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
// general reverse_value function template implementation approach using std::reverse
|
// general reverse_value function template implementation approach using std::reverse
|
||||||
// suggested by Mathias Gaunard
|
// suggested by Mathias Gaunard
|
||||||
@@ -250,7 +260,45 @@ namespace endian
|
|||||||
reinterpret_cast<char*>(&tmp) + sizeof(T));
|
reinterpret_cast<char*>(&tmp) + sizeof(T));
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
}
|
template <class T>
|
||||||
|
inline void big_reverse_copy(T from, char* to) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
# ifdef BOOST_BIG_ENDIAN
|
||||||
|
std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T));
|
||||||
|
# else
|
||||||
|
std::reverse_copy(reinterpret_cast<const char*>(&from),
|
||||||
|
reinterpret_cast<const char*>(&from)+sizeof(T), to);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
inline void big_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
# ifdef BOOST_BIG_ENDIAN
|
||||||
|
std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T));
|
||||||
|
# else
|
||||||
|
std::reverse_copy(from, from+sizeof(T), reinterpret_cast<char*>(&to));
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
inline void little_reverse_copy(T from, char* to) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
# ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
std::memcpy(to, reinterpret_cast<const char*>(&from), sizeof(T));
|
||||||
|
# else
|
||||||
|
std::reverse_copy(reinterpret_cast<const char*>(&from),
|
||||||
|
reinterpret_cast<const char*>(&from)+sizeof(T), to);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
inline void little_reverse_copy(const char* from, T& to) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
# ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
std::memcpy(reinterpret_cast<char*>(&to), from, sizeof(T));
|
||||||
|
# else
|
||||||
|
std::reverse_copy(from, from+sizeof(T), reinterpret_cast<char*>(&to));
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class ReversibleValue >
|
template <class ReversibleValue >
|
||||||
inline ReversibleValue big_endian_value(ReversibleValue x) BOOST_NOEXCEPT
|
inline ReversibleValue big_endian_value(ReversibleValue x) BOOST_NOEXCEPT
|
||||||
|
@@ -88,6 +88,14 @@ namespace endian
|
|||||||
typedef boost::endian::endian<order::little, float, 32, align::yes> little_float32_t;
|
typedef boost::endian::endian<order::little, float, 32, align::yes> little_float32_t;
|
||||||
typedef boost::endian::endian<order::little, double, 64, align::yes> little_float64_t;
|
typedef boost::endian::endian<order::little, double, 64, align::yes> little_float64_t;
|
||||||
|
|
||||||
|
// unaligned big endian floating point types
|
||||||
|
typedef boost::endian::endian<order::big, float, 32, align::no> big_float32un_t;
|
||||||
|
typedef boost::endian::endian<order::big, double, 64, align::no> big_float64un_t;
|
||||||
|
|
||||||
|
// unaligned little endian floating point types
|
||||||
|
typedef boost::endian::endian<order::little, float, 32, align::no> little_float32un_t;
|
||||||
|
typedef boost::endian::endian<order::little, double, 64, align::no> little_float64un_t;
|
||||||
|
|
||||||
// aligned big endian signed integer types
|
// aligned big endian signed integer types
|
||||||
typedef endian<order::big, int16_t, 16, align::yes> big_int16_t;
|
typedef endian<order::big, int16_t, 16, align::yes> big_int16_t;
|
||||||
typedef endian<order::big, int32_t, 32, align::yes> big_int32_t;
|
typedef endian<order::big, int32_t, 32, align::yes> big_int32_t;
|
||||||
@@ -182,6 +190,7 @@ namespace endian
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
// Unrolled loops for loading and storing streams of bytes.
|
// Unrolled loops for loading and storing streams of bytes.
|
||||||
|
|
||||||
template <typename T, std::size_t n_bytes,
|
template <typename T, std::size_t n_bytes,
|
||||||
@@ -312,6 +321,106 @@ namespace endian
|
|||||||
private:
|
private:
|
||||||
char m_value[n_bits/8];
|
char m_value[n_bits/8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// unaligned float big endian specialization
|
||||||
|
template <>
|
||||||
|
class endian< 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
|
||||||
|
explicit endian(value_type val) BOOST_NOEXCEPT
|
||||||
|
{ detail::big_reverse_copy(val, 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)];
|
||||||
|
};
|
||||||
|
|
||||||
|
// unaligned double big endian specialization
|
||||||
|
template <>
|
||||||
|
class endian< 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
|
||||||
|
explicit endian(value_type val) BOOST_NOEXCEPT
|
||||||
|
{ detail::big_reverse_copy(val, 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)];
|
||||||
|
};
|
||||||
|
|
||||||
|
// unaligned float little endian specialization
|
||||||
|
template <>
|
||||||
|
class endian< 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
|
||||||
|
explicit endian(value_type val) BOOST_NOEXCEPT
|
||||||
|
{ detail::little_reverse_copy(val, 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)];
|
||||||
|
};
|
||||||
|
|
||||||
|
// unaligned double little endian specialization
|
||||||
|
template <>
|
||||||
|
class endian< 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
|
||||||
|
explicit endian(value_type val) BOOST_NOEXCEPT
|
||||||
|
{ detail::little_reverse_copy(val, 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)];
|
||||||
|
};
|
||||||
|
|
||||||
// unaligned little endian specialization
|
// unaligned little endian specialization
|
||||||
template <typename T, std::size_t n_bits>
|
template <typename T, std::size_t n_bits>
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#define BOOST_ENDIAN_FORCE_PODNESS
|
#define BOOST_ENDIAN_FORCE_PODNESS
|
||||||
|
|
||||||
#include <boost/endian/detail/disable_warnings.hpp>
|
#include <boost/endian/detail/disable_warnings.hpp>
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#define BOOST_ENDIAN_LOG
|
#define BOOST_ENDIAN_LOG
|
||||||
|
|
||||||
#include <boost/endian/detail/disable_warnings.hpp>
|
#include <boost/endian/detail/disable_warnings.hpp>
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include <boost/endian/detail/disable_warnings.hpp>
|
#include <boost/endian/detail/disable_warnings.hpp>
|
||||||
|
|
||||||
#include <boost/endian/types.hpp>
|
#include <boost/endian/types.hpp>
|
||||||
@@ -234,6 +236,17 @@ namespace
|
|||||||
VERIFY(little_float32.data() == reinterpret_cast<const char *>(&little_float32));
|
VERIFY(little_float32.data() == reinterpret_cast<const char *>(&little_float32));
|
||||||
VERIFY(little_float64.data() == reinterpret_cast<const char *>(&little_float64));
|
VERIFY(little_float64.data() == reinterpret_cast<const char *>(&little_float64));
|
||||||
|
|
||||||
|
big_float32un_t big_float32un;
|
||||||
|
big_float64un_t big_float64un;
|
||||||
|
little_float32un_t little_float32un;
|
||||||
|
little_float64un_t little_float64un;
|
||||||
|
|
||||||
|
VERIFY(big_float32un.data() == reinterpret_cast<const char *>(&big_float32un));
|
||||||
|
VERIFY(big_float64un.data() == reinterpret_cast<const char *>(&big_float64un));
|
||||||
|
|
||||||
|
VERIFY(little_float32un.data() == reinterpret_cast<const char *>(&little_float32un));
|
||||||
|
VERIFY(little_float64un.data() == reinterpret_cast<const char *>(&little_float64un));
|
||||||
|
|
||||||
VERIFY(big_8.data() == reinterpret_cast<const char *>(&big_8));
|
VERIFY(big_8.data() == reinterpret_cast<const char *>(&big_8));
|
||||||
VERIFY(big_16.data() == reinterpret_cast<const char *>(&big_16));
|
VERIFY(big_16.data() == reinterpret_cast<const char *>(&big_16));
|
||||||
VERIFY(big_24.data() == reinterpret_cast<const char *>(&big_24));
|
VERIFY(big_24.data() == reinterpret_cast<const char *>(&big_24));
|
||||||
@@ -318,6 +331,11 @@ namespace
|
|||||||
VERIFY_SIZE(sizeof( little_float32_t ), 4 );
|
VERIFY_SIZE(sizeof( little_float32_t ), 4 );
|
||||||
VERIFY_SIZE(sizeof( little_float64_t ), 8 );
|
VERIFY_SIZE(sizeof( little_float64_t ), 8 );
|
||||||
|
|
||||||
|
VERIFY_SIZE(sizeof( big_float32un_t ), 4 );
|
||||||
|
VERIFY_SIZE(sizeof( big_float64un_t ), 8 );
|
||||||
|
VERIFY_SIZE(sizeof( little_float32un_t ), 4 );
|
||||||
|
VERIFY_SIZE(sizeof( little_float64un_t ), 8 );
|
||||||
|
|
||||||
VERIFY_SIZE( sizeof( big_8_t ), 1 );
|
VERIFY_SIZE( sizeof( big_8_t ), 1 );
|
||||||
VERIFY_SIZE( sizeof( big_16_t ), 2 );
|
VERIFY_SIZE( sizeof( big_16_t ), 2 );
|
||||||
VERIFY_SIZE( sizeof( big_24_t ), 3 );
|
VERIFY_SIZE( sizeof( big_24_t ), 3 );
|
||||||
@@ -486,6 +504,18 @@ namespace
|
|||||||
native_u64_t v31;
|
native_u64_t v31;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct big_float_struct
|
||||||
|
{
|
||||||
|
int16_t v0;
|
||||||
|
big_float32_t v1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct big_unaligned_float_struct
|
||||||
|
{
|
||||||
|
int16_t v0;
|
||||||
|
big_float32un_t v1;
|
||||||
|
};
|
||||||
|
|
||||||
// aligned test cases
|
// aligned test cases
|
||||||
|
|
||||||
struct big_aligned_struct
|
struct big_aligned_struct
|
||||||
@@ -514,6 +544,8 @@ namespace
|
|||||||
VERIFY_SIZE( sizeof(native_u_struct), 39 );
|
VERIFY_SIZE( sizeof(native_u_struct), 39 );
|
||||||
VERIFY_SIZE( sizeof(big_aligned_struct), 24 );
|
VERIFY_SIZE( sizeof(big_aligned_struct), 24 );
|
||||||
VERIFY_SIZE( sizeof(little_aligned_struct), 24 );
|
VERIFY_SIZE( sizeof(little_aligned_struct), 24 );
|
||||||
|
VERIFY_SIZE( sizeof(big_float_struct), 8 );
|
||||||
|
VERIFY_SIZE( sizeof(big_unaligned_float_struct), 6 );
|
||||||
|
|
||||||
if ( saved_err_count == err_count )
|
if ( saved_err_count == err_count )
|
||||||
{
|
{
|
||||||
@@ -526,6 +558,7 @@ namespace
|
|||||||
|
|
||||||
void check_representation_and_range_and_ops()
|
void check_representation_and_range_and_ops()
|
||||||
{
|
{
|
||||||
|
// aligned floating point types
|
||||||
float big_float32_expected = std::numeric_limits<float>::max();
|
float big_float32_expected = std::numeric_limits<float>::max();
|
||||||
boost::endian::big_endian(big_float32_expected);
|
boost::endian::big_endian(big_float32_expected);
|
||||||
big_float32_t big_float32(std::numeric_limits<float>::max());
|
big_float32_t big_float32(std::numeric_limits<float>::max());
|
||||||
@@ -560,6 +593,52 @@ namespace
|
|||||||
VERIFY_VALUE_AND_OPS( little_float64_t, double, std::numeric_limits<double>::max() );
|
VERIFY_VALUE_AND_OPS( little_float64_t, double, std::numeric_limits<double>::max() );
|
||||||
VERIFY_VALUE_AND_OPS( little_float64_t, double, std::numeric_limits<double>::min() );
|
VERIFY_VALUE_AND_OPS( little_float64_t, double, std::numeric_limits<double>::min() );
|
||||||
|
|
||||||
|
// unaligned floating point types
|
||||||
|
float big_float32un_expected = std::numeric_limits<float>::max();
|
||||||
|
boost::endian::big_endian(big_float32un_expected);
|
||||||
|
big_float32un_t big_float32un(std::numeric_limits<float>::max());
|
||||||
|
VERIFY(std::memcmp(big_float32un.data(),
|
||||||
|
reinterpret_cast<const char*>(&big_float32un_expected), sizeof(float)) == 0);
|
||||||
|
|
||||||
|
float little_float32un_expected = std::numeric_limits<float>::max();
|
||||||
|
boost::endian::little_endian(little_float32un_expected);
|
||||||
|
little_float32un_t little_float32un(std::numeric_limits<float>::max());
|
||||||
|
VERIFY(std::memcmp(little_float32un.data(),
|
||||||
|
reinterpret_cast<const char*>(&little_float32un_expected), sizeof(float)) == 0);
|
||||||
|
|
||||||
|
double big_float64un_expected = std::numeric_limits<double>::max();
|
||||||
|
boost::endian::big_endian(big_float64un_expected);
|
||||||
|
big_float64un_t big_float64un(std::numeric_limits<double>::max());
|
||||||
|
VERIFY(std::memcmp(big_float64un.data(),
|
||||||
|
reinterpret_cast<const char*>(&big_float64un_expected), sizeof(double)) == 0);
|
||||||
|
|
||||||
|
double little_float64un_expected = std::numeric_limits<double>::max();
|
||||||
|
boost::endian::little_endian(little_float64un_expected);
|
||||||
|
little_float64un_t little_float64un(std::numeric_limits<double>::max());
|
||||||
|
VERIFY(std::memcmp(little_float64un.data(),
|
||||||
|
reinterpret_cast<const char*>(&little_float64un_expected), sizeof(double)) == 0);
|
||||||
|
|
||||||
|
VERIFY_VALUE_AND_OPS( big_float32un_t, float, std::numeric_limits<float>::max() );
|
||||||
|
VERIFY_VALUE_AND_OPS( big_float32un_t, float, std::numeric_limits<float>::min() );
|
||||||
|
VERIFY_VALUE_AND_OPS( big_float64un_t, double, std::numeric_limits<double>::max() );
|
||||||
|
VERIFY_VALUE_AND_OPS( big_float64un_t, double, std::numeric_limits<double>::min() );
|
||||||
|
|
||||||
|
VERIFY_VALUE_AND_OPS( little_float32un_t, float, std::numeric_limits<float>::max() );
|
||||||
|
VERIFY_VALUE_AND_OPS( little_float32un_t, float, std::numeric_limits<float>::min() );
|
||||||
|
VERIFY_VALUE_AND_OPS( little_float64un_t, double, std::numeric_limits<double>::max() );
|
||||||
|
VERIFY_VALUE_AND_OPS( little_float64un_t, double, std::numeric_limits<double>::min() );
|
||||||
|
|
||||||
|
float a = 1.0F;
|
||||||
|
big_float32_t b(1.0F);
|
||||||
|
big_float32un_t c(1.0F);
|
||||||
|
little_float32_t d(1.0F);
|
||||||
|
little_float32un_t e(1.0F);
|
||||||
|
VERIFY(a==b);
|
||||||
|
VERIFY(a==c);
|
||||||
|
VERIFY(a==d);
|
||||||
|
VERIFY(a==e);
|
||||||
|
|
||||||
|
// unaligned integer types
|
||||||
VERIFY_BIG_REPRESENTATION( big_8_t );
|
VERIFY_BIG_REPRESENTATION( big_8_t );
|
||||||
VERIFY_VALUE_AND_OPS( big_8_t, int_least8_t, 0x7f );
|
VERIFY_VALUE_AND_OPS( big_8_t, int_least8_t, 0x7f );
|
||||||
VERIFY_VALUE_AND_OPS( big_8_t, int_least8_t, -0x80 );
|
VERIFY_VALUE_AND_OPS( big_8_t, int_least8_t, -0x80 );
|
||||||
@@ -728,6 +807,7 @@ namespace
|
|||||||
VERIFY_NATIVE_REPRESENTATION( native_u64_t );
|
VERIFY_NATIVE_REPRESENTATION( native_u64_t );
|
||||||
VERIFY_VALUE_AND_OPS( native_u64_t, uint_least64_t, 0xffffffffffffffffULL );
|
VERIFY_VALUE_AND_OPS( native_u64_t, uint_least64_t, 0xffffffffffffffffULL );
|
||||||
|
|
||||||
|
// aligned integer types
|
||||||
VERIFY_BIG_REPRESENTATION( big_int16_t );
|
VERIFY_BIG_REPRESENTATION( big_int16_t );
|
||||||
VERIFY_VALUE_AND_OPS( big_int16_t, int_least16_t, 0x7fff );
|
VERIFY_VALUE_AND_OPS( big_int16_t, int_least16_t, 0x7fff );
|
||||||
VERIFY_VALUE_AND_OPS( big_int16_t, int_least16_t, -0x8000 );
|
VERIFY_VALUE_AND_OPS( big_int16_t, int_least16_t, -0x8000 );
|
||||||
|
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#define BOOST_ENDIAN_NO_INTRINSICS
|
#define BOOST_ENDIAN_NO_INTRINSICS
|
||||||
//#define BOOST_ENDIAN_LOG
|
//#define BOOST_ENDIAN_LOG
|
||||||
|
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include "speed_test_functions.hpp"
|
#include "speed_test_functions.hpp"
|
||||||
|
|
||||||
namespace user
|
namespace user
|
||||||
|
Reference in New Issue
Block a user