Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:34:16

0001 //  boost polymorphic_cast.hpp header file  ----------------------------------------------//
0002 
0003 //  (C) Copyright Kevlin Henney and Dave Abrahams 1999.
0004 //  (C) Copyright Boris Rasin 2014.
0005 //  Distributed under the Boost
0006 //  Software License, Version 1.0. (See accompanying file
0007 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 //  See http://www.boost.org/libs/conversion for Documentation.
0010 
0011 //  Revision History
0012 //  10 Nov 14  polymorphic_pointer_downcast moved to a separate header,
0013 //             minor improvements to stisfy latest Boost coding style
0014 //  08 Nov 14  Add polymorphic_pointer_downcast (Boris Rasin)
0015 //  09 Jun 14  "cast.hpp" was renamed to "polymorphic_cast.hpp" and
0016 //             inclusion of numeric_cast was removed (Antony Polukhin)
0017 //  23 Jun 05  numeric_cast removed and redirected to the new verion (Fernando Cacciola)
0018 //  02 Apr 01  Removed BOOST_NO_LIMITS workarounds and included
0019 //             <boost/limits.hpp> instead (the workaround did not
0020 //             actually compile when BOOST_NO_LIMITS was defined in
0021 //             any case, so we loose nothing). (John Maddock)
0022 //  21 Jan 01  Undid a bug I introduced yesterday. numeric_cast<> never
0023 //             worked with stock GCC; trying to get it to do that broke
0024 //             vc-stlport.
0025 //  20 Jan 01  Moved BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS to config.hpp.
0026 //             Removed unused BOOST_EXPLICIT_TARGET macro. Moved
0027 //             boost::detail::type to boost/type.hpp. Made it compile with
0028 //             stock gcc again (Dave Abrahams)
0029 //  29 Nov 00  Remove nested namespace cast, cleanup spacing before Formal
0030 //             Review (Beman Dawes)
0031 //  19 Oct 00  Fix numeric_cast for floating-point types (Dave Abrahams)
0032 //  15 Jul 00  Suppress numeric_cast warnings for GCC, Borland and MSVC
0033 //             (Dave Abrahams)
0034 //  30 Jun 00  More MSVC6 wordarounds.  See comments below.  (Dave Abrahams)
0035 //  28 Jun 00  Removed implicit_cast<>.  See comment below. (Beman Dawes)
0036 //  27 Jun 00  More MSVC6 workarounds
0037 //  15 Jun 00  Add workarounds for MSVC6
0038 //   2 Feb 00  Remove bad_numeric_cast ";" syntax error (Doncho Angelov)
0039 //  26 Jan 00  Add missing throw() to bad_numeric_cast::what(0 (Adam Levar)
0040 //  29 Dec 99  Change using declarations so usages in other namespaces work
0041 //             correctly (Dave Abrahams)
0042 //  23 Sep 99  Change polymorphic_downcast assert to also detect M.I. errors
0043 //             as suggested Darin Adler and improved by Valentin Bonnard.
0044 //   2 Sep 99  Remove controversial asserts, simplify, rename.
0045 //  30 Aug 99  Move to cast.hpp, replace value_cast with numeric_cast,
0046 //             place in nested namespace.
0047 //   3 Aug 99  Initial version
0048 
0049 #ifndef BOOST_POLYMORPHIC_CAST_HPP
0050 #define BOOST_POLYMORPHIC_CAST_HPP
0051 
0052 #include <boost/config.hpp>
0053 
0054 #ifdef BOOST_HAS_PRAGMA_ONCE
0055 #   pragma once
0056 #endif
0057 
0058 # include <boost/assert.hpp>
0059 # include <boost/throw_exception.hpp>
0060 
0061 # include <memory>  // std::addressof
0062 # include <typeinfo>
0063 # include <type_traits>
0064 
0065 namespace boost
0066 {
0067 //  See the documentation for descriptions of how to choose between
0068 //  static_cast<>, dynamic_cast<>, polymorphic_cast<> and polymorphic_downcast<>
0069 
0070 //  polymorphic_cast  --------------------------------------------------------//
0071 
0072     //  Runtime checked polymorphic downcasts and crosscasts.
0073     //  Suggested in The C++ Programming Language, 3rd Ed, Bjarne Stroustrup,
0074     //  section 15.8 exercise 1, page 425.
0075 
0076     template <class Target, class Source>
0077     inline Target polymorphic_cast(Source* x)
0078     {
0079         Target tmp = dynamic_cast<Target>(x);
0080         if ( tmp == 0 ) boost::throw_exception( std::bad_cast() );
0081         return tmp;
0082     }
0083 
0084 //  polymorphic_downcast  ----------------------------------------------------//
0085 
0086     //  BOOST_ASSERT() checked raw pointer polymorphic downcast.  Crosscasts prohibited.
0087 
0088     //  WARNING: Because this cast uses BOOST_ASSERT(), it violates
0089     //  the One Definition Rule if used in multiple translation units
0090     //  where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER
0091     //  NDEBUG are defined inconsistently.
0092 
0093     //  Contributed by Dave Abrahams
0094 
0095     template <class Target, class Source>
0096     inline Target polymorphic_downcast(Source* x)
0097     {
0098         BOOST_ASSERT( dynamic_cast<Target>(x) == x );  // detect logic error
0099         return static_cast<Target>(x);
0100     }
0101 
0102     //  BOOST_ASSERT() checked reference polymorphic downcast.  Crosscasts prohibited.
0103 
0104     //  WARNING: Because this cast uses BOOST_ASSERT(), it violates
0105     //  the One Definition Rule if used in multiple translation units
0106     //  where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER
0107     //  NDEBUG are defined inconsistently.
0108 
0109     //  Contributed by Julien Delacroix
0110 
0111     template <class Target, class Source>
0112     inline typename std::enable_if<
0113         std::is_reference<Target>::value, Target
0114     >::type polymorphic_downcast(Source& x)
0115     {
0116         typedef typename std::remove_reference<Target>::type* target_pointer_type;
0117         return *boost::polymorphic_downcast<target_pointer_type>(
0118             std::addressof(x)
0119         );
0120     }
0121 
0122 } // namespace boost
0123 
0124 #endif  // BOOST_POLYMORPHIC_CAST_HPP