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
|
||||
|
||||
#include <boost/endian/detail/integral_by_size.hpp>
|
||||
#include <boost/endian/detail/is_trivially_copyable.hpp>
|
||||
#include <boost/endian/conversion.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 <cstring>
|
||||
|
||||
@ -26,6 +30,12 @@ template<class T, std::size_t N1, BOOST_SCOPED_ENUM(order) O1, std::size_t N2, B
|
||||
|
||||
} // 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>
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||
|
||||
T t;
|
||||
std::memcpy( &t, p, N );
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||
|
||||
typename integral_by_size<N>::type tmp;
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
|
||||
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
|
||||
|
||||
#include <boost/endian/detail/integral_by_size.hpp>
|
||||
#include <boost/endian/detail/is_trivially_copyable.hpp>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cstddef>
|
||||
#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
|
||||
|
||||
// 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>
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_trivially_copyable<T>::value );
|
||||
|
||||
typename integral_by_size<N>::type tmp;
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 4 ];
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
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
|
||||
{
|
||||
BOOST_STATIC_ASSERT( is_integral<T>::value || is_enum<T>::value );
|
||||
|
||||
unsigned char tmp[ 8 ];
|
||||
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