Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -75,10 +75,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__) @@ -93,12 +91,6 @@ # endif #endif // _WIN32 -#ifdef __linux__ -# if defined(__GNUC__) && _GNUC_VER >= 403 -# define _LIBCPP_HAS_IS_BASE_OF -# endif -#endif - #ifdef __sun__ # include # ifdef _LITTLE_ENDIAN @@ -318,6 +310,10 @@ # 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 @@ -401,6 +397,11 @@ #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 @@ -535,6 +536,7 @@ #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) Index: include/exception =================================================================== --- include/exception +++ include/exception @@ -193,9 +193,7 @@ throw_with_nested(_Tp&& __t, typename enable_if< is_class::type>::value && !is_base_of::type>::value -#if _LIBCPP_STD_VER > 11 && __has_feature(is_final) - && !is_final::type>::value -#endif + && !__libcpp_is_final::type>::value >::type* = 0) #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES throw_with_nested (_Tp& __t, typename enable_if< @@ -215,9 +213,7 @@ throw_with_nested(_Tp&& __t, typename enable_if< !is_class::type>::value || is_base_of::type>::value -#if _LIBCPP_STD_VER > 11 && __has_feature(is_final) - || is_final::type>::value -#endif + || __libcpp_is_final::type>::value >::type* = 0) #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES throw_with_nested (_Tp& __t, typename enable_if< Index: include/ext/hash_map =================================================================== --- include/ext/hash_map +++ include/ext/hash_map @@ -203,6 +203,7 @@ #include <__hash_table> #include #include +#include #include #if __DEPRECATED @@ -213,16 +214,16 @@ #endif #endif +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header +#endif namespace __gnu_cxx { using namespace std; -template ::value -#if __has_feature(is_final) - && !__is_final(_Hash) -#endif +template ::value && !__libcpp_is_final<_Hash>::value > class __hash_map_hasher : private _Hash @@ -255,10 +256,8 @@ {return __hash_(__x);} }; -template ::value -#if __has_feature(is_final) - && !__is_final(_Pred) -#endif +template ::value && !__libcpp_is_final<_Pred>::value > class __hash_map_equal : private _Pred Index: include/map =================================================================== --- include/map +++ include/map @@ -428,6 +428,7 @@ #include #include #include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -435,10 +436,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template ::value -#if __has_feature(is_final) - && !__is_final(_Compare) -#endif +template ::value && !__libcpp_is_final<_Compare>::value > class __map_value_compare : private _Compare Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -1947,14 +1947,9 @@ template ::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; Index: include/tuple =================================================================== --- include/tuple +++ include/tuple @@ -161,10 +161,8 @@ // __tuple_leaf -template ::value -#if __has_feature(is_final) - && !__is_final(_Hp) -#endif +template ::value && !__libcpp_is_final<_Hp>::value > class __tuple_leaf; Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -809,8 +809,16 @@ // is_final -#if _LIBCPP_STD_VER > 11 && __has_feature(is_final) -template struct _LIBCPP_TYPE_VIS_ONLY +#if defined(_LIBCPP_HAS_IS_FINAL) +template struct _LIBCPP_TYPE_VIS_ONLY +__libcpp_is_final : public integral_constant {}; +#else +template struct _LIBCPP_TYPE_VIS_ONLY +__libcpp_is_final : public false_type {}; +#endif + +#if defined(_LIBCPP_HAS_IS_FINAL) && _LIBCPP_STD_VER > 11 +template struct _LIBCPP_TYPE_VIS_ONLY is_final : public integral_constant {}; #endif Index: include/unordered_map =================================================================== --- include/unordered_map +++ include/unordered_map @@ -361,10 +361,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template ::value -#if __has_feature(is_final) - && !__is_final(_Hash) -#endif +template ::value && !__libcpp_is_final<_Hash>::value > class __unordered_map_hasher : private _Hash @@ -412,10 +410,8 @@ {return __hash_(__x);} }; -template ::value -#if __has_feature(is_final) - && !__is_final(_Pred) -#endif +template ::value && !__libcpp_is_final<_Pred>::value > class __unordered_map_equal : private _Pred