From de33887009680b5753db72f2ae6b776cfef14456 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 13 Mar 2019 01:44:29 +0200 Subject: [PATCH] Identify and static-assert the requirements of endian_load/endian_store --- include/boost/endian/detail/endian_load.hpp | 30 ++++++++++++++ include/boost/endian/detail/endian_store.hpp | 28 +++++++++++++ .../endian/detail/is_trivially_copyable.hpp | 39 +++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 include/boost/endian/detail/is_trivially_copyable.hpp diff --git a/include/boost/endian/detail/endian_load.hpp b/include/boost/endian/detail/endian_load.hpp index c292e77..8fac68a 100644 --- a/include/boost/endian/detail/endian_load.hpp +++ b/include/boost/endian/detail/endian_load.hpp @@ -7,8 +7,12 @@ // http://www.boost.org/LICENSE_1_0.txt #include +#include #include #include +#include +#include +#include #include #include @@ -26,6 +30,12 @@ template inline T endian_load( unsigned char const * p ) BOOST_NOEXCEPT { @@ -41,6 +51,8 @@ template struct endian_load_ { inline T operator()( unsigned char const * p ) const BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( is_trivially_copyable::value ); + T t; std::memcpy( &t, p, N ); return t; @@ -53,6 +65,8 @@ template::value ); + typename integral_by_size::type tmp; std::memcpy( &tmp, p, N ); @@ -70,6 +84,8 @@ template struct endian_load_impl::value || is_enum::value ); + unsigned char tmp[ 4 ]; tmp[0] = p[0]; @@ -85,6 +101,8 @@ template struct endian_load_impl::value || is_enum::value ); + unsigned char tmp[ 4 ]; tmp[0] = boost::is_signed::value && ( p[0] & 0x80 )? 0xFF: 0x00; @@ -102,6 +120,8 @@ template struct endian_load_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; unsigned char fill = boost::is_signed::value && ( p[4] & 0x80 )? 0xFF: 0x00; @@ -124,6 +144,8 @@ template struct endian_load_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; unsigned char fill = boost::is_signed::value && ( p[0] & 0x80 )? 0xFF: 0x00; @@ -148,6 +170,8 @@ template struct endian_load_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; unsigned char fill = boost::is_signed::value && ( p[5] & 0x80 )? 0xFF: 0x00; @@ -170,6 +194,8 @@ template struct endian_load_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; unsigned char fill = boost::is_signed::value && ( p[0] & 0x80 )? 0xFF: 0x00; @@ -194,6 +220,8 @@ template struct endian_load_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; unsigned char fill = boost::is_signed::value && ( p[6] & 0x80 )? 0xFF: 0x00; @@ -216,6 +244,8 @@ template struct endian_load_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; unsigned char fill = boost::is_signed::value && ( p[0] & 0x80 )? 0xFF: 0x00; diff --git a/include/boost/endian/detail/endian_store.hpp b/include/boost/endian/detail/endian_store.hpp index 33501b6..03edbbe 100644 --- a/include/boost/endian/detail/endian_store.hpp +++ b/include/boost/endian/detail/endian_store.hpp @@ -7,7 +7,9 @@ // http://www.boost.org/LICENSE_1_0.txt #include +#include #include +#include #include #include @@ -25,6 +27,12 @@ template inline void endian_store( T const & v, unsigned char * p ) BOOST_NOEXCEPT { @@ -40,6 +48,8 @@ template struct endian_store { inline void operator()( T const & v, unsigned char * p ) const BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT( is_trivially_copyable::value ); + std::memcpy( p, &v, N ); } }; @@ -50,6 +60,8 @@ template::value ); + typename integral_by_size::type tmp; std::memcpy( &tmp, &v, N ); @@ -65,6 +77,8 @@ template struct endian_store_impl::value || is_enum::value ); + unsigned char tmp[ 4 ]; endian::endian_store( v, tmp ); @@ -78,6 +92,8 @@ template struct endian_store_impl::value || is_enum::value ); + unsigned char tmp[ 4 ]; endian::endian_store( v, tmp ); @@ -93,6 +109,8 @@ template struct endian_store_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; endian::endian_store( v, tmp ); @@ -108,6 +126,8 @@ template struct endian_store_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; endian::endian_store( v, tmp ); @@ -125,6 +145,8 @@ template struct endian_store_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; endian::endian_store( v, tmp ); @@ -141,6 +163,8 @@ template struct endian_store_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; endian::endian_store( v, tmp ); @@ -159,6 +183,8 @@ template struct endian_store_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; endian::endian_store( v, tmp ); @@ -176,6 +202,8 @@ template struct endian_store_impl::value || is_enum::value ); + unsigned char tmp[ 8 ]; endian::endian_store( v, tmp ); diff --git a/include/boost/endian/detail/is_trivially_copyable.hpp b/include/boost/endian/detail/is_trivially_copyable.hpp new file mode 100644 index 0000000..334cd46 --- /dev/null +++ b/include/boost/endian/detail/is_trivially_copyable.hpp @@ -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 +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +# include +#endif + +namespace boost +{ +namespace endian +{ +namespace detail +{ + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + +using std::is_trivially_copyable; + +#else + +template struct is_trivially_copyable: boost::integral_constant::value && boost::has_trivial_assign::value> {}; + +#endif + +} // namespace detail +} // namespace endian +} // namespace boost + +#endif // BOOST_ENDIAN_DETAIL_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED