[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-commits
Subject:    Re: [PATCH] D11555: [libcxx] Allow use of <atomic> in C++03. Try 3.
From:       Eric Fiselier <eric () efcs ! ca>
Date:       2015-07-30 4:36:40
Message-ID: fbaf606accf0bed33f1cf68dc39d23de () localhost ! localdomain
[Download RAW message or body]

EricWF updated this revision to Diff 30985.
EricWF updated the summary for this revision.
EricWF added a comment.

- Address review comments.


http://reviews.llvm.org/D11555

Files:
  include/__config
  include/algorithm
  include/atomic
  include/ios
  include/memory
  include/type_traits
  src/ios.cpp
  src/memory.cpp
  test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
  test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
  test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
  test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
  test/std/atomics/atomics.flag/clear.pass.cpp
  test/std/atomics/atomics.flag/init.pass.cpp
  test/std/atomics/atomics.flag/init03.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_compare_exchange_strong.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_compare_exchange_strong_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_compare_exchange_weak.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_compare_exchange_weak_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_exchange.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_exchange_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_add.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_add_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_and.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_and_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_or.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_or_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_sub.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_sub_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_xor.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_fetch_xor_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_helpers.h
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_init.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_is_lock_free.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_load.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_load_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_store.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_store_explicit.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/at=
omic_var_init.pass.cpp
  test/std/atomics/atomics.types.operations/atomics.types.operations.req/ct=
or.pass.cpp
  test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/m=
ove2.pass.cpp
  test/support/test_macros.h


["D11555.30985.patch" (text/x-patch)]

Index: test/support/test_macros.h
===================================================================
--- test/support/test_macros.h
+++ test/support/test_macros.h
@@ -56,8 +56,10 @@
 #endif
 
 #if TEST_STD_VER >= 11
+#define TEST_CONSTEXPR constexpr
 #define TEST_NOEXCEPT noexcept
 #else
+#define TEST_CONSTEXPR
 #define TEST_NOEXCEPT
 #endif
 
Index: test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
 ===================================================================
--- test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
                
+++ test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
 @@ -10,13 +10,6 @@
 // UNSUPPORTED: libcpp-has-no-threads
 // UNSUPPORTED: c++98, c++03
 
-// NOTE: std::terminate is called so the destructors are not invoked and the
-// memory is not freed. This will cause ASAN to fail.
-// XFAIL: asan
-
-// NOTE: TSAN will report this test as leaking a thread.
-// XFAIL: tsan
-
 // <thread>
 
 // class thread
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
                
+++ 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);
-    }
-    {
-        constexpr Atomic a{t};
-        assert(a == t);
-    }
-    {
-        constexpr Atomic a = ATOMIC_VAR_INIT(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);
+        }
     }
-}
+};
 
 
 int main()
 {
-    test<int>();
-    test<UserType>();
+    TestFunc<UserType>()();
+    TestEachIntegralType<TestFunc>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp
                
+++ 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>
 
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
                
+++ 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,48 +23,23 @@
 #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);
     assert(t == T(1));
     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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
                
+++ 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,48 +23,23 @@
 #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));
     assert(t == T(1));
     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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
                
+++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
 @@ -24,48 +24,22 @@
 #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));
     assert(std::atomic_load_explicit(&t, std::memory_order_seq_cst) == T(1));
     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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
                
+++ 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,48 +24,22 @@
 #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));
     assert(std::atomic_load(&t) == T(1));
     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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
                
+++ test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
 @@ -22,42 +22,27 @@
 #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
 {
     char _[4];
 };
 
 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
                
+++ 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,48 +24,22 @@
 #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));
     assert(t == T(1));
     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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h
 ===================================================================
--- /dev/null
+++ 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
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
                
+++ 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,11 +54,11 @@
                                             std::memory_order_seq_cst) == T(3));
         assert(t == T(1));
     }
-}
+  }
+};
 
 template <class T>
-void
-testp()
+void testp()
 {
     {
         typedef std::atomic<T> A;
@@ -79,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*>();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
                
+++ 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,11 +51,11 @@
         assert(std::atomic_fetch_sub(&t, T(2)) == T(3));
         assert(t == T(1));
     }
-}
+  }
+};
 
 template <class T>
-void
-testp()
+void testp()
 {
     {
         typedef std::atomic<T> A;
@@ -74,38 +75,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*>();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
                
+++ 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*>();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
                
+++ 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,11 +51,11 @@
         assert(std::atomic_fetch_add(&t, T(2)) == T(1));
         assert(t == T(3));
     }
-}
+  }
+};
 
 template <class T>
