diff --git a/cast.htm b/cast.htm deleted file mode 100644 index e1c466d..0000000 --- a/cast.htm +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - - Header boost/polymorphic_cast.hpp Documentation - - - - -

boost.png (6897 bytes)Header boost/polymorphic_cast.hpp

- -

Cast Functions

- -

The header boost/polymorphic_cast.hpp provides - polymorphic_cast and - polymorphic_downcast - function templates designed to complement the C++ built-in casts.

The header boost/polymorphic_pointer_cast.hpp provides - polymorphic_pointer_cast and - polymorphic_pointer_downcast function templates. - -

The program cast_test.cpp can be used to - verify these function templates work as expected.

- -

Polymorphic casts

- -

Pointers to polymorphic objects (objects of classes which define at - least one virtual function) are sometimes downcast or crosscast. - Downcasting means casting from a base class to a derived class. - Crosscasting means casting across an inheritance hierarchy diagram, such - as from one base to the other in a Y diagram hierarchy.

- -

Such casts can be done with old-style casts, but this approach is - never to be recommended. Old-style casts are sorely lacking in type - safety, suffer poor readability, and are difficult to locate with search - tools.

- -

The C++ built-in static_cast can be used for efficiently - downcasting pointers to polymorphic objects, but provides no error - detection for the case where the pointer being cast actually points to - the wrong derived class. The polymorphic_downcast template retains - the efficiency of static_cast for non-debug compilations, but for - debug compilations adds safety via an assert() that a dynamic_cast - succeeds.

- -

The C++ built-in dynamic_cast can be used for downcasts and - crosscasts of pointers to polymorphic objects, but error notification in - the form of a returned value of 0 is inconvenient to test, or worse yet, - easy to forget to test. The throwing form of dynamic_cast, which - works on references, can be used on pointers through the ugly expression - &dynamic_cast<T&>(*p), which causes undefined - behavior if p is 0. The polymorphic_cast - template performs a dynamic_cast on a pointer, and throws an - exception if the dynamic_cast returns 0.

- -

A polymorphic_downcast should be used for - downcasts that you are certain should succeed. Error checking is - only performed in translation units where NDEBUG is - not defined, via -

  assert( dynamic_cast<Derived>(x) == x )
-
where x is the source pointer. This approach - ensures that not only is a non-zero pointer returned, but also - that it is correct in the presence of multiple inheritance. - Attempts to crosscast using polymorphic_downcast will - fail to compile. - Warning: Because polymorphic_downcast uses assert(), it - violates the One Definition Rule (ODR) if NDEBUG is inconsistently - defined across translation units. [See ISO Std 3.2] -

- For crosscasts, or when the success of a cast can only be known at - runtime, or when efficiency is not important, - polymorphic_cast is preferred.

- -

The C++ built-in dynamic_cast must be used to cast references - rather than pointers. It is also the only cast that can be used to check - whether a given interface is supported; in that case a return of 0 isn't - an error condition.

- -

While polymorphic_downcast and polymorphic_cast work with built-in pointer types only, - polymorphic_pointer_downcast and polymorphic_pointer_cast are more generic versions - with support for any pointer type for which the following expressions would be valid:

- -

For polymorphic_pointer_downcast:

-   static_pointer_cast<Derived>(p);
  dynamic_pointer_cast<Derived>(p);


- -

For polymorphic_pointer_cast:

-   dynamic_pointer_cast<Derived>(p);
  !p; // conversion to bool with negation


-

This includes C++ built-in pointers, std::shared_ptr, boost::shared_ptr, boost::intrusive_ptr, etc.

- -

polymorphic_cast, polymorphic_downcast, polymorphic_pointer_cast and polymorphic_pointer_downcast synopsis

