forked from boostorg/endian
Identify and static-assert the requirements of endian_load/endian_store
This commit is contained in:
@ -7,8 +7,12 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
#include <boost/endian/detail/integral_by_size.hpp>
|
#include <boost/endian/detail/integral_by_size.hpp>
|
||||||
|
#include <boost/endian/detail/is_trivially_copyable.hpp>
|
||||||
#include <boost/endian/conversion.hpp>
|
#include <boost/endian/conversion.hpp>
|
||||||
#include <boost/type_traits/is_signed.hpp>
|
#include <boost/type_traits/is_signed.hpp>
|
||||||
|
#include <boost/type_traits/is_integral.hpp>
|
||||||
|
#include <boost/type_traits/is_enum.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@ -26,6 +30,12 @@ template<class T, std::size_t N1, BOOST_SCOPED_ENUM(order) O1, std::size_t N2, B
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
// Requires:
|
||||||
|
//
|
||||||
|
// 1 <= N <= sizeof(T) <= 8
|
||||||
|
// T is TriviallyCopyable
|
||||||
|
// if N < sizeof(T), T is integral or enum
|
||||||
|
|
||||||
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) Order>
|
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) Order>
|
||||||
inline T endian_load( unsigned char const * p ) BOOST_NOEXCEPT
|
inline T endian_load( unsigned char const * p ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
@ -41,6 +51,8 @@ template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O> struct endian_load_
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||||
|
|
||||||
T t;
|
T t;
|
||||||
std::memcpy( &t, p, N );
|
std::memcpy( &t, p, N );
|
||||||
return t;
|
return t;
|
||||||
@ -53,6 +65,8 @@ template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O1, BOOST_SCOPED_ENUM(
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||||
|
|
||||||
typename integral_by_size<N>::type tmp;
|
typename integral_by_size<N>::type tmp;
|
||||||
std::memcpy( &tmp, p, N );
|
std::memcpy( &tmp, p, N );
|
||||||
|
|
||||||
@ -70,6 +84,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4,
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 4 ];
|
unsigned char tmp[ 4 ];
|
||||||
|
|
||||||
tmp[0] = p[0];
|
tmp[0] = p[0];
|
||||||
@ -85,6 +101,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 4,
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 4 ];
|
unsigned char tmp[ 4 ];
|
||||||
|
|
||||||
tmp[0] = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
tmp[0] = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||||
@ -102,6 +120,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
|
|
||||||
unsigned char fill = boost::is_signed<T>::value && ( p[4] & 0x80 )? 0xFF: 0x00;
|
unsigned char fill = boost::is_signed<T>::value && ( p[4] & 0x80 )? 0xFF: 0x00;
|
||||||
@ -124,6 +144,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
|
|
||||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||||
@ -148,6 +170,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
|
|
||||||
unsigned char fill = boost::is_signed<T>::value && ( p[5] & 0x80 )? 0xFF: 0x00;
|
unsigned char fill = boost::is_signed<T>::value && ( p[5] & 0x80 )? 0xFF: 0x00;
|
||||||
@ -170,6 +194,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
|
|
||||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||||
@ -194,6 +220,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
|
|
||||||
unsigned char fill = boost::is_signed<T>::value && ( p[6] & 0x80 )? 0xFF: 0x00;
|
unsigned char fill = boost::is_signed<T>::value && ( p[6] & 0x80 )? 0xFF: 0x00;
|
||||||
@ -216,6 +244,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_load_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
|
|
||||||
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
unsigned char fill = boost::is_signed<T>::value && ( p[0] & 0x80 )? 0xFF: 0x00;
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
#include <boost/endian/detail/integral_by_size.hpp>
|
#include <boost/endian/detail/integral_by_size.hpp>
|
||||||
|
#include <boost/endian/detail/is_trivially_copyable.hpp>
|
||||||
#include <boost/endian/conversion.hpp>
|
#include <boost/endian/conversion.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@ -25,6 +27,12 @@ template<class T, std::size_t N1, BOOST_SCOPED_ENUM(order) O1, std::size_t N2, B
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
// Requires:
|
||||||
|
//
|
||||||
|
// 1 <= N <= sizeof(T) <= 8
|
||||||
|
// T is TriviallyCopyable
|
||||||
|
// if N < sizeof(T), T is integral or enum
|
||||||
|
|
||||||
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) Order>
|
template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) Order>
|
||||||
inline void endian_store( T const & v, unsigned char * p ) BOOST_NOEXCEPT
|
inline void endian_store( T const & v, unsigned char * p ) BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
@ -40,6 +48,8 @@ template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O> struct endian_store
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||||
|
|
||||||
std::memcpy( p, &v, N );
|
std::memcpy( p, &v, N );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -50,6 +60,8 @@ template<class T, std::size_t N, BOOST_SCOPED_ENUM(order) O1, BOOST_SCOPED_ENUM(
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||||
|
|
||||||
typename integral_by_size<N>::type tmp;
|
typename integral_by_size<N>::type tmp;
|
||||||
std::memcpy( &tmp, &v, N );
|
std::memcpy( &tmp, &v, N );
|
||||||
|
|
||||||
@ -65,6 +77,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4,
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 4 ];
|
unsigned char tmp[ 4 ];
|
||||||
endian::endian_store<T, 4, order::little>( v, tmp );
|
endian::endian_store<T, 4, order::little>( v, tmp );
|
||||||
|
|
||||||
@ -78,6 +92,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 4,
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 4 ];
|
unsigned char tmp[ 4 ];
|
||||||
endian::endian_store<T, 4, order::big>( v, tmp );
|
endian::endian_store<T, 4, order::big>( v, tmp );
|
||||||
|
|
||||||
@ -93,6 +109,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
endian::endian_store<T, 8, order::little>( v, tmp );
|
endian::endian_store<T, 8, order::little>( v, tmp );
|
||||||
|
|
||||||
@ -108,6 +126,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
endian::endian_store<T, 8, order::big>( v, tmp );
|
endian::endian_store<T, 8, order::big>( v, tmp );
|
||||||
|
|
||||||
@ -125,6 +145,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
endian::endian_store<T, 8, order::little>( v, tmp );
|
endian::endian_store<T, 8, order::little>( v, tmp );
|
||||||
|
|
||||||
@ -141,6 +163,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
endian::endian_store<T, 8, order::big>( v, tmp );
|
endian::endian_store<T, 8, order::big>( v, tmp );
|
||||||
|
|
||||||
@ -159,6 +183,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
endian::endian_store<T, 8, order::little>( v, tmp );
|
endian::endian_store<T, 8, order::little>( v, tmp );
|
||||||
|
|
||||||
@ -176,6 +202,8 @@ template<class T, BOOST_SCOPED_ENUM(order) Order> struct endian_store_impl<T, 8,
|
|||||||
{
|
{
|
||||||
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||||
|
|
||||||
unsigned char tmp[ 8 ];
|
unsigned char tmp[ 8 ];
|
||||||
endian::endian_store<T, 8, order::big>( v, tmp );
|
endian::endian_store<T, 8, order::big>( v, tmp );
|
||||||
|
|
||||||
|
39
include/boost/endian/detail/is_trivially_copyable.hpp
Normal file
39
include/boost/endian/detail/is_trivially_copyable.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef BOOST_ENDIAN_DETAIL_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED
|
||||||
|
#define BOOST_ENDIAN_DETAIL_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED
|
||||||
|
|
||||||
|
// Copyright 2019 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||||
|
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||||
|
# include <type_traits>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace endian
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||||
|
|
||||||
|
using std::is_trivially_copyable;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<class T> struct is_trivially_copyable: boost::integral_constant<bool,
|
||||||
|
boost::has_trivial_copy<T>::value && boost::has_trivial_assign<T>::value> {};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace endian
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_ENDIAN_DETAIL_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED
|
Reference in New Issue
Block a user