-void
-testp()
+void testp()
 {
     {
         typedef std::atomic<T> A;
@@ -74,38 +75,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*>();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
 ===================================================================
--- test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
                
+++ 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>()();
 }
Index: test/std/atomics/atomics.flag/init03.pass.cpp
===================================================================
--- test/std/atomics/atomics.flag/init03.pass.cpp
+++ test/std/atomics/atomics.flag/init03.pass.cpp
@@ -13,13 +13,13 @@
 
 // struct atomic_flag
 
-// atomic_flag() = ATOMIC_FLAG_INIT;
+// TESTING EXTENSION atomic_flag(bool)
 
 #include <atomic>
 #include <cassert>
 
 int main()
 {
-    std::atomic_flag f = ATOMIC_FLAG_INIT;
+    std::atomic_flag f(false);
     assert(f.test_and_set() == 0);
 }
Index: test/std/atomics/atomics.flag/init.pass.cpp
===================================================================
--- test/std/atomics/atomics.flag/init.pass.cpp
+++ test/std/atomics/atomics.flag/init.pass.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 // UNSUPPORTED: libcpp-has-no-threads
+// XFAIL: c++98, c++03
 
 // <atomic>
 
Index: test/std/atomics/atomics.flag/clear.pass.cpp
===================================================================
--- test/std/atomics/atomics.flag/clear.pass.cpp
+++ 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);
Index: test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
===================================================================
--- test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
+++ 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);
Index: test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
===================================================================
--- test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
+++ 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);
Index: test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
===================================================================
--- test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
+++ test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
@@ -18,7 +18,10 @@
 #include <algorithm>
 #include <functional>
 #include <cassert>
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#include "test_macros.h"
+
+#ifndef TEST_STD_VER >= 11
 #include <memory>
 
 struct indirect_less
@@ -28,7 +31,29 @@
         {return *x < *y;}
 };
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+struct S {
+	S() : i_(0) {}
+	S(int i) : i_(i) {}
+	
+	S(const S&  rhs) : i_(rhs.i_) {}
+	S(      S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }
+	
+	S& operator =(const S&  rhs) { i_ = rhs.i_;              return *this; }
+	S& operator =(      S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); \
return *this; } +	S& operator =(int i)         { i_ = i;                   return \
*this; } +	
+	bool operator  <(const S&  rhs) const { return i_ < rhs.i_; }
+	bool operator  >(const S&  rhs) const { return i_ > rhs.i_; }
+	bool operator ==(const S&  rhs) const { return i_ == rhs.i_; }
+	bool operator ==(int i)         const { return i_ == i; }
+
+	void set(int i) { i_ = i; }
+	
+	int i_;
+	};
+
+
+#endif  // TEST_STD_VER >= 11
 
 #include "test_iterators.h"
 #include "counting_predicates.hpp"
@@ -38,19 +63,20 @@
 test_one(unsigned N, unsigned M)
 {
     assert(M <= N);
-    int* ia = new int[N];
+    typedef typename std::iterator_traits<Iter>::value_type value_type;
+    value_type* ia = new value_type[N];
     for (unsigned i = 0; i < N; ++i)
         ia[i] = i;
     std::random_shuffle(ia, ia+N);
-    std::sort(ia, ia+M, std::greater<int>());
-    std::sort(ia+M, ia+N, std::greater<int>());
-    binary_counting_predicate<std::greater<int>, int, int> \
pred((std::greater<int>())); +    std::sort(ia, ia+M, std::greater<value_type>());
+    std::sort(ia+M, ia+N, std::greater<value_type>());
+    binary_counting_predicate<std::greater<value_type>, value_type, value_type> \
pred((std::greater<value_type>()));  std::inplace_merge(Iter(ia), Iter(ia+M), \
Iter(ia+N), std::ref(pred));  if(N > 0)
     {
         assert(ia[0] == N-1);
         assert(ia[N-1] == 0);
-        assert(std::is_sorted(ia, ia+N, std::greater<int>()));
+        assert(std::is_sorted(ia, ia+N, std::greater<value_type>()));
         assert(pred.count() <= (N-1));
     }
     delete [] ia;
@@ -93,7 +119,11 @@
     test<random_access_iterator<int*> >();
     test<int*>();
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef TEST_STD_VER >= 11
+    test<bidirectional_iterator<S*> >();
+    test<random_access_iterator<S*> >();
+    test<S*>();
+
     {
     unsigned N = 100;
     unsigned M = 50;
@@ -112,5 +142,5 @@
     }
     delete [] ia;
     }
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif  // TEST_STD_VER >= 11
 }
Index: test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
===================================================================
--- test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
+++ test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
@@ -20,12 +20,35 @@
 
 #include "test_iterators.h"
 
