]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/atomic/test/api_test_helpers.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / atomic / test / api_test_helpers.hpp
index 3f09700a3282b15f22e99fb813f96d3d08c43d4d..32e788d243957dbf05d4061f50ce5cfeacff24c1 100644 (file)
 #include <cstring>
 #include <cstdlib>
 #include <limits>
+#include <vector>
 #include <iostream>
 #include <boost/config.hpp>
 #include <boost/cstdint.hpp>
 #include <boost/type.hpp>
+#include <boost/core/enable_if.hpp>
 #include <boost/type_traits/integral_constant.hpp>
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/type_traits/is_pointer.hpp>
 #include <boost/type_traits/make_signed.hpp>
 #include <boost/type_traits/make_unsigned.hpp>
 #include <boost/type_traits/conditional.hpp>
-#include "aligned_object.hpp"
-
-struct test_stream_type
-{
-    typedef std::ios_base& (*ios_base_manip)(std::ios_base&);
-    typedef std::basic_ios< char, std::char_traits< char > >& (*basic_ios_manip)(std::basic_ios< char, std::char_traits< char > >&);
-    typedef std::ostream& (*stream_manip)(std::ostream&);
-
-    template< typename T >
-    test_stream_type const& operator<< (T const& value) const
-    {
-        std::cerr << value;
-        return *this;
-    }
-
-    test_stream_type const& operator<< (ios_base_manip manip) const
-    {
-        std::cerr << manip;
-        return *this;
-    }
-    test_stream_type const& operator<< (basic_ios_manip manip) const
-    {
-        std::cerr << manip;
-        return *this;
-    }
-    test_stream_type const& operator<< (stream_manip manip) const
-    {
-        std::cerr << manip;
-        return *this;
-    }
-
-    // Make sure characters are printed as numbers if tests fail
-    test_stream_type const& operator<< (char value) const
-    {
-        std::cerr << static_cast< int >(value);
-        return *this;
-    }
-    test_stream_type const& operator<< (signed char value) const
-    {
-        std::cerr << static_cast< int >(value);
-        return *this;
-    }
-    test_stream_type const& operator<< (unsigned char value) const
-    {
-        std::cerr << static_cast< unsigned int >(value);
-        return *this;
-    }
-    test_stream_type const& operator<< (short value) const
-    {
-        std::cerr << static_cast< int >(value);
-        return *this;
-    }
-    test_stream_type const& operator<< (unsigned short value) const
-    {
-        std::cerr << static_cast< unsigned int >(value);
-        return *this;
-    }
-
-#if defined(BOOST_HAS_INT128)
-    // Some GCC versions don't provide output operators for __int128
-    test_stream_type const& operator<< (boost::int128_type const& v) const
-    {
-        std::cerr << static_cast< long long >(v);
-        return *this;
-    }
-    test_stream_type const& operator<< (boost::uint128_type const& v) const
-    {
-        std::cerr << static_cast< unsigned long long >(v);
-        return *this;
-    }
-#endif // defined(BOOST_HAS_INT128)
-#if defined(BOOST_HAS_FLOAT128)
-    // libstdc++ does not provide output operators for __float128
-    test_stream_type const& operator<< (boost::float128_type const& v) const
-    {
-        std::cerr << static_cast< double >(v);
-        return *this;
-    }
-#endif // defined(BOOST_HAS_FLOAT128)
-};
-
-const test_stream_type test_stream = {};
-
-#define BOOST_LIGHTWEIGHT_TEST_OSTREAM test_stream
-
-#include <boost/core/lightweight_test.hpp>
 
+#include "lightweight_test_stream.hpp"
 #include "value_with_epsilon.hpp"
+#include "atomic_wrapper.hpp"
 
 const unsigned int max_weak_cas_loops = 1000;
 
-//! Wrapper type for atomic template
 template< typename T >
-struct atomic_wrapper
+struct is_atomic :
+    public boost::false_type
 {
-    typedef boost::atomic< T > atomic_type;
-
-    atomic_type a;
+};
 