- -
-
namespace boost {
-
-template <class Derived, class Base>
-inline Derived polymorphic_cast(Base* x);
-// Throws: std::bad_cast if ( dynamic_cast<Derived>(x) == 0 )
-// Returns: dynamic_cast<Derived>(x)
-
-template <class Derived, class Base>
-inline Derived polymorphic_downcast(Base* x);
-// Effects: assert( dynamic_cast<Derived>(x) == x );
-// Returns: static_cast<Derived>(x)
-
-template <class Derived, class Base>
-inline auto polymorphic_pointer_cast(Base x);
-// Throws: std::bad_cast if ( dynamic_pointer_cast<Derived>(x) == 0 )
-// Returns: dynamic_pointer_cast<Derived>(x)
-
-template <class Derived, class Base>
-inline auto polymorphic_pointer_downcast(Base x);
-// Effects: assert( dynamic_pointer_cast<Derived>(x) == x );
-// Returns: static_pointer_cast<Derived>(x)
-
-}
-
-
- -

polymorphic_downcast example

- -
-
#include <boost/polymorphic_cast.hpp>
-...
-class Fruit { public: virtual ~Fruit(){}; ... };
-class Banana : public Fruit { ... };
-...
-void f( Fruit * fruit ) {
-// ... logic which leads us to believe it is a Banana
-  Banana * banana = boost::polymorphic_downcast<Banana*>(fruit);
-  ...
-
-
- -

polymorphic_pointer_downcast example

- -
-
#include <boost/polymorphic_pointer_cast.hpp>
-
-class Fruit { public: virtual ~Fruit(){} };
-class Banana : public Fruit {};
-
-// use one of these:
-
-typedef Fruit* FruitPtr;
-typedef std::shared_ptr<Fruit> FruitPtr;
-typedef boost::shared_ptr<Fruit> FruitPtr;
-typedef boost::intrusive_ptr<Fruit> FruitPtr;
-
-void f(FruitPtr fruit)
-{
-  // ... logic which leads us to believe it is a banana
-  auto banana = boost::polymorphic_pointer_downcast<Banana>(fruit);
-  ...
-}
-
-
- -

History

- -

polymorphic_cast was suggested by Bjarne Stroustrup in "The C++ - Programming Language".
- polymorphic_downcast was contributed by Dave Abrahams.
- polymorphic_pointer_downcast was contributed by Boris Rasin and - polymorphic_pointer_cast by Antony Polukhin.
- An old - numeric_cast that was contributed by Kevlin Henney is now superseeded by the Boost Numeric Conversion Library

-
- -

Revised - June 23, 2005

- - - - diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 new file mode 100644 index 0000000..7ca7b8f --- /dev/null +++ b/doc/Jamfile.v2 @@ -0,0 +1,42 @@ +# Copyright (c) 2016 Mikhail Maximov + +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +project doc/conversion ; + +using quickbook ; +import boostbook ; + +xml conversion_lib : conversion.qbk ; +boostbook standalone + : + conversion_lib + : + boost.root=../../../.. + # File name of HTML output: + root.filename=conversion + # How far down we chunk nested sections, basically all of them: + chunk.section.depth=0 + # Don't put the first section on the same page as the TOC: + chunk.first.sections=0 + # How far down sections get TOC's + toc.section.depth=2 + # Max depth in each TOC: + toc.max.depth=2 + # How far down we go with TOC's + generate.section.toc.level=0 + + generate.manifest=0 + ; + +############################################################################### +alias boostdoc + : conversion + : + : + : ; +explicit boostdoc ; +alias boostrelease ; +explicit boostrelease ; diff --git a/doc/conversion.qbk b/doc/conversion.qbk new file mode 100644 index 0000000..85ca7d7 --- /dev/null +++ b/doc/conversion.qbk @@ -0,0 +1,197 @@ +[/ + Copyright 2016 Mikhail Maximov. + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +] + +[article The Conversion Library + [quickbook 1.6] + [compatibility-mode 1.5] + [id conversion_lib] + [version 1.6] + [authors [Stroustrup, Bjarne], [Abrahams, Dave], [Rasin, Boris], [Polukhin, Antony]] + [copyright 2001 Beman Dawes] + [license + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + [@http://www.boost.org/LICENSE_1_0.txt]) + ] + [source-mode teletype] +] + +[/ QuickBook Document version 1.5 ] +[/ Dec, 2016 ] + +[section Description] + +The Conversion Library improves program safety and clarity by performing +otherwise messy conversions. It includes cast-style function templates designed +to complement the C++ Standard's built-in casts. + +To reduce coupling, particularly to standard library IOStreams, +the Boost Conversion Library is supplied by several headers: + +# The [@boost:boost/polymorphic_cast.hpp boost/polymorphic_cast.hpp] header + provides [link polymorphic_cast `polymorphic_cast<>`] and + [link polymorphic_downcast `polymorphic_downcast<>`] + to perform safe casting between polymorphic types. +# The [@boost:boost/polymorphic_pointer_cast.hpp boost/polymorphic_pointer_cast.hpp] header + provides [link polymorphic_pointer_cast `polymorphic_pointer_cast<>`] and + [link polymorphic_pointer_cast `polymorphic_pointer_downcast<>`] +# The [@boost:boost/implicit_cast.hpp boost/implicit_cast.hpp] header provides `implicit_cast<>` + to perform implicit casts only (no down-cast, no void*->T*, no U->T if T has only explicit constructors for U). +# The [@boost:boost/lexical_cast.hpp boost/lexical_cast.hpp] header + provides [@boost:libs/lexical_cast/doc/html/index.html `lexical_cast<>`] general literal text conversions, such as an `int` represented as a `string`, or vice-versa. + +[endsect] + +[section Polymorphic casts] +Pointers to polymorphic objects (objects of classes which define at +least one virtual function) are sometimes downcast or crosscast. +Downcasting means casting from a base class to a derived class. +Crosscasting means casting across an inheritance hierarchy diagram, such +as from one base to the other in a [^Y] diagram hierarchy. + +Such casts can be done with old-style casts, but this approach is +never to be recommended. Old-style casts are sorely lacking in type +safety, suffer poor readability, and are difficult to locate with search +tools. + +[#polymorphic_downcast] + +The C++ built-in `static_cast` can be used for efficiently +downcasting pointers to polymorphic objects, but provides no error +detection for the case where the pointer being cast actually points to +the wrong derived class. The `polymorphic_downcast` template retains +the efficiency of `static_cast` for non-debug compilations, but for +debug compilations adds safety via an `assert()` that a `dynamic_cast` +succeeds. + +A `polymorphic_downcast` should be used for +downcasts that you are certain should succeed. Error checking is +only performed in translation units where `NDEBUG` is +not defined, via +``` + assert( dynamic_cast(x) == x ) +``` +where `x` is the source pointer. This approach +ensures that not only is a non-zero pointer returned, but also +that it is correct in the presence of multiple inheritance. +Attempts to crosscast using `polymorphic_downcast` will +fail to compile. + +[warning Because `polymorphic_downcast` uses `assert()`, it +violates the One Definition Rule (ODR) if NDEBUG is inconsistently +defined across translation units. See ISO Std 3.2] + +[#polymorphic_cast] + +The C++ built-in `dynamic_cast` can be used for downcasts and +crosscasts of pointers to polymorphic objects, but error notification in +the form of a returned value of 0 is inconvenient to test, or worse yet, +easy to forget to test. The throwing form of `dynamic_cast`, which +works on references, can be used on pointers through the ugly expression +`&dynamic_cast(*p), which causes undefined +behavior if `p` is `0`. The `polymorphic_cast` +template performs a `dynamic_cast` on a pointer, and throws an +exception if the `dynamic_cast` returns 0. + +For crosscasts, or when the success of a cast can only be known at runtime, +or when efficiency is not important, `polymorphic_cast` is preferred. + +The C++ built-in dynamic_cast must be used to cast references rather than pointers. +It is also the only cast that can be used to check whether a given interface is supported; in that case a return of 0 isn't an error condition. + +[#polymorphic_pointer_cast] +While polymorphic_downcast and polymorphic_cast work with built-in pointer types only, +polymorphic_pointer_downcast and polymorphic_pointer_cast are more generic versions +with support for any pointer type for which the following expressions would be valid: + +For `polymorphic_pointer_downcast`: +``` + static_pointer_cast(p); + dynamic_pointer_cast(p); +``` +For `polymorphic_pointer_cast`: +``` + dynamic_pointer_cast(p); + !p; // conversion to bool with negation +``` + +This includes C++ built-in pointers, `std::shared_ptr`, +`boost::shared_ptr`, `boost::intrusive_ptr`, etc. + +[endsect] +[section `polymorphic_cast`, `polymorphic_downcast`, `polymorphic_pointer_cast` and `polymorphic_pointer_downcast` synopsis] +``` + namespace boost { + + template + inline Derived polymorphic_cast(Base* x); + // Throws: std::bad_cast if ( dynamic_cast(x) == 0 ) + // Returns: dynamic_cast(x) + + template + inline Derived polymorphic_downcast(Base* x); + // Effects: assert( dynamic_cast(x) == x ); + // Returns: static_cast(x) + + template + inline auto polymorphic_pointer_cast(Base x); + // Throws: std::bad_cast if ( dynamic_pointer_cast(x) == 0 ) + // Returns: dynamic_pointer_cast(x) + + template + inline auto polymorphic_pointer_downcast(Base x); + // Effects: assert( dynamic_pointer_cast(x) == x ); + // Returns: static_pointer_cast(x) + + } +``` +[endsect] +[section `polymorphic_downcast` example] +``` + #include + ... + class Fruit { public: virtual ~Fruit(){}; ... }; + class Banana : public Fruit { ... }; + ... + void f( Fruit * fruit ) { + // ... logic which leads us to believe it is a Banana + Banana * banana = boost::polymorphic_downcast(fruit); + ... + } +``` +[endsect] +[section `polymorphic_pointer_downcast` example] +``` + #include + + class Fruit { public: virtual ~Fruit(){} }; + class Banana : public Fruit {}; + + // use one of these: + + typedef Fruit* FruitPtr; + typedef std::shared_ptr FruitPtr; + typedef boost::shared_ptr FruitPtr; + typedef boost::intrusive_ptr FruitPtr; + + void f(FruitPtr fruit) { + // ... logic which leads us to believe it is a banana + auto banana = boost::polymorphic_pointer_downcast(fruit); + ... + } +``` +[endsect] +[section History] +`polymorphic_cast` was suggested by Bjarne Stroustrup in "The C++ Programming Language". + +`polymorphic_downcast` was contributed by [@http://www.boost.org/people/dave_abrahams.htm Dave Abrahams]. + +`polymorphic_pointer_downcast` was contributed by [@http://www.boost.org/people/boris_rasin.htm Boris Rasin] +and `polymorphic_pointer_cast` by Antony Polukhin. + +An old numeric_cast that was contributed by [@http://www.boost.org/people/kevlin_henney.htm Kevlin Henney] +is now superseeded by the [@boost:numeric_conversion/doc/html/html/boost_numericconversion/improved_numeric_cast__.html Boost Numeric Conversion Library] +[endsect] diff --git a/index.html b/index.html index afc39d3..0f61fb0 100644 --- a/index.html +++ b/index.html @@ -1,53 +1,35 @@ + + - - - - - -Boost Conversion Library + + +Boost.Conversion - - - -

Boost -Conversion Library

- -

The Conversion Library improves program safety and clarity by performing -otherwise messy conversions.  It includes cast-style function templates designed to complement the C++ -Standard's built-in casts.

-

To reduce coupling, particularly to standard library IOStreams, the Boost -Conversion Library is -supplied by several headers:

-
    -
  • The boost/polymorphic_cast.hpp and boost/polymorphic_pointer_cast.hpp - headers provide polymorphic_cast<>, - polymorphic_downcast<> and polymorphic_pointer_downcast<> to perform safe casting between - polymorphic types.
    -
  • -
  • The boost/implicit_cast.hpp header provides implicit_cast<> - to perform implicit casts only (no down-cast, no void*->T*, no U->T if T has only explicit constructors for U).
    -
  • -
  • The boost/lexical_cast header provides lexical_cast<> - general literal text conversions, such as an int represented as - a string, or vice-versa.
  • -
-
-

Revised June 23, 2005 -

- + +

+ Automatic redirection failed, please go to + ../../doc/html/conversion.html +

+

+ © 2014 Antony Polukhin +

- - + \ No newline at end of file