EricWF created this revision.
EricWF added reviewers: mclow.lists, chandlerc, jroelofs.
EricWF added a subscriber: cfe-commits.
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.
http://reviews.llvm.org/D11555
Files:
include/__config
include/atomic
include/ios
include/memory
src/ios.cpp
src/memory.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/atomic_compare_exchange_strong.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_weak.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_exchange.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_fetch_add.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_and.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_or.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_sub.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_xor.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_helpers.h
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_is_lock_free.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_explicit.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_explicit.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/ctor.pass.cpp
test/support/test_macros.h
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/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;
@@ -55,6 +57,6 @@
int main()
{
- test<int>();
test<UserType>();
+ TEST_EACH_ATOMIC_INTEGRAL();
}
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,9 +23,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
typedef std::atomic<T> A;
A t;
@@ -37,35 +37,8 @@
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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,9 +23,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
typedef std::atomic<T> A;
A t;
@@ -37,35 +37,8 @@
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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,9 +24,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
typedef std::atomic<T> A;
A t;
@@ -37,35 +38,7 @@
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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,9 +24,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
typedef std::atomic<T> A;
A t;
@@ -37,35 +38,7 @@
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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,9 +22,10 @@
#include <atomic>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
typedef std::atomic<T> A;
A t;
@@ -42,22 +43,5 @@
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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,6 +24,8 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
void
test()
@@ -37,35 +39,7 @@
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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,49 @@
+#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; }
+};
+
+#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS
+#define TEST_UNICODE_CHAR_TYPES_IMP()
+#else
+#define TEST_UNICODE_CHAR_TYPES_IMP() \
+ test<char16_t>(); \
+ test<char32_t>();
+#
+#endif
+
+#define TEST_EACH_ATOMIC_INTEGRAL() \
+ 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_UNICODE_CHAR_TYPES_IMP() \
+ test<wchar_t>()
+
+#define TEST_EACH_ATOMIC_TYPE() \
+ TEST_EACH_ATOMIC_INTEGRAL(); \
+ test<UserAtomicType>(); \
+ test<int*>(); \
+ test<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,6 +23,8 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
void
test()
@@ -47,20 +49,5 @@
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
+ TEST_EACH_ATOMIC_INTEGRAL();
}
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,9 +23,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -45,20 +46,5 @@
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
+ TEST_EACH_ATOMIC_INTEGRAL();
}
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,9 +33,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -56,8 +57,7 @@
}
template <class T>
-void
-testp()
+void testp()
{
{
typedef std::atomic<T> A;
@@ -79,38 +79,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
+ TEST_EACH_ATOMIC_INTEGRAL();
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,9 +32,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -53,8 +54,7 @@
}
template <class T>
-void
-testp()
+void testp()
{
{
typedef std::atomic<T> A;
@@ -74,38 +74,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
+ TEST_EACH_ATOMIC_INTEGRAL();
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,9 +23,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -47,20 +48,5 @@
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
+ TEST_EACH_ATOMIC_INTEGRAL();
}
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,9 +23,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -45,20 +46,5 @@
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
+ TEST_EACH_ATOMIC_INTEGRAL();
}
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,9 +23,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -47,20 +48,5 @@
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
+ TEST_EACH_ATOMIC_INTEGRAL();
}
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,9 +23,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -45,20 +46,5 @@
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
+ TEST_EACH_ATOMIC_INTEGRAL();
}
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,9 +32,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -78,38 +79,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
+ TEST_EACH_ATOMIC_INTEGRAL();
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,9 +32,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -53,8 +54,7 @@
}
template <class T>
-void
-testp()
+void testp()
{
{
typedef std::atomic<T> A;
@@ -74,38 +74,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
+ TEST_EACH_ATOMIC_INTEGRAL();
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,9 +24,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
typedef std::atomic<T> A;
A t;
@@ -41,35 +42,8 @@
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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,9 +24,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
typedef std::atomic<T> A;
A t;
@@ -39,35 +40,8 @@
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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,9 +29,10 @@
#include <cmpxchg_loop.h>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -63,35 +64,7 @@
}
}
-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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,10 +25,10 @@
#include <cassert>
#include <cmpxchg_loop.h>
+#include "atomic_helpers.h"
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -56,35 +56,7 @@
}
}
-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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,9 +27,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -61,35 +62,7 @@
}
}
-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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
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,9 +24,10 @@
#include <type_traits>
#include <cassert>
+#include "atomic_helpers.h"
+
template <class T>
-void
-test()
+void test()
{
{
typedef std::atomic<T> A;
@@ -54,35 +55,7 @@
}
}
-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*>();
+ TEST_EACH_ATOMIC_TYPE();
}
Index: test/std/atomics/atomics.flag/init03.pass.cpp
===================================================================
--- /dev/null
+++ 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);
+}
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: 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/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/__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
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits