cast.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright David Abrahams 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef CAST_DWA200269_HPP
  6. # define CAST_DWA200269_HPP
  7. # include <boost/python/detail/prefix.hpp>
  8. # include <boost/python/detail/type_traits.hpp>
  9. # include <boost/type.hpp>
  10. # include <boost/python/base_type_traits.hpp>
  11. # include <boost/python/detail/convertible.hpp>
  12. namespace boost { namespace python {
  13. namespace detail
  14. {
  15. template <class Source, class Target> inline Target* upcast_impl(Source*, Target*);
  16. template <class Source, class Target>
  17. inline Target* upcast(Source* p, yes_convertible, no_convertible, Target*)
  18. {
  19. return p;
  20. }
  21. template <class Source, class Target>
  22. inline Target* upcast(Source* p, no_convertible, no_convertible, Target*)
  23. {
  24. typedef typename base_type_traits<Source>::type base;
  25. return detail::upcast_impl((base*)p, (Target*)0);
  26. }
  27. template <bool is_same = true>
  28. struct upcaster
  29. {
  30. template <class T>
  31. static inline T* execute(T* x, T*) { return x; }
  32. };
  33. template <>
  34. struct upcaster<false>
  35. {
  36. template <class Source, class Target>
  37. static inline Target* execute(Source* x, Target*)
  38. {
  39. return detail::upcast(
  40. x, detail::convertible<Target*>::check(x)
  41. , detail::convertible<Source*>::check((Target*)0)
  42. , (Target*)0);
  43. }
  44. };
  45. template <class Target, class Source>
  46. inline Target* downcast(Source* p, yes_convertible)
  47. {
  48. return static_cast<Target*>(p);
  49. }
  50. template <class Target, class Source>
  51. inline Target* downcast(Source* p, no_convertible, boost::type<Target>* = 0)
  52. {
  53. typedef typename base_type_traits<Source>::type base;
  54. return (Target*)detail::downcast<base>(p, convertible<Source*>::check((base*)0));
  55. }
  56. template <class T>
  57. inline void assert_castable(boost::type<T>* = 0)
  58. {
  59. typedef char must_be_a_complete_type[sizeof(T)] BOOST_ATTRIBUTE_UNUSED;
  60. }
  61. template <class Source, class Target>
  62. inline Target* upcast_impl(Source* x, Target*)
  63. {
  64. typedef typename detail::add_cv<Source>::type src_t;
  65. typedef typename detail::add_cv<Target>::type target_t;
  66. bool const same = detail::is_same<src_t,target_t>::value;
  67. return detail::upcaster<same>::execute(x, (Target*)0);
  68. }
  69. }
  70. template <class Target, class Source>
  71. inline Target* upcast(Source* x, Target* = 0)
  72. {
  73. detail::assert_castable<Source>();
  74. detail::assert_castable<Target>();
  75. return detail::upcast_impl(x, (Target*)0);
  76. }
  77. template <class Target, class Source>
  78. inline Target* downcast(Source* x, Target* = 0)
  79. {
  80. detail::assert_castable<Source>();
  81. detail::assert_castable<Target>();
  82. return detail::downcast<Target>(x, detail::convertible<Source*>::check((Target*)0));
  83. }
  84. }} // namespace boost::python
  85. #endif // CAST_DWA200269_HPP