[857] | 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 |
|
---|
| 8 | # include <boost/python/detail/prefix.hpp>
|
---|
| 9 |
|
---|
| 10 | # include <boost/type_traits/same_traits.hpp>
|
---|
| 11 | # include <boost/type_traits/cv_traits.hpp>
|
---|
| 12 | # include <boost/type.hpp>
|
---|
| 13 | # include <boost/python/base_type_traits.hpp>
|
---|
| 14 | # include <boost/python/detail/convertible.hpp>
|
---|
| 15 |
|
---|
| 16 | namespace boost { namespace python {
|
---|
| 17 |
|
---|
| 18 | namespace detail
|
---|
| 19 | {
|
---|
| 20 | template <class Source, class Target> inline Target* upcast_impl(Source*, Target*);
|
---|
| 21 |
|
---|
| 22 | template <class Source, class Target>
|
---|
| 23 | inline Target* upcast(Source* p, yes_convertible, no_convertible, Target*)
|
---|
| 24 | {
|
---|
| 25 | return p;
|
---|
| 26 | }
|
---|
| 27 |
|
---|
| 28 | template <class Source, class Target>
|
---|
| 29 | inline Target* upcast(Source* p, no_convertible, no_convertible, Target*)
|
---|
| 30 | {
|
---|
| 31 | typedef typename base_type_traits<Source>::type base;
|
---|
| 32 |
|
---|
| 33 | return detail::upcast_impl((base*)p, (Target*)0);
|
---|
| 34 | }
|
---|
| 35 |
|
---|
| 36 | template <bool is_same = true>
|
---|
| 37 | struct upcaster
|
---|
| 38 | {
|
---|
| 39 | template <class T>
|
---|
| 40 | static inline T* execute(T* x, T*) { return x; }
|
---|
| 41 | };
|
---|
| 42 |
|
---|
| 43 | template <>
|
---|
| 44 | struct upcaster<false>
|
---|
| 45 | {
|
---|
| 46 | template <class Source, class Target>
|
---|
| 47 | static inline Target* execute(Source* x, Target*)
|
---|
| 48 | {
|
---|
| 49 | return detail::upcast(
|
---|
| 50 | x, detail::convertible<Target*>::check(x)
|
---|
| 51 | , detail::convertible<Source*>::check((Target*)0)
|
---|
| 52 | , (Target*)0);
|
---|
| 53 | }
|
---|
| 54 | };
|
---|
| 55 |
|
---|
| 56 |
|
---|
| 57 | template <class Target, class Source>
|
---|
| 58 | inline Target* downcast(Source* p, yes_convertible)
|
---|
| 59 | {
|
---|
| 60 | return static_cast<Target*>(p);
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | template <class Target, class Source>
|
---|
| 64 | inline Target* downcast(Source* p, no_convertible, boost::type<Target>* = 0)
|
---|
| 65 | {
|
---|
| 66 | typedef typename base_type_traits<Source>::type base;
|
---|
| 67 | return (Target*)detail::downcast<base>(p, convertible<Source*>::check((base*)0));
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | template <class T>
|
---|
| 71 | inline void assert_castable(boost::type<T>* = 0)
|
---|
| 72 | {
|
---|
| 73 | typedef char must_be_a_complete_type[sizeof(T)];
|
---|
| 74 | }
|
---|
| 75 |
|
---|
| 76 | template <class Source, class Target>
|
---|
| 77 | inline Target* upcast_impl(Source* x, Target*)
|
---|
| 78 | {
|
---|
| 79 | typedef typename add_cv<Source>::type src_t;
|
---|
| 80 | typedef typename add_cv<Target>::type target_t;
|
---|
| 81 | bool const same = is_same<src_t,target_t>::value;
|
---|
| 82 |
|
---|
| 83 | return detail::upcaster<same>::execute(x, (Target*)0);
|
---|
| 84 | }
|
---|
| 85 | }
|
---|
| 86 |
|
---|
| 87 | template <class Target, class Source>
|
---|
| 88 | inline Target* upcast(Source* x, Target* = 0)
|
---|
| 89 | {
|
---|
| 90 | detail::assert_castable<Source>();
|
---|
| 91 | detail::assert_castable<Target>();
|
---|
| 92 | return detail::upcast_impl(x, (Target*)0);
|
---|
| 93 |
|
---|
| 94 | }
|
---|
| 95 |
|
---|
| 96 | template <class Target, class Source>
|
---|
| 97 | inline Target* downcast(Source* x, Target* = 0)
|
---|
| 98 | {
|
---|
| 99 | detail::assert_castable<Source>();
|
---|
| 100 | detail::assert_castable<Target>();
|
---|
| 101 | return detail::downcast<Target>(x, detail::convertible<Source*>::check((Target*)0));
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | }} // namespace boost::python
|
---|
| 105 |
|
---|
| 106 | #endif // CAST_DWA200269_HPP
|
---|