-    BOOST_DEFAULTED_FUNCTION(atomic_wrapper(), {})
-    explicit atomic_wrapper(T const& value) : a(value) {}
+template< typename T >
+struct is_atomic< boost::atomic< T > > :
+    public boost::true_type
+{
 };
 
-//! Wrapper type for atomic_ref template
 template< typename T >
-struct atomic_ref_wrapper
+struct is_atomic< boost::ipc_atomic< T > > :
+    public boost::true_type
 {
-    typedef boost::atomic_ref< T > atomic_type;
+};
 
-    aligned_object< T, atomic_type::required_alignment > object;
-    atomic_type a;
+template< typename T >
+struct is_atomic_ref :
+    public boost::false_type
+{
+};
 
-    atomic_ref_wrapper() : a(object.get()) {}
-    explicit atomic_ref_wrapper(T const& value) : object(value), a(object.get()) {}
+template< typename T >
+struct is_atomic_ref< boost::atomic_ref< T > > :
+    public boost::true_type
+{
 };
 
-/* provide helpers that exercise whether the API
-functions of "boost::atomic" provide the correct
-operational semantic in the case of sequential
-execution */
+template< typename T >
+struct is_atomic_ref< boost::ipc_atomic_ref< T > > :
+    public boost::true_type
+{
+};
 
+template< typename Flag >
 inline void test_flag_api(void)
 {
 #ifndef BOOST_ATOMIC_NO_ATOMIC_FLAG_INIT
-    boost::atomic_flag f = BOOST_ATOMIC_FLAG_INIT;
+    Flag f = BOOST_ATOMIC_FLAG_INIT;
 #else
-    boost::atomic_flag f;
+    Flag f;
 #endif
 
     BOOST_TEST( !f.test() );
@@ -165,22 +90,22 @@ inline void test_flag_api(void)
 }
 
 template< typename T >
-inline void test_atomic_type_traits(boost::type< boost::atomic< T > >)
+inline typename boost::enable_if< is_atomic< T > >::type test_atomic_type_traits(boost::type< T >)
 {
-    BOOST_TEST_GE(sizeof(boost::atomic< T >), sizeof(T));
+    BOOST_TEST_GE(sizeof(T), sizeof(typename T::value_type));
 }
 
 template< typename T >
-inline void test_atomic_type_traits(boost::type< boost::atomic_ref< T > >)
+inline typename boost::enable_if< is_atomic_ref< T > >::type test_atomic_type_traits(boost::type< T >)
 {
-    if (boost::atomic_ref< T >::is_always_lock_free)
+    if (T::is_always_lock_free)
     {
-        BOOST_TEST_GE(boost::atomic_ref< T >::required_alignment, boost::alignment_of< T >::value);
+        BOOST_TEST_GE(T::required_alignment, boost::alignment_of< typename T::value_type >::value);
     }
     else
     {
         // Lock-based implementation should not require alignment higher than alignof(T)
-        BOOST_TEST_EQ(boost::atomic_ref< T >::required_alignment, boost::alignment_of< T >::value);
+        BOOST_TEST_EQ(T::required_alignment, boost::alignment_of< typename T::value_type >::value);
     }
 }
 
@@ -192,13 +117,13 @@ void test_base_operators(T value1, T value2, T value3)
     // explicit load/store
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         BOOST_TEST_EQ( a.load(), value1 );
     }
 
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.store(value2);
         BOOST_TEST_EQ( a.load(), value2 );
     }
@@ -206,13 +131,13 @@ void test_base_operators(T value1, T value2, T value3)
     // overloaded assignment/conversion
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         BOOST_TEST( value1 == a );
     }
 
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a = value2;
         BOOST_TEST( value2 == a );
     }
@@ -220,7 +145,7 @@ void test_base_operators(T value1, T value2, T value3)
     // exchange-type operators
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.exchange(value2);
         BOOST_TEST_EQ( a.load(), value2 );
         BOOST_TEST_EQ( n, value1 );
@@ -228,7 +153,7 @@ void test_base_operators(T value1, T value2, T value3)
 
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T expected = value1;
         bool success = a.compare_exchange_strong(expected, value3);
         BOOST_TEST( success );
