[libcxx] Allow use of <atomic> in C++03. Try 3.

Summary:
After putting this question up on cfe-dev I have decided that it would be best to allow the use of `<atomic>` in C++03. Although static initialization is a concern the syntax required to get it is C++11 only. Meaning that C++11 constant static initialization cannot silently break in C++03, it will always cause a syntax error. Furthermore `ATOMIC_VAR_INIT` and `ATOMIC_FLAG_INIT` remain defined in C++03 even though they cannot be used because C++03 usages will cause better error messages.

The main change in this patch is to replace `__has_feature(cxx_atomic)`, which only returns true when C++ >= 11, to `__has_extension(c_atomic)` which returns true whenever clang supports the required atomic builtins.


This patch adds the following macros:
* `_LIBCPP_HAS_C_ATOMIC_IMP`      - Defined on clang versions which provide the C `_Atomic` keyword.
* `_LIBCPP_HAS_GCC_ATOMIC_IMP` - Defined on GCC > 4.7. We must use the fallback atomic implementation.
* `_LIBCPP_HAS_NO_ATOMIC_HEADER` - Defined when it is not safe to include `<atomic>`.

`_LIBCPP_HAS_C_ATOMIC_IMP` and `_LIBCPP_HAS_GCC_ATOMIC_IMP` are mutually exclusive, only one should be defined. If neither is defined then `<atomic>` is not implemented and including `<atomic>` will issue an error.

Reviewers: chandlerc, jroelofs, mclow.lists

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D11555

llvm-svn: 245463
diff --git a/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp b/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
index 8a60f81..3a74e13 100644
--- a/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
@@ -22,13 +22,13 @@
 int main()
 {
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f(false);
         f.test_and_set();
         atomic_flag_clear(&f);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f(false);
         f.test_and_set();
         atomic_flag_clear(&f);
         assert(f.test_and_set() == 0);
diff --git a/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
index 92e57ec..0467384 100644
--- a/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
@@ -22,37 +22,37 @@
 int main()
 {
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f(false);
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_relaxed);
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f(false);
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_release);
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f(false);
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_seq_cst);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f(false);
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_relaxed);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f(false);
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_release);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f(false);
         f.test_and_set();
         atomic_flag_clear_explicit(&f, std::memory_order_seq_cst);
         assert(f.test_and_set() == 0);
diff --git a/libcxx/test/std/atomics/atomics.flag/clear.pass.cpp b/libcxx/test/std/atomics/atomics.flag/clear.pass.cpp
index 7c93626..ea5ae45 100644
--- a/libcxx/test/std/atomics/atomics.flag/clear.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.flag/clear.pass.cpp
@@ -22,49 +22,49 @@
 int main()
 {
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f(false);
         f.test_and_set();
         f.clear();
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f(false);
         f.test_and_set();
         f.clear(std::memory_order_relaxed);
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f(false);
         f.test_and_set();
         f.clear(std::memory_order_release);
         assert(f.test_and_set() == 0);
     }
     {
-        std::atomic_flag f = ATOMIC_FLAG_INIT;
+        std::atomic_flag f(false);
         f.test_and_set();
         f.clear(std::memory_order_seq_cst);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f(false);
         f.test_and_set();
         f.clear();
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f(false);
         f.test_and_set();
         f.clear(std::memory_order_relaxed);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f(false);
         f.test_and_set();
         f.clear(std::memory_order_release);
         assert(f.test_and_set() == 0);
     }
     {
-        volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
+        volatile std::atomic_flag f(false);
         f.test_and_set();
         f.clear(std::memory_order_seq_cst);
         assert(f.test_and_set() == 0);
diff --git a/libcxx/test/std/atomics/atomics.flag/init.pass.cpp b/libcxx/test/std/atomics/atomics.flag/init.pass.cpp
index c90509d..c4a121b 100644
--- a/libcxx/test/std/atomics/atomics.flag/init.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.flag/init.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// XFAIL: c++98, c++03
 
 // <atomic>
 
diff --git a/libcxx/test/std/atomics/atomics.flag/init03.pass.cpp b/libcxx/test/std/atomics/atomics.flag/init03.pass.cpp
new file mode 100644
index 0000000..0910bc5
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.flag/init03.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <atomic>
+
+// struct atomic_flag
+
+// TESTING EXTENSION atomic_flag(bool)
+
+#include <atomic>
+#include <cassert>
+
+int main()
+{
+    std::atomic_flag f(false);
+    assert(f.test_and_set() == 0);
+}
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
index f1cc993..7b221dc 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A a;
@@ -52,37 +53,10 @@
         assert(a == T(2));
         assert(t == T(2));
     }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
