File indexing completed on 2025-01-18 09:50:40
0001
0002
0003
0004
0005 #ifndef CAST_DWA200269_HPP
0006 # define CAST_DWA200269_HPP
0007
0008 # include <boost/python/detail/prefix.hpp>
0009 # include <boost/python/detail/type_traits.hpp>
0010
0011 # include <boost/type.hpp>
0012 # include <boost/python/base_type_traits.hpp>
0013 # include <boost/python/detail/convertible.hpp>
0014
0015 namespace boost { namespace python {
0016
0017 namespace detail
0018 {
0019 template <class Source, class Target> inline Target* upcast_impl(Source*, Target*);
0020
0021 template <class Source, class Target>
0022 inline Target* upcast(Source* p, yes_convertible, no_convertible, Target*)
0023 {
0024 return p;
0025 }
0026
0027 template <class Source, class Target>
0028 inline Target* upcast(Source* p, no_convertible, no_convertible, Target*)
0029 {
0030 typedef typename base_type_traits<Source>::type base;
0031
0032 return detail::upcast_impl((base*)p, (Target*)0);
0033 }
0034
0035 template <bool is_same = true>
0036 struct upcaster
0037 {
0038 template <class T>
0039 static inline T* execute(T* x, T*) { return x; }
0040 };
0041
0042 template <>
0043 struct upcaster<false>
0044 {
0045 template <class Source, class Target>
0046 static inline Target* execute(Source* x, Target*)
0047 {
0048 return detail::upcast(
0049 x, detail::convertible<Target*>::check(x)
0050 , detail::convertible<Source*>::check((Target*)0)
0051 , (Target*)0);
0052 }
0053 };
0054
0055
0056 template <class Target, class Source>
0057 inline Target* downcast(Source* p, yes_convertible)
0058 {
0059 return static_cast<Target*>(p);
0060 }
0061
0062 template <class Target, class Source>
0063 inline Target* downcast(Source* p, no_convertible, boost::type<Target>* = 0)
0064 {
0065 typedef typename base_type_traits<Source>::type base;
0066 return (Target*)detail::downcast<base>(p, convertible<Source*>::check((base*)0));
0067 }
0068
0069 template <class T>
0070 inline void assert_castable(boost::type<T>* = 0)
0071 {
0072 typedef char must_be_a_complete_type[sizeof(T)] BOOST_ATTRIBUTE_UNUSED;
0073 }
0074
0075 template <class Source, class Target>
0076 inline Target* upcast_impl(Source* x, Target*)
0077 {
0078 typedef typename detail::add_cv<Source>::type src_t;
0079 typedef typename detail::add_cv<Target>::type target_t;
0080 bool const same = detail::is_same<src_t,target_t>::value;
0081
0082 return detail::upcaster<same>::execute(x, (Target*)0);
0083 }
0084 }
0085
0086 template <class Target, class Source>
0087 inline Target* upcast(Source* x, Target* = 0)
0088 {
0089 detail::assert_castable<Source>();
0090 detail::assert_castable<Target>();
0091 return detail::upcast_impl(x, (Target*)0);
0092
0093 }
0094
0095 template <class Target, class Source>
0096 inline Target* downcast(Source* x, Target* = 0)
0097 {
0098 detail::assert_castable<Source>();
0099 detail::assert_castable<Target>();
0100 return detail::downcast<Target>(x, detail::convertible<Source*>::check((Target*)0));
0101 }
0102
0103 }}
0104
0105 #endif