diff options
Diffstat (limited to 'boost/atomic/detail/storage_type.hpp')
-rw-r--r-- | boost/atomic/detail/storage_type.hpp | 138 |
1 files changed, 125 insertions, 13 deletions
diff --git a/boost/atomic/detail/storage_type.hpp b/boost/atomic/detail/storage_type.hpp index a024f1d327..63a7cef581 100644 --- a/boost/atomic/detail/storage_type.hpp +++ b/boost/atomic/detail/storage_type.hpp @@ -16,9 +16,12 @@ #ifndef BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ #define BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ -#include <cstring> +#include <cstddef> #include <boost/cstdint.hpp> #include <boost/atomic/detail/config.hpp> +#if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) +#include <cstring> +#endif #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once @@ -28,84 +31,163 @@ namespace boost { namespace atomics { namespace detail { -template< unsigned int Size > +template< typename T > +BOOST_FORCEINLINE void non_atomic_load(T const volatile& from, T& to) BOOST_NOEXCEPT +{ + to = from; +} + +template< std::size_t Size > struct buffer_storage { - unsigned char data[Size]; + BOOST_ALIGNMENT(16) unsigned char data[Size]; BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT { - bool result = true; - for (unsigned int i = 0; i < Size && result; ++i) - { - result &= data[i] == 0; - } - return result; + return (data[0] == 0u && BOOST_ATOMIC_DETAIL_MEMCMP(data, data + 1, Size - 1) == 0); } BOOST_FORCEINLINE bool operator== (buffer_storage const& that) const BOOST_NOEXCEPT { - return std::memcmp(data, that.data, Size) == 0; + return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) == 0; } BOOST_FORCEINLINE bool operator!= (buffer_storage const& that) const BOOST_NOEXCEPT { - return std::memcmp(data, that.data, Size) != 0; + return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) != 0; } }; -template< unsigned int Size, bool Signed > +template< std::size_t Size > +BOOST_FORCEINLINE void non_atomic_load(buffer_storage< Size > const volatile& from, buffer_storage< Size >& to) BOOST_NOEXCEPT +{ + BOOST_ATOMIC_DETAIL_MEMCPY(to.data, const_cast< unsigned char const* >(from.data), Size); +} + +template< std::size_t Size, bool Signed > struct make_storage_type { typedef buffer_storage< Size > type; + + struct aligned + { + type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 1u, false > { typedef boost::uint8_t type; + + struct aligned + { + type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 1u, true > { typedef boost::int8_t type; + + struct aligned + { + type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 2u, false > { typedef boost::uint16_t type; + + struct aligned + { + BOOST_ALIGNMENT(2) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 2u, true > { typedef boost::int16_t type; + + struct aligned + { + BOOST_ALIGNMENT(2) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 4u, false > { typedef boost::uint32_t type; + + struct aligned + { + BOOST_ALIGNMENT(4) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 4u, true > { typedef boost::int32_t type; + + struct aligned + { + BOOST_ALIGNMENT(4) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 8u, false > { typedef boost::uint64_t type; + + struct aligned + { + BOOST_ALIGNMENT(8) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 8u, true > { typedef boost::int64_t type; + + struct aligned + { + BOOST_ALIGNMENT(8) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; #if defined(BOOST_HAS_INT128) @@ -114,17 +196,33 @@ template< > struct make_storage_type< 16u, false > { typedef boost::uint128_type type; + + struct aligned + { + BOOST_ALIGNMENT(16) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; template< > struct make_storage_type< 16u, true > { typedef boost::int128_type type; + + struct aligned + { + BOOST_ALIGNMENT(16) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; }; #elif !defined(BOOST_NO_ALIGNMENT) -struct BOOST_ALIGNMENT(16) storage128_t +struct storage128_t { boost::uint64_t data[2]; @@ -143,10 +241,24 @@ BOOST_FORCEINLINE bool operator!= (storage128_t const& left, storage128_t const& return !(left == right); } +BOOST_FORCEINLINE void non_atomic_load(storage128_t const volatile& from, storage128_t& to) BOOST_NOEXCEPT +{ + to.data[0] = from.data[0]; + to.data[1] = from.data[1]; +} + template< bool Signed > struct make_storage_type< 16u, Signed > { typedef storage128_t type; + + struct aligned + { + BOOST_ALIGNMENT(16) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {} + }; }; #endif |