@@ -238,7 +163,7 @@ void test_base_operators(T value1, T value2, T value3)
 
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T expected = value2;
         bool success = a.compare_exchange_strong(expected, value3);
         BOOST_TEST( !success );
@@ -248,7 +173,7 @@ void test_base_operators(T value1, T value2, T value3)
 
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T expected;
         unsigned int loops = 0;
         bool success = false;
@@ -266,7 +191,7 @@ void test_base_operators(T value1, T value2, T value3)
 
     {
         Wrapper<T> wrapper(value1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T expected;
         unsigned int loops = 0;
         bool success = false;
@@ -430,7 +355,7 @@ void test_additive_operators_with_type_and_test()
     const AddType zero_add = 0;
     {
         Wrapper<T> wrapper(zero_value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.add_and_test(zero_diff);
         BOOST_TEST_EQ( f, false );
         BOOST_TEST_EQ( a.load(), zero_value );
@@ -441,14 +366,14 @@ void test_additive_operators_with_type_and_test()
     }
     {
         Wrapper<T> wrapper(zero_value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.add_and_test((distance_limits< T, D >::max)());
         BOOST_TEST_EQ( f, true );
         BOOST_TEST_EQ( a.load(), T(zero_add + (distance_limits< T, D >::max)()) );
     }
     {
         Wrapper<T> wrapper(zero_value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.add_and_test((distance_limits< T, D >::min)());
         BOOST_TEST_EQ( f, ((distance_limits< T, D >::min)() != 0) );
         BOOST_TEST_EQ( a.load(), T(zero_add + (distance_limits< T, D >::min)()) );
@@ -456,7 +381,7 @@ void test_additive_operators_with_type_and_test()
 
     {
         Wrapper<T> wrapper(zero_value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.sub_and_test(zero_diff);
         BOOST_TEST_EQ( f, false );
         BOOST_TEST_EQ( a.load(), zero_value );
@@ -467,14 +392,14 @@ void test_additive_operators_with_type_and_test()
     }
     {
         Wrapper<T> wrapper(zero_value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.sub_and_test((distance_limits< T, D >::max)());
         BOOST_TEST_EQ( f, true );
         BOOST_TEST_EQ( a.load(), T(zero_add - (distance_limits< T, D >::max)()) );
     }
     {
         Wrapper<T> wrapper(zero_value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.sub_and_test((distance_limits< T, D >::min)());
         BOOST_TEST_EQ( f, ((distance_limits< T, D >::min)() != 0) );
         // Be very careful as to not cause signed overflow on negation
@@ -501,7 +426,7 @@ void test_additive_operators_with_type(T value, D delta)
     // explicit add/sub
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_add(delta);
         BOOST_TEST_EQ( a.load(), T((AddType)value + delta) );
         BOOST_TEST_EQ( n, value );
@@ -509,16 +434,67 @@ void test_additive_operators_with_type(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_sub(delta);
         BOOST_TEST_EQ( a.load(), T((AddType)value - delta) );
         BOOST_TEST_EQ( n, value );
     }
 
+    // add/sub with an immediate
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_add(1);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + 1) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_sub(1);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - 1) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_add(76);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + 76) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_sub(76);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - 76) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    if ((std::numeric_limits< D >::max)() >= 4097)
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_add((D)4097);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + (D)4097) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    if ((std::numeric_limits< D >::max)() >= 4097)
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_sub((D)4097);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - (D)4097) );
+        BOOST_TEST_EQ( n, value );
+    }
+
     // overloaded modify/assign
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = (a += delta);
         BOOST_TEST_EQ( a.load(), T((AddType)value + delta) );
         BOOST_TEST_EQ( n, T((AddType)value + delta) );
@@ -526,7 +502,7 @@ void test_additive_operators_with_type(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = (a -= delta);
         BOOST_TEST_EQ( a.load(), T((AddType)value - delta) );
         BOOST_TEST_EQ( n, T((AddType)value - delta) );
@@ -535,7 +511,7 @@ void test_additive_operators_with_type(T value, D delta)
     // overloaded increment/decrement
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a++;
         BOOST_TEST_EQ( a.load(), T((AddType)value + 1) );
         BOOST_TEST_EQ( n, value );
@@ -543,7 +519,7 @@ void test_additive_operators_with_type(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = ++a;
         BOOST_TEST_EQ( a.load(), T((AddType)value + 1) );
         BOOST_TEST_EQ( n, T((AddType)value + 1) );
@@ -551,7 +527,7 @@ void test_additive_operators_with_type(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a--;
         BOOST_TEST_EQ( a.load(), T((AddType)value - 1) );
         BOOST_TEST_EQ( n, value );
@@ -559,7 +535,7 @@ void test_additive_operators_with_type(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = --a;
         BOOST_TEST_EQ( a.load(), T((AddType)value - 1) );
         BOOST_TEST_EQ( n, T((AddType)value - 1) );
@@ -568,7 +544,7 @@ void test_additive_operators_with_type(T value, D delta)
     // Operations returning the actual resulting value
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.add(delta);
         BOOST_TEST_EQ( a.load(), T((AddType)value + delta) );
         BOOST_TEST_EQ( n, T((AddType)value + delta) );
@@ -576,27 +552,123 @@ void test_additive_operators_with_type(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.sub(delta);
         BOOST_TEST_EQ( a.load(), T((AddType)value - delta) );
         BOOST_TEST_EQ( n, T((AddType)value - delta) );
     }
 
+    // The same with an immediate
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.add(1);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + 1) );
+        BOOST_TEST_EQ( n, T((AddType)value + 1) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.sub(1);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - 1) );
+        BOOST_TEST_EQ( n, T((AddType)value - 1) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.add(76);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + 76) );
+        BOOST_TEST_EQ( n, T((AddType)value + 76) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.sub(76);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - 76) );
+        BOOST_TEST_EQ( n, T((AddType)value - 76) );
+    }
+
+    if ((std::numeric_limits< D >::max)() >= 4097)
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.add((D)4097);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + (D)4097) );
+        BOOST_TEST_EQ( n, T((AddType)value + (D)4097) );
+    }
+
+    if ((std::numeric_limits< D >::max)() >= 4097)
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.sub((D)4097);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - (D)4097) );
+        BOOST_TEST_EQ( n, T((AddType)value - (D)4097) );
+    }
+
     // Opaque operations
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_add(delta);
         BOOST_TEST_EQ( a.load(), T((AddType)value + delta) );
     }
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_sub(delta);
         BOOST_TEST_EQ( a.load(), T((AddType)value - delta) );
     }
 
