|
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 |