+#ifndef TEST_STD_VER >= 11
+struct S {
+	S() : i_(0) {}
+	S(int i) : i_(i) {}
+	
+	S(const S&  rhs) : i_(rhs.i_) {}
+	S(      S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }
+	
+	S& operator =(const S&  rhs) { i_ = rhs.i_;              return *this; }
+	S& operator =(      S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); \
return *this; } +	S& operator =(int i)         { i_ = i;                   return \
*this; } +	
+	bool operator  <(const S&  rhs) const { return i_ < rhs.i_; }
+	bool operator ==(const S&  rhs) const { return i_ == rhs.i_; }
+	bool operator ==(int i)         const { return i_ == i; }
+
+	void set(int i) { i_ = i; }
+	
+	int i_;
+	};
+#endif
+
 template <class Iter>
 void
 test_one(unsigned N, unsigned M)
 {
+    typedef typename std::iterator_traits<Iter>::value_type value_type;
     assert(M <= N);
-    int* ia = new int[N];
+    value_type* ia = new value_type[N];
     for (unsigned i = 0; i < N; ++i)
         ia[i] = i;
     std::random_shuffle(ia, ia+N);
@@ -76,4 +99,10 @@
     test<bidirectional_iterator<int*> >();
     test<random_access_iterator<int*> >();
     test<int*>();
+
+#ifndef TEST_STD_VER >= 11
+    test<bidirectional_iterator<S*> >();
+    test<random_access_iterator<S*> >();
+    test<S*>();
+#endif  // TEST_STD_VER >= 11
 }
Index: src/memory.cpp
===================================================================
--- src/memory.cpp
+++ src/memory.cpp
@@ -124,7 +124,7 @@
 
 #endif  // _LIBCPP_NO_RTTI
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 static const std::size_t __sp_mut_count = 16;
 static pthread_mutex_t mut_back_imp[__sp_mut_count] =
@@ -177,7 +177,7 @@
     return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
 }
 
-#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS
+#endif // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 void
 declare_reachable(void*)
Index: src/ios.cpp
===================================================================
--- src/ios.cpp
+++ src/ios.cpp
@@ -152,7 +152,7 @@
 }
 
 // xalloc
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 atomic<int> ios_base::__xindex_ = ATOMIC_VAR_INIT(0);
 #else
 int ios_base::__xindex_ = 0;
Index: include/type_traits
===================================================================
--- include/type_traits
+++ include/type_traits
@@ -474,7 +474,7 @@
 // template <class _Tp, class _Up> struct __libcpp_is_member_function_pointer<_Tp \
_Up::*> : public is_function<_Tp> {};  // 
 
-template <class _MP, bool _IsMemberFuctionPtr, bool _IsMemberObjectPtr>
+template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
 struct __member_pointer_traits_imp
 {  // forward declaration; specializations later
 };
Index: include/memory
===================================================================
--- include/memory
+++ include/memory
@@ -612,7 +612,7 @@
     #include <cassert>
 #endif
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 #  include <atomic>
 #endif
 
@@ -5381,7 +5381,9 @@
 basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only
+// enabled with clang.
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 class _LIBCPP_TYPE_VIS __sp_mut
 {
@@ -5507,7 +5509,7 @@
     return atomic_compare_exchange_weak(__p, __v, __w);
 }
 
-#endif  // __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#endif  // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
 
 //enum class
 struct _LIBCPP_TYPE_VIS pointer_safety
Index: include/ios
===================================================================
--- include/ios
+++ include/ios
@@ -216,7 +216,7 @@
 #include <__locale>
 #include <system_error>
 
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 #include <atomic>     // for __xindex_
 #endif
 
@@ -367,7 +367,9 @@
     int*            __index_;
     size_t          __event_size_;
     size_t          __event_cap_;
-#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
+// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only
+// enabled with clang.
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
     static atomic<int> __xindex_;
 #else
     static int      __xindex_;
Index: include/atomic
===================================================================
--- include/atomic
+++ include/atomic
@@ -535,21 +535,20 @@
 
 #ifdef _LIBCPP_HAS_NO_THREADS
 #error <atomic> is not supported on this single threaded system
-#else // !_LIBCPP_HAS_NO_THREADS
+#endif
+#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
+#error <atomic> is not implemented
+#endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#if !__has_feature(cxx_atomic) && _GNUC_VER < 407
-#error <atomic> is not implemented
-#else
-
 typedef enum memory_order
 {
     memory_order_relaxed, memory_order_consume, memory_order_acquire,
     memory_order_release, memory_order_acq_rel, memory_order_seq_cst
 } memory_order;
 