index f667ab7..27de5be 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
@@ -27,10 +27,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A a;
@@ -59,37 +60,10 @@
         assert(a == T(2));
         assert(t == T(2));
     }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
index 175c445..8c12715 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
@@ -25,11 +25,11 @@
 #include <cassert>
 
 #include <cmpxchg_loop.h>
+#include "atomic_helpers.h"
 
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A a;
@@ -54,37 +54,10 @@
         assert(a == T(2));
         assert(t == T(2));
     }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
index 46f80bf..90a93f0 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
@@ -29,10 +29,11 @@
 
 #include <cmpxchg_loop.h>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A a;
@@ -61,37 +62,10 @@
         assert(a == T(2));
         assert(t == T(2));
     }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
index 525e74a..035d974 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -37,37 +38,11 @@
     std::atomic_init(&vt, T(3));
     assert(std::atomic_exchange(&vt, T(4)) == T(3));
     assert(vt == T(4));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
index 9fe4ac8..4d66bb5 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -39,37 +40,11 @@
     assert(std::atomic_exchange_explicit(&vt, T(4), std::memory_order_seq_cst)
            == T(3));
     assert(vt == T(4));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
index 3408def..48ff601 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
@@ -32,10 +32,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -50,62 +51,33 @@
         assert(std::atomic_fetch_add(&t, T(2)) == T(1));
         assert(t == T(3));
     }
-}
-
-template <class T>
-void
-testp()
-{
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        A t;
-        std::atomic_init(&t, T(1*sizeof(X)));
-        assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X)));
-        assert(t == T(3*sizeof(X)));
-    }
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        volatile A t;
-        std::atomic_init(&t, T(1*sizeof(X)));
-        assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X)));
-        assert(t == T(3*sizeof(X)));
-    }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-    A(const A& a) : i(a.i) {}
-    A(const volatile A& a) : i(a.i) {}
-
-    void operator=(const volatile A& a) volatile {i = a.i;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+template <class T>
+void testp()
+{
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        A t;
+        std::atomic_init(&t, T(1*sizeof(X)));
+        assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X)));
+        assert(t == T(3*sizeof(X)));
+    }
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        volatile A t;
+        std::atomic_init(&t, T(1*sizeof(X)));
+        assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X)));
+        assert(t == T(3*sizeof(X)));
+    }
+}
+
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
     testp<int*>();
     testp<const int*>();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
index 9977bd4..2dc90c9 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
@@ -32,10 +32,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -52,7 +53,8 @@
                                             std::memory_order_seq_cst) == T(1));
         assert(t == T(3));
     }
-}
+  }
+};
 
 template <class T>
 void
@@ -78,38 +80,9 @@
     }
 }
 
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-    A(const A& a) : i(a.i) {}
-    A(const volatile A& a) : i(a.i) {}
-
-    void operator=(const volatile A& a) volatile {i = a.i;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
-};
-
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
     testp<int*>();
     testp<const int*>();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
index 4c7c043..57355d3 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -41,24 +42,10 @@
         assert(std::atomic_fetch_and(&t, T(2)) == T(3));
         assert(t == T(2));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
index d83bbf2..26ff5f6 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -43,24 +44,10 @@
                std::memory_order_seq_cst) == T(3));
         assert(t == T(2));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
index acf6d43..ca44fdc 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -41,24 +42,10 @@
         assert(std::atomic_fetch_or(&t, T(2)) == T(3));
         assert(t == T(3));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
index 72685e4..72bbde7 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -43,24 +44,10 @@
                std::memory_order_seq_cst) == T(3));
         assert(t == T(3));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
index ed8b541..2743040 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
@@ -32,10 +32,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -50,62 +51,33 @@
         assert(std::atomic_fetch_sub(&t, T(2)) == T(3));
         assert(t == T(1));
     }
