Unified implementation of bitwise_fp_cast and bitwise_cast.
Also use memset to clear the tail padding of the storage as gcc generates slightly better code for that.
This commit is contained in:
parent
72309f41f9
commit
92248dd5b8
@ -5,7 +5,7 @@
|
||||
*
|
||||
* Copyright (c) 2009 Helge Bahmann
|
||||
* Copyright (c) 2012 Tim Blechmann
|
||||
* Copyright (c) 2013 - 2014 Andrey Semashev
|
||||
* Copyright (c) 2013 - 2018 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/detail/bitwise_cast.hpp
|
||||
@ -16,47 +16,53 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/addressof.hpp>
|
||||
#include <boost/atomic/detail/string_ops.hpp>
|
||||
#include <boost/atomic/detail/type_traits/integral_constant.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 40600
|
||||
#pragma GCC diagnostic push
|
||||
// missing initializer for member var
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
template< std::size_t FromSize, typename To >
|
||||
BOOST_FORCEINLINE void clear_padding(To& to, atomics::detail::true_type) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ATOMIC_DETAIL_MEMSET(reinterpret_cast< unsigned char* >(atomics::detail::addressof(to)) + FromSize, 0, sizeof(To) - FromSize);
|
||||
}
|
||||
|
||||
template< std::size_t FromSize, typename To >
|
||||
BOOST_FORCEINLINE void clear_padding(To& to, atomics::detail::false_type) BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
template< typename To, std::size_t FromSize, typename From >
|
||||
BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT
|
||||
{
|
||||
To to;
|
||||
BOOST_ATOMIC_DETAIL_MEMCPY
|
||||
(
|
||||
atomics::detail::addressof(to),
|
||||
atomics::detail::addressof(from),
|
||||
(FromSize < sizeof(To) ? FromSize : sizeof(To))
|
||||
);
|
||||
atomics::detail::clear_padding< FromSize >(to, atomics::detail::integral_constant< bool, FromSize < sizeof(To) >());
|
||||
return to;
|
||||
}
|
||||
|
||||
template< typename To, typename From >
|
||||
BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT
|
||||
{
|
||||
struct
|
||||
{
|
||||
To to;
|
||||
}
|
||||
value = {};
|
||||
BOOST_ATOMIC_DETAIL_MEMCPY
|
||||
(
|
||||
atomics::detail::addressof(value.to),
|
||||
atomics::detail::addressof(from),
|
||||
(sizeof(From) < sizeof(To) ? sizeof(From) : sizeof(To))
|
||||
);
|
||||
return value.to;
|
||||
return atomics::detail::bitwise_cast< To, sizeof(From) >(from);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace atomics
|
||||
} // namespace boost
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 40600
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
|
||||
|
@ -16,20 +16,13 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/addressof.hpp>
|
||||
#include <boost/atomic/detail/string_ops.hpp>
|
||||
#include <boost/atomic/detail/float_sizes.hpp>
|
||||
#include <boost/atomic/detail/bitwise_cast.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 40600
|
||||
#pragma GCC diagnostic push
|
||||
// missing initializer for member var
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
@ -83,26 +76,11 @@ struct value_sizeof< const volatile T > : value_sizeof< T > {};
|
||||
template< typename To, typename From >
|
||||
BOOST_FORCEINLINE To bitwise_fp_cast(From const& from) BOOST_NOEXCEPT
|
||||
{
|
||||
struct
|
||||
{
|
||||
To to;
|
||||
}
|
||||
value = {};
|
||||
BOOST_ATOMIC_DETAIL_MEMCPY
|
||||
(
|
||||
atomics::detail::addressof(value.to),
|
||||
atomics::detail::addressof(from),
|
||||
(atomics::detail::value_sizeof< From >::value < sizeof(To) ? atomics::detail::value_sizeof< From >::value : sizeof(To))
|
||||
);
|
||||
return value.to;
|
||||
return atomics::detail::bitwise_cast< To, atomics::detail::value_sizeof< From >::value >(from);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace atomics
|
||||
} // namespace boost
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 40600
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_
|
||||
|
@ -27,9 +27,13 @@
|
||||
#if __has_builtin(__builtin_memcmp)
|
||||
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP
|
||||
#endif
|
||||
#if __has_builtin(__builtin_memset)
|
||||
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET
|
||||
#endif
|
||||
#elif defined(BOOST_GCC)
|
||||
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY
|
||||
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP
|
||||
#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY)
|
||||
@ -44,7 +48,13 @@
|
||||
#define BOOST_ATOMIC_DETAIL_MEMCMP std::memcmp
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP)
|
||||
#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET)
|
||||
#define BOOST_ATOMIC_DETAIL_MEMSET __builtin_memset
|
||||
#else
|
||||
#define BOOST_ATOMIC_DETAIL_MEMSET std::memset
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET)
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user