compute_base_modifiers.hpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #ifndef BOOST_DESCRIBE_DETAIL_COMPUTE_BASE_MODIFIERS_HPP_INCLUDED
  2. #define BOOST_DESCRIBE_DETAIL_COMPUTE_BASE_MODIFIERS_HPP_INCLUDED
  3. // Copyright 2020, 2021 Peter Dimov
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // https://www.boost.org/LICENSE_1_0.txt
  6. #include <boost/describe/modifiers.hpp>
  7. #include <type_traits>
  8. namespace boost
  9. {
  10. namespace describe
  11. {
  12. namespace detail
  13. {
  14. #if defined(_MSC_VER)
  15. # pragma warning(push)
  16. # pragma warning(disable: 4594) // can never be instantiated - indirect virtual base class is inaccessible
  17. # pragma warning(disable: 4624) // destructor was implicitly defined as deleted
  18. #endif
  19. // is_public_base_of
  20. template<class T, class U> using is_public_base_of = std::is_convertible<U*, T*>;
  21. // is_protected_base_of
  22. struct ipb_final
  23. {
  24. template<class T, class U> using fn = std::false_type;
  25. };
  26. struct ipb_non_final
  27. {
  28. template<class T, class U> struct fn: U
  29. {
  30. static std::true_type f( T* );
  31. template<class X> static auto g( X x ) -> decltype( f(x) );
  32. static std::false_type g( ... );
  33. using type = decltype( g((U*)0) );
  34. };
  35. };
  36. template<class T, class U> using is_protected_base_of =
  37. typename std::conditional<std::is_final<U>::value || std::is_union<U>::value, ipb_final, ipb_non_final>::type::template fn<T, U>::type;
  38. // is_virtual_base_of
  39. template<class T, class U, class = void> struct can_cast: std::false_type {};
  40. template<class T, class U> struct can_cast<T, U, decltype((void)(U*)(T*)0)>: std::true_type {};
  41. template<class T, class U> using is_virtual_base_of =
  42. std::integral_constant<bool, can_cast<U, T>::value && !can_cast<T, U>::value>;
  43. // compute_base_modifiers
  44. template<class C, class B> constexpr unsigned compute_base_modifiers() noexcept
  45. {
  46. return (is_public_base_of<B, C>::value? mod_public: (is_protected_base_of<B, C>::value? mod_protected: mod_private)) | (is_virtual_base_of<B, C>::value? mod_virtual: 0);
  47. }
  48. #if defined(_MSC_VER)
  49. # pragma warning(pop)
  50. #endif
  51. } // namespace detail
  52. } // namespace describe
  53. } // namespace boost
  54. #endif // #ifndef BOOST_DESCRIBE_DETAIL_COMPUTE_BASE_MODIFIERS_HPP_INCLUDED