-}
-
-template <class T>
-void
-testp()
-{
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        A t;
-        std::atomic_init(&t, T(3*sizeof(X)));
-        assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
-        assert(t == T(1*sizeof(X)));
-    }
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        volatile A t;
-        std::atomic_init(&t, T(3*sizeof(X)));
-        assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
-        assert(t == T(1*sizeof(X)));
-    }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-    A(const A& a) : i(a.i) {}
-    A(const volatile A& a) : i(a.i) {}
-
-    void operator=(const volatile A& a) volatile {i = a.i;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+template <class T>
+void testp()
+{
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        A t;
+        std::atomic_init(&t, T(3*sizeof(X)));
+        assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
+        assert(t == T(1*sizeof(X)));
+    }
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        volatile A t;
+        std::atomic_init(&t, T(3*sizeof(X)));
+        assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
+        assert(t == T(1*sizeof(X)));
+    }
+}
+
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
     testp<int*>();
     testp<const int*>();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
index e6c92ea..6e94c50 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
@@ -33,10 +33,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -53,64 +54,35 @@
                                             std::memory_order_seq_cst) == T(3));
         assert(t == T(1));
     }
-}
-
-template <class T>
-void
-testp()
-{
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        A t;
-        std::atomic_init(&t, T(3*sizeof(X)));
-        assert(std::atomic_fetch_sub_explicit(&t, 2,
-                                  std::memory_order_seq_cst) == T(3*sizeof(X)));
-        assert(t == T(1*sizeof(X)));
-    }
-    {
-        typedef std::atomic<T> A;
-        typedef typename std::remove_pointer<T>::type X;
-        volatile A t;
-        std::atomic_init(&t, T(3*sizeof(X)));
-        assert(std::atomic_fetch_sub_explicit(&t, 2,
-                                  std::memory_order_seq_cst) == T(3*sizeof(X)));
-        assert(t == T(1*sizeof(X)));
-    }
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-    A(const A& a) : i(a.i) {}
-    A(const volatile A& a) : i(a.i) {}
-
-    void operator=(const volatile A& a) volatile {i = a.i;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+template <class T>
+void testp()
+{
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        A t;
+        std::atomic_init(&t, T(3*sizeof(X)));
+        assert(std::atomic_fetch_sub_explicit(&t, 2,
+                                  std::memory_order_seq_cst) == T(3*sizeof(X)));
+        assert(t == T(1*sizeof(X)));
+    }
+    {
+        typedef std::atomic<T> A;
+        typedef typename std::remove_pointer<T>::type X;
+        volatile A t;
+        std::atomic_init(&t, T(3*sizeof(X)));
+        assert(std::atomic_fetch_sub_explicit(&t, 2,
+                                  std::memory_order_seq_cst) == T(3*sizeof(X)));
+        assert(t == T(1*sizeof(X)));
+    }
+}
+
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
     testp<int*>();
     testp<const int*>();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
index fc6b97b..42d57de 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -41,24 +42,10 @@
         assert(std::atomic_fetch_xor(&t, T(2)) == T(3));
         assert(t == T(1));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
index 58772aa..8f388fee 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
@@ -23,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     {
         typedef std::atomic<T> A;
         A t;
@@ -43,24 +44,10 @@
                std::memory_order_seq_cst) == T(3));
         assert(t == T(1));
     }
