[libcxx] r239664 - [libcxx] Fix detection of __is_final.

Eric Fiselier eric at efcs.ca
Sat Jun 13 00:08:02 PDT 2015


Author: ericwf
Date: Sat Jun 13 02:08:02 2015
New Revision: 239664

URL: http://llvm.org/viewvc/llvm-project?rev=239664&view=rev
Log:
[libcxx] Fix detection of __is_final.

Summary: Currently we only enable the use of __is_final(...) with Clang. GCC also provides __is_final(...) since 4.7 in all standard modes. This patch creates the macro _LIBCPP_HAS_IS_FINAL to note the availability of `__is_final`.

Reviewers: danalbert, mclow.lists

Reviewed By: mclow.lists

Subscribers: cfe-commits

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

Modified:
    libcxx/trunk/include/__config
    libcxx/trunk/include/exception
    libcxx/trunk/include/ext/hash_map
    libcxx/trunk/include/map
    libcxx/trunk/include/memory
    libcxx/trunk/include/tuple
    libcxx/trunk/include/type_traits
    libcxx/trunk/include/unordered_map

Modified: libcxx/trunk/include/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=239664&r1=239663&r2=239664&view=diff
==============================================================================
--- libcxx/trunk/include/__config (original)
+++ libcxx/trunk/include/__config Sat Jun 13 02:08:02 2015
@@ -77,10 +77,8 @@
 #ifdef _WIN32
 #  define _LIBCPP_LITTLE_ENDIAN 1
 #  define _LIBCPP_BIG_ENDIAN    0
-// Compiler intrinsics (GCC or MSVC)
-#  if defined(__clang__) \
-   || (defined(_MSC_VER) && _MSC_VER >= 1400) \
-   || (defined(__GNUC__) && _GNUC_VER > 403)
+// Compiler intrinsics (MSVC)
+#if defined(_MSC_VER) && _MSC_VER >= 1400
 #    define _LIBCPP_HAS_IS_BASE_OF
 #  endif
 #  if defined(_MSC_VER) && !defined(__clang__)
@@ -95,12 +93,6 @@
 #  endif
 #endif  // _WIN32
 
-#ifdef __linux__
-#  if defined(__GNUC__) && _GNUC_VER >= 403
-#    define _LIBCPP_HAS_IS_BASE_OF
-#  endif
-#endif
-
 #ifdef __sun__
 # include <sys/isa_defs.h>
 # ifdef _LITTLE_ENDIAN
@@ -320,6 +312,10 @@ typedef __char32_t char32_t;
 #  define _LIBCPP_HAS_IS_BASE_OF
 #endif
 
+#if __has_feature(is_final)
+#  define _LIBCPP_HAS_IS_FINAL
+#endif
+
 // Objective-C++ features (opt-in)
 #if __has_feature(objc_arc)
 #define _LIBCPP_HAS_OBJC_ARC
