You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

43 line
1.4KB

  1. // (C) Copyright Kevlin Henney and Dave Abrahams 1999.
  2. // Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef RANGES_V3_UTILITY_POLYMORPHIC_CAST_HPP
  6. #define RANGES_V3_UTILITY_POLYMORPHIC_CAST_HPP
  7. #include <memory>
  8. #include <type_traits>
  9. #include <meta/meta.hpp>
  10. #include <range/v3/detail/config.hpp>
  11. namespace ranges
  12. {
  13. template<typename Target, typename Source>
  14. auto polymorphic_downcast(Source * x) noexcept
  15. -> meta::if_<std::is_pointer<Target>,
  16. decltype((static_cast<Target>(x), dynamic_cast<Target>(x)))>
  17. {
  18. auto result = static_cast<Target>(x);
  19. RANGES_ASSERT(dynamic_cast<Target>(x) == result);
  20. return result;
  21. }
  22. template<typename Target, typename Source>
  23. auto polymorphic_downcast(Source && x) noexcept
  24. -> meta::if_<std::is_reference<Target>,
  25. decltype((static_cast<Target>(std::declval<Source>()),
  26. dynamic_cast<Target>(std::declval<Source>())))>
  27. {
  28. auto && result = static_cast<Target>(static_cast<Source &&>(x));
  29. #ifndef NDEBUG
  30. auto && dresult = dynamic_cast<Target>(static_cast<Source &&>(x));
  31. RANGES_ASSERT(std::addressof(dresult) == std::addressof(result));
  32. #endif
  33. return static_cast<Target>(result);
  34. }
  35. } // namespace ranges
  36. #endif // RANGES_V3_UTILITY_POLYMORPHIC_CAST_HPP