1 //
2 //  pointer_cast_test.cpp - a test for boost/pointer_cast.hpp
3 //
4 //  Copyright (c) 2005 Ion Gaztanaga
5 //  Copyright (c) 2005 Peter Dimov
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 
12 #include <boost/config.hpp>
13 
14 #include <boost/pointer_cast.hpp>
15 
16 #include <boost/shared_ptr.hpp>
17 #include <boost/scoped_ptr.hpp>
18 #include <boost/get_pointer.hpp>
19 
20 #include <boost/detail/lightweight_test.hpp>
21 
22 namespace
23 {
24 
25 // Let's create these inheritance relationship:
26 //
27 //    base   base2
28 //      |     |
29 //      derived
30 //         |
31 //  derived_derived
32 //
33 
34 class base
35 {
36    public:
~base()37    virtual ~base(){}
38    int filler [5];
39 };
40 
41 class base2
42 {
43 public:
44 
~base2()45     virtual ~base2(){}
46     int filler [5];
47 };
48 
49 class derived
50    : public base, public base2
51 {
52     int filler [5];
53 };
54 
55 class derived_derived
56    : public derived
57 {
58     int filler [5];
59 };
60 
61 // And now some simple check functions
62 
63 #if !defined( BOOST_NO_RTTI )
64 
65 template <class BasePtr>
check_dynamic_pointer_cast(const BasePtr & ptr)66 bool check_dynamic_pointer_cast(const BasePtr &ptr)
67 {
68    //Check that dynamic_pointer_cast versus dynamic_cast
69    return
70    //Correct cast with dynamic_pointer_cast
71    boost::get_pointer(boost::dynamic_pointer_cast<derived>(ptr)) ==
72       //Correct cast with dynamic_cast
73       dynamic_cast<derived*>(boost::get_pointer(ptr))
74    &&
75    //Incorrect cast with dynamic_pointer_cast
76    boost::get_pointer(boost::dynamic_pointer_cast<derived_derived>(ptr)) ==
77       //Incorrect cast with dynamic_cast
78       dynamic_cast<derived_derived*>(boost::get_pointer(ptr));
79 }
80 
81 #endif
82 
83 template <class BasePtr>
check_static_pointer_cast(const BasePtr & ptr)84 bool check_static_pointer_cast(const BasePtr &ptr)
85 {
86    return
87    //Cast base -> derived -> base2 using static_pointer_cast
88    boost::get_pointer(
89             boost::static_pointer_cast<base2>(
90                boost::static_pointer_cast<derived>(ptr))) ==
91    //Now the same with static_cast
92    static_cast<base2*>(static_cast<derived*>(boost::get_pointer(ptr)));
93 }
94 
95 template <class BasePtr>
check_const_pointer_cast(const BasePtr & ptr)96 bool check_const_pointer_cast(const BasePtr &ptr)
97 {
98    return
99    //Unconst and const again using const_pointer_cast
100    boost::get_pointer(
101       boost::const_pointer_cast<const base>
102          (boost::const_pointer_cast<base>(ptr))) ==
103    //Now the same with const_cast
104    const_cast<const base*>(const_cast<base*>(boost::get_pointer(ptr)));
105 }
106 
107 }
108 
main()109 int main()
110 {
111     {
112         // Try casts with shared_ptr
113 
114         boost::shared_ptr<base> ptr(new derived);
115 
116 #if !defined( BOOST_NO_RTTI )
117         BOOST_TEST( check_dynamic_pointer_cast( ptr ) );
118 #endif
119         BOOST_TEST( check_static_pointer_cast( ptr ) );
120         BOOST_TEST( check_const_pointer_cast( ptr ) );
121     }
122 
123     {
124         // Try casts with raw pointer
125 
126         boost::scoped_ptr<base> ptr(new derived);
127 
128 #if !defined( BOOST_NO_RTTI )
129         BOOST_TEST( check_dynamic_pointer_cast( ptr.get() ) );
130 #endif
131         BOOST_TEST( check_static_pointer_cast( ptr.get() ) );
132         BOOST_TEST( check_const_pointer_cast( ptr.get() ) );
133     }
134 
135     return boost::report_errors();
136 }
137