-#if _GNUC_VER >= 407
+#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
 namespace __gcc_atomic {
 template <typename _Tp>
 struct __gcc_atomic_t {
@@ -805,7 +804,7 @@
   return __atomic_fetch_xor(&__a->__a_value, __pattern,
                             __gcc_atomic::__to_gcc_order(__order));
 }
-#endif // _GNUC_VER >= 407
+#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP
 
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -825,7 +824,7 @@
     _LIBCPP_INLINE_VISIBILITY
     bool is_lock_free() const volatile _NOEXCEPT
     {
-#if __has_feature(cxx_atomic)
+#if defined(_LIBCPP_HAS_C_ATOMIC_IMP)
     return __c11_atomic_is_lock_free(sizeof(_Tp));
 #else
     return __atomic_is_lock_free(sizeof(_Tp), 0);
@@ -1779,8 +1778,6 @@
 #define ATOMIC_FLAG_INIT {false}
 #define ATOMIC_VAR_INIT(__v) {__v}
 
-// lock-free property
-
 #define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
 #define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
 #define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
@@ -1792,10 +1789,6 @@
 #define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
 #define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
 
-#endif  //  !__has_feature(cxx_atomic)
-
 _LIBCPP_END_NAMESPACE_STD
 
-#endif  // !_LIBCPP_HAS_NO_THREADS
-
 #endif  // _LIBCPP_ATOMIC
Index: include/algorithm
===================================================================
--- include/algorithm
+++ include/algorithm
@@ -4361,6 +4361,34 @@
 
 // inplace_merge
 
+template <class _Compare, class _InputIterator1, class _InputIterator2,
+          class _OutputIterator>
+void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,
+                          _InputIterator2 __first2, _InputIterator2 __last2,
+                          _OutputIterator __result, _Compare __comp)
+{
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+        {
+            _VSTD::move(__first1, __last1, __result);
+            return;
+        }
+
+        if (__comp(*__first2, *__first1))
+        {
+            *__result = _VSTD::move(*__first2);
+            ++__first2;
+        }
+        else
+        {
+            *__result = _VSTD::move(*__first1);
+            ++__first1;
+        }
+    }
+    // __first2 through __last2 are already in the right spot.
+}
+
 template <class _Compare, class _BidirectionalIterator>
 void
 __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator \
__middle, _BidirectionalIterator __last, @@ -4376,22 +4404,18 @@
         value_type* __p = __buff;
         for (_BidirectionalIterator __i = __first; __i != __middle; \
__d.__incr((value_type*)0), (void) ++__i, ++__p)  ::new(__p) \
                value_type(_VSTD::move(*__i));
-        __merge<_Compare>(move_iterator<value_type*>(__buff),
-                          move_iterator<value_type*>(__p),
-                          move_iterator<_BidirectionalIterator>(__middle),
-                          move_iterator<_BidirectionalIterator>(__last),
-                          __first, __comp);
+        __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp);
     }
     else
     {
         value_type* __p = __buff;
         for (_BidirectionalIterator __i = __middle; __i != __last; \
__d.__incr((value_type*)0), (void) ++__i, ++__p)  ::new(__p) \
value_type(_VSTD::move(*__i));  typedef reverse_iterator<_BidirectionalIterator> \
_RBi;  typedef reverse_iterator<value_type*> _Rv;
-        __merge(move_iterator<_RBi>(_RBi(__middle)), \
                move_iterator<_RBi>(_RBi(__first)),
-                move_iterator<_Rv>(_Rv(__p)), move_iterator<_Rv>(_Rv(__buff)),
-                _RBi(__last), __negate<_Compare>(__comp));
+        __half_inplace_merge(_Rv(__p), _Rv(__buff), 
+                             _RBi(__middle), _RBi(__first),
+                             _RBi(__last), __negate<_Compare>(__comp));
     }
 }
 
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -37,6 +37,9 @@
 #ifndef __has_builtin
 #define __has_builtin(__x) 0
 #endif
+#ifndef __has_extension
+#define __has_extension(__x) 0
+#endif
 #ifndef __has_feature
 #define __has_feature(__x) 0
 #endif
@@ -767,4 +770,15 @@
 #define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
 #endif
 
-#endif  // _LIBCPP_CONFIG
+#if __has_extension(c_atomic)
+#define _LIBCPP_HAS_C_ATOMIC_IMP
+#elif _GNUC_VER > 407
+#define _LIBCPP_HAS_GCC_ATOMIC_IMP
+#endif
+
+#if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)) \
+     || defined(_LIBCPP_HAS_NO_THREADS)
+#define _LIBCPP_HAS_NO_ATOMIC_HEADER
+#endif
+
+#endif // _LIBCPP_CONFIG



_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic