summaryrefslogtreecommitdiff
path: root/boost/atomic/detail/storage_type.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/atomic/detail/storage_type.hpp')
-rw-r--r--boost/atomic/detail/storage_type.hpp138
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