From 3e2890c243ab2953fae65bc1f8c84cf9fb89106c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 3 May 2020 03:22:21 +0300 Subject: [PATCH] Enable endian_reverse_inplace for integral/enum/float/double --- .../boost/endian/detail/endian_reverse.hpp | 35 ++++++++++++++----- test/endian_reverse_test3.cpp | 7 ++++ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/boost/endian/detail/endian_reverse.hpp b/include/boost/endian/detail/endian_reverse.hpp index 52f5c0d..027ae81 100644 --- a/include/boost/endian/detail/endian_reverse.hpp +++ b/include/boost/endian/detail/endian_reverse.hpp @@ -1,10 +1,9 @@ #ifndef BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED #define BOOST_ENDIAN_DETAIL_ENDIAN_REVERSE_HPP_INCLUDED -// Copyright 2019 Peter Dimov -// +// Copyright 2019, 2020 Peter Dimov // Distributed under the Boost Software License, Version 1.0. -// http://www.boost.org/LICENSE_1_0.txt +// https://www.boost.org/LICENSE_1_0.txt #include #include @@ -115,14 +114,14 @@ template struct is_endian_reversible: boost::integral_constant struct is_endian_reversible_inplace: boost::integral_constant::value && !boost::is_same::value) || is_scoped_enum::value> + boost::is_integral::value || boost::is_enum::value || boost::is_same::value || boost::is_same::value> { }; } // namespace detail // Requires: -// T is non-bool integral +// T is non-bool integral or scoped enumeration type template inline BOOST_CONSTEXPR typename enable_if_< !is_class::value, T >::type @@ -135,10 +134,30 @@ template inline BOOST_CONSTEXPR return static_cast( detail::endian_reverse_impl( static_cast( x ) ) ); } -template -inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT +// Requires: +// T is integral, enumeration, float or double + +template inline + typename enable_if_< !is_class::value >::type + endian_reverse_inplace( T & x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( detail::is_endian_reversible_inplace::value ); + + typename detail::integral_by_size< sizeof(T) >::type x2; + + std::memcpy( &x2, &x, sizeof(T) ); + + x2 = detail::endian_reverse_impl( x2 ); + + std::memcpy( &x, &x2, sizeof(T) ); +} + +// Default implementation for user-defined types + +template inline + typename enable_if_< is_class::value >::type + endian_reverse_inplace( T & x ) BOOST_NOEXCEPT { - BOOST_STATIC_ASSERT( boost::is_class::value || detail::is_endian_reversible_inplace::value ); x = endian_reverse( x ); } diff --git a/test/endian_reverse_test3.cpp b/test/endian_reverse_test3.cpp index c417fea..64a38a0 100644 --- a/test/endian_reverse_test3.cpp +++ b/test/endian_reverse_test3.cpp @@ -50,9 +50,16 @@ int main() #endif test_reverse_inplace( 1 ); + test_reverse_inplace( true ); + + test_reverse_inplace( 1.0f ); + test_reverse_inplace( 1.0 ); + + test_reverse_inplace( e1 ); #if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) + test_reverse_inplace( e2 ); test_reverse_inplace( E3::e3 ); test_reverse_inplace( E4::e4 );