@@ -403,6 +399,11 @@ namespace std {
 #if _GNUC_VER >= 407
 #define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T)
 #define _LIBCPP_IS_LITERAL(T) __is_literal_type(T)
+#define _LIBCPP_HAS_IS_FINAL
+#endif
+
+#if defined(__GNUC__) && _GNUC_VER >= 403
+#  define _LIBCPP_HAS_IS_BASE_OF
 #endif
 
 #if !__EXCEPTIONS
@@ -537,6 +538,7 @@ namespace std {
 #define _LIBCPP_HAS_NO_NULLPTR
 #define _LIBCPP_HAS_NO_UNICODE_CHARS
 #define _LIBCPP_HAS_IS_BASE_OF
+#define _LIBCPP_HAS_IS_FINAL
 #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
 
 #if defined(_AIX)

Modified: libcxx/trunk/include/exception
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/exception?rev=239664&r1=239663&r2=239664&view=diff
==============================================================================
--- libcxx/trunk/include/exception (original)
+++ libcxx/trunk/include/exception Sat Jun 13 02:08:02 2015
@@ -195,9 +195,7 @@ void
 throw_with_nested(_Tp&& __t, typename enable_if<
                   is_class<typename remove_reference<_Tp>::type>::value &&
                   !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
-#if _LIBCPP_STD_VER > 11 && __has_feature(is_final)
-                  && !is_final<typename remove_reference<_Tp>::type>::value
-#endif
+                  && !__libcpp_is_final<typename remove_reference<_Tp>::type>::value
                                     >::type* = 0)
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 throw_with_nested (_Tp& __t, typename enable_if<
@@ -217,9 +215,7 @@ void
 throw_with_nested(_Tp&& __t, typename enable_if<
                   !is_class<typename remove_reference<_Tp>::type>::value ||
                   is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
-#if _LIBCPP_STD_VER > 11 && __has_feature(is_final)
-                  || is_final<typename remove_reference<_Tp>::type>::value
-#endif
+                  || __libcpp_is_final<typename remove_reference<_Tp>::type>::value
                                     >::type* = 0)
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 throw_with_nested (_Tp& __t, typename enable_if<

Modified: libcxx/trunk/include/ext/hash_map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/ext/hash_map?rev=239664&r1=239663&r2=239664&view=diff
==============================================================================
--- libcxx/trunk/include/ext/hash_map (original)
+++ libcxx/trunk/include/ext/hash_map Sat Jun 13 02:08:02 2015
@@ -203,6 +203,7 @@ template <class Key, class T, class Hash
 #include <__hash_table>
 #include <functional>
 #include <stdexcept>
+#include <type_traits>
 #include <ext/__hash>
 
 #if __DEPRECATED
@@ -213,16 +214,16 @@ template <class Key, class T, class Hash
 #endif
 #endif
 
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
+#endif
 
 namespace __gnu_cxx {
 
 using namespace std;
 
-template <class _Tp, class _Hash, bool = is_empty<_Hash>::value
-#if __has_feature(is_final)
-                                         && !__is_final(_Hash)
-#endif
+template <class _Tp, class _Hash,
+          bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value
         >
 class __hash_map_hasher
     : private _Hash
@@ -255,10 +256,8 @@ public:
         {return __hash_(__x);}
 };
 
-template <class _Tp, class _Pred, bool = is_empty<_Pred>::value
-#if __has_feature(is_final)
-                                         && !__is_final(_Pred)
-#endif
+template <class _Tp, class _Pred,
+          bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
          >
 class __hash_map_equal
     : private _Pred

Modified: libcxx/trunk/include/map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/map?rev=239664&r1=239663&r2=239664&view=diff
==============================================================================
--- libcxx/trunk/include/map (original)
+++ libcxx/trunk/include/map Sat Jun 13 02:08:02 2015
@@ -428,6 +428,7 @@ swap(multimap<Key, T, Compare, Allocator
 #include <utility>
 #include <functional>
 #include <initializer_list>
+#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -435,10 +436,8 @@ swap(multimap<Key, T, Compare, Allocator
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value
-#if __has_feature(is_final)
-                                                        && !__is_final(_Compare)
-#endif
+template <class _Key, class _CP, class _Compare,
+          bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value
          >
 class __map_value_compare
     : private _Compare

Modified: libcxx/trunk/include/memory
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=239664&r1=239663&r2=239664&view=diff
==============================================================================
--- libcxx/trunk/include/memory (original)
+++ libcxx/trunk/include/memory Sat Jun 13 02:08:02 2015
@@ -1982,14 +1982,9 @@ public:
 template <class _T1, class _T2, bool = is_same<typename remove_cv<_T1>::type,
                                                      typename remove_cv<_T2>::type>::value,
                                 bool = is_empty<_T1>::value
-#if __has_feature(is_final)
-                                       && !__is_final(_T1)
-#endif
-                                ,
+                                       && !__libcpp_is_final<_T1>::value,
                                 bool = is_empty<_T2>::value
-#if __has_feature(is_final)
-                                       && !__is_final(_T2)
-#endif
+                                       && !__libcpp_is_final<_T2>::value
          >
 struct __libcpp_compressed_pair_switch;
 

Modified: libcxx/trunk/include/tuple
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=239664&r1=239663&r2=239664&view=diff
==============================================================================
--- libcxx/trunk/include/tuple (original)
+++ libcxx/trunk/include/tuple Sat Jun 13 02:08:02 2015
@@ -161,10 +161,8 @@ using tuple_element_t = typename tuple_e
 
 // __tuple_leaf
 
-template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
-#if __has_feature(is_final)
-                                 && !__is_final(_Hp)
-#endif
+template <size_t _Ip, class _Hp,
+          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
          >
 class __tuple_leaf;
 

Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=239664&r1=239663&r2=239664&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Sat Jun 13 02:08:02 2015
@@ -803,8 +803,16 @@ template <class _Tp> struct _LIBCPP_TYPE
 
 // is_final
 
-#if _LIBCPP_STD_VER > 11 && __has_feature(is_final)
-template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY 
+#if defined(_LIBCPP_HAS_IS_FINAL)
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
+__libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};
+#else
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
+__libcpp_is_final : public false_type {};
+#endif
+
+#if defined(_LIBCPP_HAS_IS_FINAL) && _LIBCPP_STD_VER > 11
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
 is_final : public integral_constant<bool, __is_final(_Tp)> {};
 #endif
 

Modified: libcxx/trunk/include/unordered_map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/unordered_map?rev=239664&r1=239663&r2=239664&view=diff
==============================================================================
--- libcxx/trunk/include/unordered_map (original)
+++ libcxx/trunk/include/unordered_map Sat Jun 13 02:08:02 2015
@@ -361,10 +361,8 @@ template <class Key, class T, class Hash
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Key, class _Cp, class _Hash, bool = is_empty<_Hash>::value
-#if __has_feature(is_final)
-                                         && !__is_final(_Hash)
-#endif
+template <class _Key, class _Cp, class _Hash,
+          bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value
          >
 class __unordered_map_hasher
     : private _Hash
@@ -412,10 +410,8 @@ public:
         {return __hash_(__x);}
 };
 
-template <class _Key, class _Cp, class _Pred, bool = is_empty<_Pred>::value
-#if __has_feature(is_final)
-                                         && !__is_final(_Pred)
-#endif
+template <class _Key, class _Cp, class _Pred,
+          bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
          >
 class __unordered_map_equal
     : private _Pred





More information about the cfe-commits mailing list