summaryrefslogtreecommitdiffstats
path: root/libcxx
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-12-20 04:20:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-12-20 04:20:28 +0000
commite3fbbccc0f18dfd28723a429d913df7c12a7056a (patch)
treefcb164312081640ad57845cb9239887ff47c16cf /libcxx
parentb1527b75055263165e7cde8db7da9980db18a9c7 (diff)
downloadbcm5719-llvm-e3fbbccc0f18dfd28723a429d913df7c12a7056a.tar.gz
bcm5719-llvm-e3fbbccc0f18dfd28723a429d913df7c12a7056a.zip
Implement std::is_base_of for the case where we don't have a compiler
intrinsic. This relies upon the fact that overload resolution does not check access and ambiguity for a derived-to-base conversion. This passes all is_base_of tests in the test suite. llvm-svn: 170662
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/include/type_traits23
1 files changed, 22 insertions, 1 deletions
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index 26c37dfa0c7..8f1c6024c71 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -617,7 +617,28 @@ struct _LIBCPP_VISIBLE is_base_of
#else // __has_feature(is_base_of)
-#error is_base_of not implemented.
+namespace __is_base_of_imp
+{
+template <class _Tp>
+struct _Dst
+{
+ _Dst(const volatile _Tp &);
+};
+template <class _Tp>
+struct _Src
+{
+ operator const volatile _Tp &();
+ template <class _Up> operator const _Dst<_Up> &();
+};
+template <size_t> struct __one { typedef char type; };
+template <class _Bp, class _Dp> typename __one<sizeof(_Dst<_Bp>(declval<_Src<_Dp> >()))>::type __test(int);
+template <class _Bp, class _Dp> __two __test(...);
+}
+
+template <class _Bp, class _Dp>
+struct _LIBCPP_VISIBLE is_base_of
+ : public integral_constant<bool, is_class<_Bp>::value &&
+ sizeof(__is_base_of_imp::__test<_Bp, _Dp>(0)) == 2> {};
#endif // __has_feature(is_base_of)
OpenPOWER on IntegriCloud