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