]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/conversion/cast.htm
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / conversion / cast.htm
CommitLineData
7c673cae
FG
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
3<html>
4 <head>
5 <meta name="generator" content=
6 "Microsoft FrontPage 5.0">
7 <meta http-equiv="Content-Type" content=
8 "text/html; charset=windows-1252">
9 <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
10 <meta name="ProgId" content="FrontPage.Editor.Document">
11
12 <title>Header boost/polymorphic_cast.hpp Documentation</title>
13 <style>
14 .copyright
15 {
16 color: #666666;
17 font-size: small;
18 }
19 </style>
20 </head>
21
22 <body bgcolor="#FFFFFF" text="#000000">
23 <h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align=
24 "middle" width="277" height="86">Header <a href=
25 "../../boost/polymorphic_cast.hpp">boost/polymorphic_cast.hpp</a></h1>
26
27 <h2><a name="Cast Functions">Cast Functions</a></h2>
28
29 <p>The header <a href="../../boost/polymorphic_cast.hpp">boost/polymorphic_cast.hpp</a> provides
30 <code><a href="#Polymorphic_cast">polymorphic_cast</a></code> and
31 <code><a href="#Polymorphic_cast">polymorphic_downcast</a></code>
32 function templates designed to complement the C++ built-in casts.</p> <p>The header <a href="../../boost/polymorphic_pointer_cast.hpp">boost/polymorphic_pointer_cast.hpp</a> provides
33 <code><a href="#Polymorphic_cast">polymorphic_pointer_cast</a></code> and
34 <code><a href="#Polymorphic_cast">polymorphic_pointer_downcast</a></code> function templates.
35
36 <p>The program <a href="test/cast_test.cpp">cast_test.cpp</a> can be used to
37 verify these function templates work as expected.</p>
38
39 <h3><a name="Polymorphic_cast">Polymorphic casts</a></h3>
40
41 <p>Pointers to polymorphic objects (objects of classes which define at
42 least one virtual function) are sometimes downcast or crosscast.
43 Downcasting means casting from a base class to a derived class.
44 Crosscasting means casting across an inheritance hierarchy diagram, such
45 as from one base to the other in a <code>Y</code> diagram hierarchy.</p>
46
47 <p>Such casts can be done with old-style casts, but this approach is
48 never to be recommended. Old-style casts are sorely lacking in type
49 safety, suffer poor readability, and are difficult to locate with search
50 tools.</p>
51
52 <p>The C++ built-in <code>static_cast</code> can be used for efficiently
53 downcasting pointers to polymorphic objects, but provides no error
54 detection for the case where the pointer being cast actually points to
55 the wrong derived class. The <code>polymorphic_downcast</code> template retains
56 the efficiency of <code>static_cast</code> for non-debug compilations, but for
57 debug compilations adds safety via an assert() that a <code>dynamic_cast</code>
58 succeeds.</p>
59
60 <p>The C++ built-in <code>dynamic_cast</code> can be used for downcasts and
61 crosscasts of pointers to polymorphic objects, but error notification in
62 the form of a returned value of 0 is inconvenient to test, or worse yet,
63 easy to forget to test. The throwing form of <code>dynamic_cast</code>, which
64 works on references, can be used on pointers through the ugly expression
65 &amp;<code>dynamic_cast&lt;T&amp;&gt;(*p)</code>, which causes undefined
66 behavior if <code>p</code> is <code>0</code>. The <code>polymorphic_cast</code>
67 template performs a <code>dynamic_cast</code> on a pointer, and throws an
68 exception if the <code>dynamic_cast</code> returns 0.</p>
69
70 <p>A <code>polymorphic_downcast</code> should be used for
71 downcasts that you are certain should succeed. Error checking is
72 only performed in translation units where <code>NDEBUG</code> is
73 not defined, via
74<pre> assert( dynamic_cast&lt;Derived&gt;(x) == x )
75</pre> where <code>x</code> is the source pointer. This approach
76 ensures that not only is a non-zero pointer returned, but also
77 that it is correct in the presence of multiple inheritance.
78 Attempts to crosscast using <code>polymorphic_downcast</code> will
79 fail to compile.
80 <b>Warning:</b> Because <code>polymorphic_downcast</code> uses assert(), it
81 violates the One Definition Rule (ODR) if NDEBUG is inconsistently
82 defined across translation units. [See ISO Std 3.2]
83 <p>
84 For crosscasts, or when the success of a cast can only be known at
85 runtime, or when efficiency is not important,
86 <code>polymorphic_cast</code> is preferred. </p>
87
88 <p>The C++ built-in <code>dynamic_cast</code> must be used to cast references
89 rather than pointers. It is also the only cast that can be used to check
90 whether a given interface is supported; in that case a return of 0 isn't
91 an error condition.</p>
92
93 <p>While <code>polymorphic_downcast</code> and <code>polymorphic_cast</code> work with built-in pointer types only,
94 <code>polymorphic_pointer_downcast</code> and <code>polymorphic_pointer_cast</code> are more generic versions
95 with support for any pointer type for which the following expressions would be valid:<br><br>
96
97 <p> For <code>polymorphic_pointer_downcast</code>:</p>
98 <code>&nbsp;&nbsp;static_pointer_cast&lt;Derived&gt;(p);<br>&nbsp;&nbsp;dynamic_pointer_cast&lt;Derived&gt;(p);</code><br><br>
99
100 <p> For <code>polymorphic_pointer_cast</code>:</p>
101 <code>&nbsp;&nbsp;dynamic_pointer_cast&lt;Derived&gt;(p);<br>&nbsp;&nbsp;!p; // conversion to bool with negation</code><br><br>
102 <p>This includes C++ built-in pointers, <code>std::shared_ptr, boost::shared_ptr, boost::intrusive_ptr</code>, etc.</p>
103
104 <h3>polymorphic_cast, polymorphic_downcast, polymorphic_pointer_cast and polymorphic_pointer_downcast synopsis</h3>
105
106 <blockquote>
107<pre>namespace boost {
108
109template &lt;class Derived, class Base&gt;
110inline Derived polymorphic_cast(Base* x);
111// Throws: std::bad_cast if ( dynamic_cast&lt;Derived&gt;(x) == 0 )
112// Returns: dynamic_cast&lt;Derived&gt;(x)
113
114template &lt;class Derived, class Base&gt;
115inline Derived polymorphic_downcast(Base* x);
116// Effects: assert( dynamic_cast&lt;Derived&gt;(x) == x );
117// Returns: static_cast&lt;Derived&gt;(x)
118
119template &lt;class Derived, class Base&gt;
120inline auto polymorphic_pointer_cast(Base x);
121// Throws: std::bad_cast if ( dynamic_pointer_cast&lt;Derived&gt;(x) == 0 )
122// Returns: dynamic_pointer_cast&lt;Derived&gt;(x)
123
124template &lt;class Derived, class Base&gt;
125inline auto polymorphic_pointer_downcast(Base x);
126// Effects: assert( dynamic_pointer_cast&lt;Derived&gt;(x) == x );
127// Returns: static_pointer_cast&lt;Derived&gt;(x)
128
129}
130</pre>
131 </blockquote>
132
133 <h3>polymorphic_downcast example</h3>
134
135 <blockquote>
136<pre>#include &lt;boost/polymorphic_cast.hpp&gt;
137...
138class Fruit { public: virtual ~Fruit(){}; ... };
139class Banana : public Fruit { ... };
140...
141void f( Fruit * fruit ) {
142// ... logic which leads us to believe it is a Banana
143 Banana * banana = boost::polymorphic_downcast&lt;Banana*&gt;(fruit);
144 ...
145</pre>
146 </blockquote>
147
148 <h3>polymorphic_pointer_downcast example</h3>
149
150 <blockquote>
151<pre>#include &lt;boost/polymorphic_pointer_cast.hpp&gt;
152
153class Fruit { public: virtual ~Fruit(){} };
154class Banana : public Fruit {};
155
156// use one of these:
157
158typedef Fruit* FruitPtr;
159typedef std::shared_ptr&lt;Fruit&gt; FruitPtr;
160typedef boost::shared_ptr&lt;Fruit&gt; FruitPtr;
161typedef boost::intrusive_ptr&lt;Fruit&gt; FruitPtr;
162
163void f(FruitPtr fruit)
164{
165 // ... logic which leads us to believe it is a banana
166 auto banana = boost::polymorphic_pointer_downcast&lt;Banana&gt;(fruit);
167 ...
168}
169</pre>
170 </blockquote>
171
172 <h3>History</h3>
173
174 <p><code>polymorphic_cast</code> was suggested by Bjarne Stroustrup in "The C++
175 Programming Language".<br>
176 <code>polymorphic_downcast</code> was contributed by <a href=
177 "http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.<br>
178 <code>polymorphic_pointer_downcast</code> was contributed by <a href=
179 "http://www.boost.org/people/boris_rasin.htm">Boris Rasin</a> and
180 <code>polymorphic_pointer_cast</code> by Antony Polukhin.<br>
181 An old
182 <code>numeric_cast</code> that was contributed by <a href=
183 "http://www.boost.org/people/kevlin_henney.htm">Kevlin Henney</a> is now superseeded by the <a href="../numeric/conversion/doc/html/index.html">Boost Numeric Conversion Library</a></p>
184 <hr>
185
186 <p>Revised
187 <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
188 -->June 23, 2005<!--webbot bot="Timestamp" endspan i-checksum="30348"
189 --></p>
190
191 <p class="copyright">&copy; Copyright boost.org 1999.
192 Distributed under the Boost Software License, Version 1.0. (See accompanying
193 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
194 </p>
195 </body>
196</html>