+    // The same with an immediate
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_add(1);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + 1) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_sub(1);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - 1) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_add(76);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + 76) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_sub(76);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - 76) );
+    }
+
+    if ((std::numeric_limits< D >::max)() >= 4097)
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_add((D)4097);
+        BOOST_TEST_EQ( a.load(), T((AddType)value + (D)4097) );
+    }
+
+    if ((std::numeric_limits< D >::max)() >= 4097)
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_sub((D)4097);
+        BOOST_TEST_EQ( a.load(), T((AddType)value - (D)4097) );
+    }
+
     // Modify and test operations
     test_additive_operators_with_type_and_test< Wrapper, T, D, AddType >();
 }
@@ -612,7 +684,7 @@ void test_negation()
 {
     {
         Wrapper<T> wrapper((T)1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_negate();
         BOOST_TEST_EQ( a.load(), (T)-1 );
         BOOST_TEST_EQ( n, (T)1 );
@@ -623,7 +695,7 @@ void test_negation()
     }
     {
         Wrapper<T> wrapper((T)1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.negate();
         BOOST_TEST_EQ( a.load(), (T)-1 );
         BOOST_TEST_EQ( n, (T)-1 );
@@ -634,7 +706,7 @@ void test_negation()
     }
     {
         Wrapper<T> wrapper((T)1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_negate();
         BOOST_TEST_EQ( a.load(), (T)-1 );
 
@@ -643,7 +715,7 @@ void test_negation()
     }
     {
         Wrapper<T> wrapper((T)1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.negate_and_test();
         BOOST_TEST_EQ( f, true );
         BOOST_TEST_EQ( a.load(), (T)-1 );
@@ -654,7 +726,7 @@ void test_negation()
     }
     {
         Wrapper<T> wrapper((T)0);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.negate_and_test();
         BOOST_TEST_EQ( f, false );
         BOOST_TEST_EQ( a.load(), (T)0 );
@@ -666,13 +738,13 @@ void test_additive_wrap(T value)
 {
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_add(1) + (T)1;
         BOOST_TEST_EQ( a.load(), n );
     }
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_sub(1) - (T)1;
         BOOST_TEST_EQ( a.load(), n );
     }
@@ -684,7 +756,7 @@ void test_bit_operators(T value, T delta)
     // explicit and/or/xor
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_and(delta);
         BOOST_TEST_EQ( a.load(), T(value & delta) );
         BOOST_TEST_EQ( n, value );
@@ -692,7 +764,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_or(delta);
         BOOST_TEST_EQ( a.load(), T(value | delta) );
         BOOST_TEST_EQ( n, value );
@@ -700,7 +772,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_xor(delta);
         BOOST_TEST_EQ( a.load(), T(value ^ delta) );
         BOOST_TEST_EQ( n, value );
@@ -708,16 +780,66 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_complement();
         BOOST_TEST_EQ( a.load(), T(~value) );
         BOOST_TEST_EQ( n, value );
     }
 
+    // and/or/xor with an immediate. The immediates below are chosen to either be encodable in an instruction or not for various target architectures.
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_and((T)1);
+        BOOST_TEST_EQ( a.load(), T(value & (T)1) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_or((T)1);
+        BOOST_TEST_EQ( a.load(), T(value | (T)1) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_xor((T)1);
+        BOOST_TEST_EQ( a.load(), T(value ^ (T)1) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    // The following constants are not encodable in AArch64
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_and((T)76);
+        BOOST_TEST_EQ( a.load(), T(value & (T)76) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_or((T)76);
+        BOOST_TEST_EQ( a.load(), T(value | (T)76) );
+        BOOST_TEST_EQ( n, value );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.fetch_xor((T)76);
+        BOOST_TEST_EQ( a.load(), T(value ^ (T)76) );
+        BOOST_TEST_EQ( n, value );
+    }
+
     // overloaded modify/assign
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = (a &= delta);
         BOOST_TEST_EQ( a.load(), T(value & delta) );
         BOOST_TEST_EQ( n, T(value & delta) );
@@ -725,7 +847,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = (a |= delta);
         BOOST_TEST_EQ( a.load(), T(value | delta) );
         BOOST_TEST_EQ( n, T(value | delta) );
@@ -733,7 +855,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = (a ^= delta);
         BOOST_TEST_EQ( a.load(), T(value ^ delta) );
         BOOST_TEST_EQ( n, T(value ^ delta) );
@@ -742,7 +864,7 @@ void test_bit_operators(T value, T delta)
     // Operations returning the actual resulting value
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.bitwise_and(delta);
         BOOST_TEST_EQ( a.load(), T(value & delta) );
         BOOST_TEST_EQ( n, T(value & delta) );
@@ -750,7 +872,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.bitwise_or(delta);
         BOOST_TEST_EQ( a.load(), T(value | delta) );
         BOOST_TEST_EQ( n, T(value | delta) );
@@ -758,7 +880,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.bitwise_xor(delta);
         BOOST_TEST_EQ( a.load(), T(value ^ delta) );
         BOOST_TEST_EQ( n, T(value ^ delta) );
@@ -766,45 +888,139 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.bitwise_complement();
         BOOST_TEST_EQ( a.load(), T(~value) );
         BOOST_TEST_EQ( n, T(~value) );
     }
 
+    // The same with an immediate
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.bitwise_and((T)1);
+        BOOST_TEST_EQ( a.load(), T(value & (T)1) );
+        BOOST_TEST_EQ( n, T(value & (T)1) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.bitwise_or((T)1);
+        BOOST_TEST_EQ( a.load(), T(value | (T)1) );
+        BOOST_TEST_EQ( n, T(value | (T)1) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.bitwise_xor((T)1);
+        BOOST_TEST_EQ( a.load(), T(value ^ (T)1) );
+        BOOST_TEST_EQ( n, T(value ^ (T)1) );
+    }
+
+    // The following constants are not encodable in AArch64
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.bitwise_and((T)76);
+        BOOST_TEST_EQ( a.load(), T(value & (T)76) );
+        BOOST_TEST_EQ( n, T(value & (T)76) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.bitwise_or((T)76);
+        BOOST_TEST_EQ( a.load(), T(value | (T)76) );
+        BOOST_TEST_EQ( n, T(value | (T)76) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        T n = a.bitwise_xor((T)76);
+        BOOST_TEST_EQ( a.load(), T(value ^ (T)76) );
+        BOOST_TEST_EQ( n, T(value ^ (T)76) );
+    }
+
     // Opaque operations
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_and(delta);
         BOOST_TEST_EQ( a.load(), T(value & delta) );
     }
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_or(delta);
         BOOST_TEST_EQ( a.load(), T(value | delta) );
     }
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_xor(delta);
         BOOST_TEST_EQ( a.load(), T(value ^ delta) );
     }
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_complement();
         BOOST_TEST_EQ( a.load(), T(~value) );
     }
 
+    // The same with an immediate
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_and((T)1);
+        BOOST_TEST_EQ( a.load(), T(value & (T)1) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_or((T)1);
+        BOOST_TEST_EQ( a.load(), T(value | (T)1) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_xor((T)1);
+        BOOST_TEST_EQ( a.load(), T(value ^ (T)1) );
+    }
+
+    // The following constants are not encodable in AArch64
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_and((T)76);
+        BOOST_TEST_EQ( a.load(), T(value & (T)76) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_or((T)76);
+        BOOST_TEST_EQ( a.load(), T(value | (T)76) );
+    }
+
+    {
+        Wrapper<T> wrapper(value);
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
+        a.opaque_xor((T)76);
+        BOOST_TEST_EQ( a.load(), T(value ^ (T)76) );
+    }
+
     // Modify and test operations
     {
         Wrapper<T> wrapper((T)1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.and_and_test((T)1);
         BOOST_TEST_EQ( f, true );
         BOOST_TEST_EQ( a.load(), T(1) );
@@ -820,7 +1036,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper((T)0);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.or_and_test((T)0);
         BOOST_TEST_EQ( f, false );
         BOOST_TEST_EQ( a.load(), T(0) );
@@ -836,7 +1052,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper((T)0);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.xor_and_test((T)0);
         BOOST_TEST_EQ( f, false );
         BOOST_TEST_EQ( a.load(), T(0) );
@@ -852,7 +1068,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper((T)0);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.complement_and_test();
         BOOST_TEST_EQ( f, true );
         BOOST_TEST_EQ( a.load(), static_cast< T >(~static_cast< T >(0)) );
@@ -865,7 +1081,7 @@ void test_bit_operators(T value, T delta)
     // Bit test and modify operations
     {
         Wrapper<T> wrapper((T)42);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.bit_test_and_set(0);
         BOOST_TEST_EQ( f, false );
         BOOST_TEST_EQ( a.load(), T(43) );
@@ -881,7 +1097,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper((T)42);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.bit_test_and_reset(0);
         BOOST_TEST_EQ( f, false );
         BOOST_TEST_EQ( a.load(), T(42) );
@@ -897,7 +1113,7 @@ void test_bit_operators(T value, T delta)
 
     {
         Wrapper<T> wrapper((T)42);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         bool f = a.bit_test_and_complement(0);
         BOOST_TEST_EQ( f, false );
         BOOST_TEST_EQ( a.load(), T(43) );
@@ -915,7 +1131,7 @@ void test_bit_operators(T value, T delta)
     {
         unsigned int runtime_bit_index = std::rand() & 7u;
         Wrapper<T> wrapper((T)42);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
 
         a.bit_test_and_set(runtime_bit_index);
         a.bit_test_and_reset(runtime_bit_index);
@@ -960,6 +1176,23 @@ inline void test_integral_api(void)
         test_negation< Wrapper, T >();
 }
 
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_integral_api(boost::true_type)
+{
+    test_integral_api< Wrapper, T >();
+}
+
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_integral_api(boost::false_type)
+{
+}
+
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_integral_api(void)
+{
+    test_lock_free_integral_api< Wrapper, T >(boost::integral_constant< bool, Wrapper< T >::atomic_type::is_always_lock_free >());
+}
+
 #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
 
 template< template< typename > class Wrapper, typename T, typename D >
@@ -968,7 +1201,7 @@ void test_fp_additive_operators(T value, D delta)
     // explicit add/sub
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_add(delta);
         BOOST_TEST_EQ( a.load(), approx(T(value + delta)) );
         BOOST_TEST_EQ( n, approx(value) );
@@ -976,7 +1209,7 @@ void test_fp_additive_operators(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_sub(delta);
         BOOST_TEST_EQ( a.load(), approx(T(value - delta)) );
         BOOST_TEST_EQ( n, approx(value) );
@@ -985,7 +1218,7 @@ void test_fp_additive_operators(T value, D delta)
     // overloaded modify/assign
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = (a += delta);
         BOOST_TEST_EQ( a.load(), approx(T(value + delta)) );
         BOOST_TEST_EQ( n, approx(T(value + delta)) );
@@ -993,7 +1226,7 @@ void test_fp_additive_operators(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = (a -= delta);
         BOOST_TEST_EQ( a.load(), approx(T(value - delta)) );
         BOOST_TEST_EQ( n, approx(T(value - delta)) );
@@ -1002,7 +1235,7 @@ void test_fp_additive_operators(T value, D delta)
     // Operations returning the actual resulting value
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.add(delta);
         BOOST_TEST_EQ( a.load(), approx(T(value + delta)) );
         BOOST_TEST_EQ( n, approx(T(value + delta)) );
@@ -1010,7 +1243,7 @@ void test_fp_additive_operators(T value, D delta)
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.sub(delta);
         BOOST_TEST_EQ( a.load(), approx(T(value - delta)) );
         BOOST_TEST_EQ( n, approx(T(value - delta)) );
@@ -1019,14 +1252,14 @@ void test_fp_additive_operators(T value, D delta)
     // Opaque operations
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_add(delta);
         BOOST_TEST_EQ( a.load(), approx(T(value + delta)) );
     }
 
     {
         Wrapper<T> wrapper(value);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_sub(delta);
         BOOST_TEST_EQ( a.load(), approx(T(value - delta)) );
     }
@@ -1037,7 +1270,7 @@ void test_fp_negation()
 {
     {
         Wrapper<T> wrapper((T)1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.fetch_negate();
         BOOST_TEST_EQ( a.load(), approx((T)-1) );
         BOOST_TEST_EQ( n, approx((T)1) );
@@ -1048,7 +1281,7 @@ void test_fp_negation()
     }
     {
         Wrapper<T> wrapper((T)1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         T n = a.negate();
         BOOST_TEST_EQ( a.load(), approx((T)-1) );
         BOOST_TEST_EQ( n, approx((T)-1) );
@@ -1059,7 +1292,7 @@ void test_fp_negation()
     }
     {
         Wrapper<T> wrapper((T)1);
-        typename Wrapper<T>::atomic_type& a = wrapper.a;
+        typename Wrapper<T>::atomic_reference_type a = wrapper.a;
         a.opaque_negate();
         BOOST_TEST_EQ( a.load(), approx((T)-1) );
 
@@ -1085,22 +1318,40 @@ void test_floating_point_api(void)
 #endif
 }
 
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_floating_point_api(boost::true_type)
+{
+    test_floating_point_api< Wrapper, T >();
+}
+
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_floating_point_api(boost::false_type)
+{
+}
+
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_floating_point_api(void)
+{
+    test_lock_free_floating_point_api< Wrapper, T >(boost::integral_constant< bool, Wrapper< T >::atomic_type::is_always_lock_free >());
+}
+
 
 template< template< typename > class Wrapper, typename T >
 void test_pointer_api(void)
 {
-    T values[3];
+    std::vector< T > values;
+    values.resize(5000); // make the vector large enough to accommodate pointer arithmetics in the additive tests
 
     test_base_operators< Wrapper, T* >(&values[0], &values[1], &values[2]);
-    test_additive_operators< Wrapper, T*>(&values[1], 1);
+    test_additive_operators< Wrapper, T* >(&values[1], 1);
 
-    test_base_operators< Wrapper, void*>(&values[0], &values[1], &values[2]);
+    test_base_operators< Wrapper, void* >(&values[0], &values[1], &values[2]);
 
 #if defined(BOOST_HAS_INTPTR_T)
     Wrapper<void*> wrapper_ptr;
-    typename Wrapper<void*>::atomic_type& ptr = wrapper_ptr.a;
+    typename Wrapper<void*>::atomic_reference_type ptr = wrapper_ptr.a;
     Wrapper<boost::intptr_t> wrapper_integral;
-    typename Wrapper<boost::intptr_t>::atomic_type& integral = wrapper_integral.a;
+    typename Wrapper<boost::intptr_t>::atomic_reference_type integral = wrapper_integral.a;
     BOOST_TEST_EQ( ptr.is_lock_free(), integral.is_lock_free() );
 #endif
 }
@@ -1110,12 +1361,48 @@ enum test_enum
     foo, bar, baz
 };
 
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_pointer_api(boost::true_type)
+{
+    test_pointer_api< Wrapper, T >();
+}
+
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_pointer_api(boost::false_type)
+{
+}
+
+template< template< typename > class Wrapper, typename T >
+inline void test_lock_free_pointer_api(void)
+{
+    test_lock_free_pointer_api< Wrapper, T >(boost::integral_constant< bool, Wrapper< T >::atomic_type::is_always_lock_free >());
+}
+
+
 template< template< typename > class Wrapper >
 void test_enum_api(void)
 {
     test_base_operators< Wrapper >(foo, bar, baz);
 }
 
+template< template< typename > class Wrapper >
+inline void test_lock_free_enum_api(boost::true_type)
+{
+    test_enum_api< Wrapper >();
+}
+
+template< template< typename > class Wrapper >
+inline void test_lock_free_enum_api(boost::false_type)
+{
+}
+
+template< template< typename > class Wrapper >
+inline void test_lock_free_enum_api(void)
+{
+    test_lock_free_enum_api< Wrapper >(boost::integral_constant< bool, Wrapper< test_enum >::atomic_type::is_always_lock_free >());
+}
+
+
 template< typename T >
 struct test_struct
 {
@@ -1141,9 +1428,9 @@ void test_struct_api(void)
 
     {
         Wrapper<T> wrapper_sa;
-        typename Wrapper<T>::atomic_type& sa = wrapper_sa.a;
+        typename Wrapper<T>::atomic_reference_type sa = wrapper_sa.a;
         Wrapper<typename T::value_type> wrapper_si;
-        typename Wrapper<typename T::value_type>::atomic_type& si = wrapper_si.a;
+        typename Wrapper<typename T::value_type>::atomic_reference_type si = wrapper_si.a;
         BOOST_TEST_EQ( sa.is_lock_free(), si.is_lock_free() );
     }
 }
@@ -1222,7 +1509,7 @@ void test_struct_with_ctor_api(void)
     {
         test_struct_with_ctor s;
         Wrapper<test_struct_with_ctor> wrapper_sa;
-        typename Wrapper<test_struct_with_ctor>::atomic_type& sa = wrapper_sa.a;
+        typename Wrapper<test_struct_with_ctor>::atomic_reference_type sa = wrapper_sa.a;
         // Check that the default constructor was called
         BOOST_TEST( sa.load() == s );
     }