-}
+  }
+};
 
 int main()
 {
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestEachIntegralType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h
new file mode 100644
index 0000000..e31420b
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h
@@ -0,0 +1,51 @@
+#ifndef ATOMIC_HELPERS_H
+#define ATOMIC_HELPERS_H
+
+#include <cassert>
+
+#include "test_macros.h"
+
+struct UserAtomicType
+{
+    int i;
+
+    explicit UserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {}
+
+    friend bool operator==(const UserAtomicType& x, const UserAtomicType& y)
+    { return x.i == y.i; }
+};
+
+template < template <class TestArg> class TestFunctor > 
+struct TestEachIntegralType {
+    void operator()() const {
+        TestFunctor<char>()(); 
+        TestFunctor<signed char>()();
+        TestFunctor<unsigned char>()();
+        TestFunctor<short>()();
+        TestFunctor<unsigned short>()();
+        TestFunctor<int>()();
+        TestFunctor<unsigned int>()();
+        TestFunctor<long>()();
+        TestFunctor<unsigned long>()();
+        TestFunctor<long long>()();
+        TestFunctor<unsigned long long>()();
+        TestFunctor<wchar_t>();
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+        TestFunctor<char16_t>()();
+        TestFunctor<char32_t>()();
+#endif
+    }
+};
+
+template < template <class TestArg> class TestFunctor > 
+struct TestEachAtomicType {
+    void operator()() const {
+        TestEachIntegralType<TestFunctor>()();
+        TestFunctor<UserAtomicType>()();
+        TestFunctor<int*>()();
+        TestFunctor<const int*>()();
+    }
+};
+
+
+#endif // ATOMIC_HELPER_H
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
index 137b6f6..884c02d 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
-//  ... assertion fails line 34
+//  ... assertion fails line 36
 
 // <atomic>
 
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -35,37 +36,10 @@
     volatile A vt;
     std::atomic_init(&vt, T(2));
     assert(vt == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
index ee22912..5d50016 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
@@ -22,17 +22,19 @@
 #include <atomic>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     bool b1 = std::atomic_is_lock_free(static_cast<const A*>(&t));
     volatile A vt;
     bool b2 = std::atomic_is_lock_free(static_cast<const volatile A*>(&vt));
     assert(b1 == b2);
-}
+  }
+};
 
 struct A
 {
@@ -41,23 +43,6 @@
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestFn<A>()();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
index 66918c7..e7b8e64 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
-//  ... assertion fails line 34
+//  ... assertion fails line 35
 
 // <atomic>
 
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -35,37 +36,10 @@
     volatile A vt;
     std::atomic_init(&vt, T(2));
     assert(std::atomic_load(&vt) == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
index 5f402a9..56533fa 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
@@ -24,10 +24,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_init(&t, T(1));
@@ -35,37 +36,10 @@
     volatile A vt;
     std::atomic_init(&vt, T(2));
     assert(std::atomic_load_explicit(&vt, std::memory_order_seq_cst) == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
index 2b9582b..e61dae9 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
-//  ... assertion fails line 31
 
 // <atomic>
 
@@ -24,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_store(&t, T(1));
@@ -35,37 +35,11 @@
     volatile A vt;
     std::atomic_store(&vt, T(2));
     assert(vt == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
index 8fe0c7d..e57cf8b 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
-//  ... assertion fails line 31
 
 // <atomic>
 
@@ -24,10 +23,11 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 template <class T>
-void
-test()
-{
+struct TestFn {
+  void operator()() const {
     typedef std::atomic<T> A;
     A t;
     std::atomic_store_explicit(&t, T(1), std::memory_order_seq_cst);
@@ -35,37 +35,11 @@
     volatile A vt;
     std::atomic_store_explicit(&vt, T(2), std::memory_order_seq_cst);
     assert(vt == T(2));
-}
-
-struct A
-{
-    int i;
-
-    explicit A(int d = 0) noexcept {i=d;}
-
-    friend bool operator==(const A& x, const A& y)
-        {return x.i == y.i;}
+  }
 };
 
+
 int main()
 {
-    test<A>();
-    test<char>();
-    test<signed char>();
-    test<unsigned char>();
-    test<short>();
-    test<unsigned short>();
-    test<int>();
-    test<unsigned int>();
-    test<long>();
-    test<unsigned long>();
-    test<long long>();
-    test<unsigned long long>();
-    test<wchar_t>();
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<char16_t>();
-    test<char32_t>();
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-    test<int*>();
-    test<const int*>();
+    TestEachAtomicType<TestFn>()();
 }
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
index 5fed691..9f25807 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// XFAIL: c++98, c++03
 
 // <atomic>
 
diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
index f85172a..f6944c7 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
@@ -22,6 +22,8 @@
 #include <type_traits>
 #include <cassert>
 
+#include "atomic_helpers.h"
+
 struct UserType {
     int i;
 
@@ -34,27 +36,29 @@
 };
 
 template <class Tp>
-void test() {
-    typedef std::atomic<Tp> Atomic;
-    static_assert(std::is_literal_type<Atomic>::value, "");
-    constexpr Tp t(42);
-    {
-        constexpr Atomic a(t);
-        assert(a == t);
+struct TestFunc {
+    void operator()() const {
+        typedef std::atomic<Tp> Atomic;
+        static_assert(std::is_literal_type<Atomic>::value, "");
+        constexpr Tp t(42);
+        {
+            constexpr Atomic a(t);
+            assert(a == t);
+        }
+        {
+            constexpr Atomic a{t};
+            assert(a == t);
+        }
+        {
+            constexpr Atomic a = ATOMIC_VAR_INIT(t);
+            assert(a == t);
+        }
     }
-    {
-        constexpr Atomic a{t};
-        assert(a == t);
-    }
-    {
-        constexpr Atomic a = ATOMIC_VAR_INIT(t);
-        assert(a == t);
-    }
-}
+};
 
 
 int main()
 {
-    test<int>();
-    test<UserType>();
+    TestFunc<UserType>()();
+    TestEachIntegralType<TestFunc>()();
 }