mirror of
https://github.com/boostorg/conversion.git
synced 2026-08-04 04:24:11 +02:00
Compare commits
114 Commits
boost-1.56.0
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 827dd94c68 | |||
| 782e083f61 | |||
| 1e6424563d | |||
| 6632ca9309 | |||
| b74a4c34cb | |||
| 452adac97f | |||
| 5f82d5aa7d | |||
| 9d64c899df | |||
| 35a71f0701 | |||
| 8a860e05d0 | |||
| 9f285ef0c4 | |||
| 5f36c2c710 | |||
| 41e62ed851 | |||
| 5cf5f78376 | |||
| 5a3587c988 | |||
| f7f3c9b5ce | |||
| 668030fcd6 | |||
| 0d60a3f7ce | |||
| 0ff5adc258 | |||
| 2598281d10 | |||
| a1104f580c | |||
| 9a03296816 | |||
| 7ba0984b34 | |||
| 4ae8b4d495 | |||
| 71b6a864a4 | |||
| b2a49138cf | |||
| 00f06d3549 | |||
| 968dfd47f1 | |||
| f0fe02f7d6 | |||
| 19b5a1cf29 | |||
| 1a2e4fd8ef | |||
| 8d1721f312 | |||
| c6ab56e983 | |||
| 1c62347706 | |||
| 56becb8fee | |||
| 67ae26b0f0 | |||
| d4e593120d | |||
| 76ed70b0b1 | |||
| 4b7d551907 | |||
| 9e3216d22f | |||
| 4e557d31d1 | |||
| 46695ffb86 | |||
| c1c098fac1 | |||
| b171fe1ff6 | |||
| a178d1a691 | |||
| 5176e189b8 | |||
| 49e6421271 | |||
| a0bfc39077 | |||
| 2bf2bba4be | |||
| f882ab890d | |||
| e0bb75e096 | |||
| 80b9240f2e | |||
| df86cb59c4 | |||
| 4fec53f3db | |||
| db398fc1c8 | |||
| 1576ff7be6 | |||
| 9540be42b4 | |||
| 7624b70a6d | |||
| 78fc22c66a | |||
| f1d5059c75 | |||
| f2e83915c3 | |||
| e0a40b7067 | |||
| 1dd1c98b79 | |||
| a1788bc31b | |||
| 58c33270a2 | |||
| e130cd860c | |||
| 9d4a518e74 | |||
| 1525157560 | |||
| 3421136ef0 | |||
| 441d4e4e1b | |||
| b3f8e9f014 | |||
| 24f2769eb7 | |||
| 6806d99529 | |||
| e38c0753ef | |||
| 6b3395e57d | |||
| 83e57ed513 | |||
| 56393150bb | |||
| e8d104f34d | |||
| a770ff87d7 | |||
| 29997a9fe1 | |||
| 2a0a2a59f5 | |||
| 51d544e6b8 | |||
| ee92f4f98b | |||
| d46e12c921 | |||
| 2648b144be | |||
| 32130aa427 | |||
| c704762482 | |||
| ae1f2a5cd1 | |||
| 993685b7d0 | |||
| eafe2d352e | |||
| 3b9769567e | |||
| 610f9fe674 | |||
| cbe18465d7 | |||
| 181eb0e6fc | |||
| 46694fb293 | |||
| 4d814efd3f | |||
| da8b2fe695 | |||
| a7b9f42b9a | |||
| b6e9403ef0 | |||
| 58e8e78899 | |||
| 8f4b6ec985 | |||
| a6100358f4 | |||
| 8f1126f6b2 | |||
| b2019fa2df | |||
| dc25edb4dd | |||
| 43ee183296 | |||
| 84ab59227d | |||
| 0dc31621c8 | |||
| 00b6a53f7e | |||
| 6199649ae2 | |||
| a8253878c8 | |||
| 582fc91adb | |||
| 6a224fa5e9 | |||
| 5d66fea7d5 |
@@ -0,0 +1,11 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -0,0 +1,182 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/**
|
||||
|
||||
env:
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
|
||||
jobs:
|
||||
posix:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-14 # Do not remove! It is the only toolset that tests CMake tests down below
|
||||
cxxstd: "03,11,14,17,20"
|
||||
os: ubuntu-24.04
|
||||
- toolset: gcc-12
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-22.04
|
||||
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
|
||||
linkflags: "linkflags=--coverage -lasan -lubsan"
|
||||
gcov_tool: "gcov-12"
|
||||
- toolset: clang
|
||||
compiler: clang++-14
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-22.04
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 10 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init --depth 10 --jobs 2 tools/boostdep tools/inspect libs/filesystem
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 3" filesystem
|
||||
rm -rf libs/$LIBRARY/*
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--depth 10 --jobs 3" $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -j4 variant=debug tools/inspect
|
||||
|
||||
- name: Run CMake tests
|
||||
if: ${{matrix.toolset == 'gcc-14'}}
|
||||
run: |
|
||||
cd ../boost-root/
|
||||
mkdir __build
|
||||
cd __build
|
||||
cmake -DBUILD_TESTING=1 -DBOOST_INCLUDE_LIBRARIES=conversion -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_C_COMPILER=gcc-14 ..
|
||||
cmake --build . --target tests
|
||||
ctest --output-on-failure --no-tests=error
|
||||
cd ..
|
||||
rm -rf __build
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost-root
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release "${{matrix.cxxflags}}" "${{matrix.linkflags}}" "${{matrix.launcher}}"
|
||||
dist/bin/inspect libs/$LIBRARY
|
||||
|
||||
- name: Prepare coverage data
|
||||
if: matrix.gcov_tool
|
||||
run: |
|
||||
mkdir -p $GITHUB_WORKSPACE/coveralls
|
||||
|
||||
echo -e "#!/bin/bash\nexec ${{matrix.gcov_tool}} \"\$@\"" > $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
|
||||
chmod +x $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
|
||||
wget https://github.com/linux-test-project/lcov/archive/v1.16.zip
|
||||
unzip v1.16.zip
|
||||
LCOV="`pwd`/lcov-1.16/bin/lcov --gcov-tool $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh"
|
||||
|
||||
echo "$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory `pwd`/libs/$LIBRARY/test --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info"
|
||||
$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory ../boost-root/ --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info
|
||||
$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info "/usr*" "*/$LIBRARY/test/*" ${{matrix.ignore_coverage}} "*/$LIBRARY/tests/*" "*/$LIBRARY/examples/*" "*/$LIBRARY/example/*" -o $GITHUB_WORKSPACE/coveralls/coverage.info
|
||||
|
||||
cd ../boost-root
|
||||
OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$LIBRARY\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
|
||||
echo $OTHER_LIBS
|
||||
eval "$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info $OTHER_LIBS -o $GITHUB_WORKSPACE/coveralls/coverage.info"
|
||||
|
||||
- name: Coveralls
|
||||
uses: coverallsapp/github-action@master
|
||||
if: matrix.gcov_tool
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path-to-lcov: ./coveralls/coverage.info
|
||||
parallel: true
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: msvc-14.3
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2025
|
||||
- toolset: gcc
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
addrmd: 64
|
||||
os: windows-2025
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
||||
echo LIBRARY: %LIBRARY%
|
||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--jobs 3" %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
|
||||
- name: Run CMake tests
|
||||
if: ${{matrix.toolset == 'msvc-14.3'}}
|
||||
shell: cmd
|
||||
run: |
|
||||
choco install --no-progress ninja
|
||||
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
|
||||
cd ../boost-root/
|
||||
mkdir __build
|
||||
cd __build
|
||||
cmake -DBUILD_TESTING=1 -DBOOST_INCLUDE_LIBRARIES=conversion ..
|
||||
cmake --build . --target tests --config Debug
|
||||
ctest --output-on-failure --no-tests=error -C Debug
|
||||
cd ..
|
||||
rm -rf __build
|
||||
|
||||
- name: Run tests
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
|
||||
|
||||
finish:
|
||||
needs: posix
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Coveralls Finished
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.github_token }}
|
||||
parallel-finished: true
|
||||
@@ -0,0 +1,22 @@
|
||||
# Copyright 2019 Mike Dev
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
cmake_minimum_required( VERSION 3.5...4.20 )
|
||||
project( boost_conversion VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX )
|
||||
|
||||
add_library( boost_conversion INTERFACE )
|
||||
add_library( Boost::conversion ALIAS boost_conversion )
|
||||
|
||||
target_include_directories( boost_conversion INTERFACE include )
|
||||
|
||||
target_link_libraries( boost_conversion
|
||||
INTERFACE
|
||||
Boost::assert
|
||||
Boost::config
|
||||
Boost::throw_exception
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
@@ -0,0 +1,15 @@
|
||||
# [Boost.Conversion](https://boost.org/libs/conversion)
|
||||
Boost.Conversion is one of the [Boost C++ Libraries](https://github.com/boostorg). This library improves program safety and clarity by performing otherwise messy conversions.
|
||||
|
||||
### Test results
|
||||
|
||||
@ | Build | Tests coverage | More info
|
||||
----------------|-------------- | -------------- |-----------
|
||||
Develop branch: | [](https://github.com/boostorg/conversion/actions/workflows/ci.yml) [](https://ci.appveyor.com/project/apolukhin/conversion/branch/develop) | [](https://coveralls.io/github/boostorg/conversion?branch=develop) | [details...](https://regression.boost.io/develop/developer/conversion.html)
|
||||
Master branch: | [](https://github.com/boostorg/conversion/actions/workflows/ci.yml) [](https://ci.appveyor.com/project/apolukhin/conversion/branch/master) | [](https://coveralls.io/github/boostorg/conversion?branch=master) | [details...](https://regression.boost.io/master/developer/conversion.html)
|
||||
|
||||
[Latest developer documentation](https://www.boost.org/doc/libs/develop/doc/html/conversion.html)
|
||||
|
||||
### License
|
||||
|
||||
Distributed under the [Boost Software License, Version 1.0](https://boost.org/LICENSE_1_0.txt).
|
||||
@@ -0,0 +1,25 @@
|
||||
# Copyright René Ferdinand Rivera Morell 2023-2024
|
||||
# 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)
|
||||
|
||||
require-b2 5.2 ;
|
||||
|
||||
constant boost_dependencies :
|
||||
/boost/assert//boost_assert
|
||||
/boost/config//boost_config
|
||||
/boost/throw_exception//boost_throw_exception ;
|
||||
|
||||
project /boost/conversion
|
||||
: common-requirements
|
||||
<include>include
|
||||
;
|
||||
|
||||
explicit
|
||||
[ alias boost_conversion : : : : <library>$(boost_dependencies) ]
|
||||
[ alias all : boost_conversion test ]
|
||||
;
|
||||
|
||||
call-if : boost-library conversion
|
||||
;
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"Microsoft FrontPage 5.0">
|
||||
<meta http-equiv="Content-Type" content=
|
||||
"text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
|
||||
<title>Header boost/polymorphic_cast.hpp Documentation</title>
|
||||
<style>
|
||||
.copyright
|
||||
{
|
||||
color: #666666;
|
||||
font-size: small;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Header <a href=
|
||||
"../../boost/polymorphic_cast.hpp">boost/polymorphic_cast.hpp</a></h1>
|
||||
|
||||
<h2><a name="Cast Functions">Cast Functions</a></h2>
|
||||
|
||||
<p>The header <a href="../../boost/polymorphic_cast.hpp">boost/polymorphic_cast.hpp</a> provides <code>
|
||||
<a href="#Polymorphic_cast">polymorphic_cast</a> and</code> <a href=
|
||||
"#Polymorphic_cast"><code>polymorphic_downcast</code></a> function templates designed to
|
||||
complement the C++ built-in casts.</p>
|
||||
|
||||
<p>The program <a href="test/cast_test.cpp">cast_test.cpp</a> can be used to
|
||||
verify these function templates work as expected.</p>
|
||||
|
||||
<h3><a name="Polymorphic_cast">Polymorphic casts</a></h3>
|
||||
|
||||
<p>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 <code>Y</code> diagram hierarchy.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>The C++ built-in <code>static_cast</code> 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 <code>polymorphic_downcast</code> template retains
|
||||
the efficiency of <code>static_cast</code> for non-debug compilations, but for
|
||||
debug compilations adds safety via an assert() that a <code>dynamic_cast</code>
|
||||
succeeds.</p>
|
||||
|
||||
<p>The C++ built-in <code>dynamic_cast</code> 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 <code>dynamic_cast</code>, which
|
||||
works on references, can be used on pointers through the ugly expression
|
||||
&<code>dynamic_cast<T&>(*p)</code>, which causes undefined
|
||||
behavior if <code>p</code> is <code>0</code>. The <code>polymorphic_cast</code>
|
||||
template performs a <code>dynamic_cast</code> on a pointer, and throws an
|
||||
exception if the <code>dynamic_cast</code> returns 0.</p>
|
||||
|
||||
<p>A <code>polymorphic_downcast</code> should be used for
|
||||
downcasts that you are certain should succeed. Error checking is
|
||||
only performed in translation units where <code>NDEBUG</code> is
|
||||
not defined, via
|
||||
<pre> assert( dynamic_cast<Derived>(x) == x )
|
||||
</pre> where <code>x</code> 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 <code>polymorphic_downcast</code> will
|
||||
fail to compile.
|
||||
<b>Warning:</b> Because <code>polymorphic_downcast</code> uses assert(), it
|
||||
violates the One Definition Rule (ODR) if NDEBUG is inconsistently
|
||||
defined across translation units. [See ISO Std 3.2]
|
||||
</p><p>
|
||||
For crosscasts, or when the success of a cast can only be known at
|
||||
runtime, or when efficiency is not important,
|
||||
<code>polymorphic_cast</code> is preferred. </p>
|
||||
|
||||
<p>The C++ built-in <code>dynamic_cast</code> 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.</p>
|
||||
|
||||
<h3>polymorphic_cast and polymorphic_downcast synopsis</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>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)
|
||||
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>polymorphic_downcast example</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>#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);
|
||||
...
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>History</h3>
|
||||
|
||||
<p><code>polymorphic_cast</code> was suggested by Bjarne Stroustrup in "The C++
|
||||
Programming Language".<br>
|
||||
<code>polymorphic_downcast</code> was contributed by <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>.<code><br>
|
||||
An old
|
||||
numeric_cast</code> that was contributed by <a href=
|
||||
"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>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
|
||||
-->June 23, 2005<!--webbot bot="Timestamp" endspan i-checksum="30348"
|
||||
--></p>
|
||||
|
||||
<p class="copyright">© Copyright boost.org 1999.
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
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>)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,38 @@
|
||||
# Copyright (c) 2016 Mikhail Maximov <vigorous.activity -at- gmail.com>
|
||||
|
||||
# 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 : conversion.qbk ;
|
||||
boostbook standalone
|
||||
:
|
||||
conversion
|
||||
:
|
||||
<xsl:param>boost.root=../../../..
|
||||
# File name of HTML output:
|
||||
<xsl:param>root.filename=conversion
|
||||
# How far down we chunk nested sections, basically all of them:
|
||||
<xsl:param>chunk.section.depth=0
|
||||
# Don't put the first section on the same page as the TOC:
|
||||
<xsl:param>chunk.first.sections=0
|
||||
# How far down sections get TOC's
|
||||
<xsl:param>toc.section.depth=2
|
||||
# Max depth in each TOC:
|
||||
<xsl:param>toc.max.depth=2
|
||||
# How far down we go with TOC's
|
||||
<xsl:param>generate.section.toc.level=0
|
||||
|
||||
<xsl:param>generate.manifest=0
|
||||
;
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc : conversion ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease ;
|
||||
explicit boostrelease ;
|
||||
@@ -0,0 +1,215 @@
|
||||
[/
|
||||
Copyright 2016 Mikhail Maximov.
|
||||
Copyright Antony Polukhin, 2020-2026.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
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>)
|
||||
]
|
||||
|
||||
[article The Conversion Library
|
||||
[quickbook 1.6]
|
||||
[compatibility-mode 1.5]
|
||||
[id conversion]
|
||||
[version 1.7]
|
||||
[authors [Stroustrup, Bjarne], [Abrahams, Dave], [Rasin, Boris], [Polukhin, Antony]]
|
||||
[copyright 2001 Beman Dawes, 2014-2026 Antony Polukhin]
|
||||
[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 c++]
|
||||
]
|
||||
|
||||
[/ 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, 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).
|
||||
|
||||
[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]
|
||||
[section 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<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]
|
||||
|
||||
[h4 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);
|
||||
...
|
||||
}
|
||||
```
|
||||
[endsect]
|
||||
|
||||
[#polymorphic_cast]
|
||||
[section 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<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.
|
||||
|
||||
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.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[#polymorphic_pointer_cast]
|
||||
[section 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<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.
|
||||
|
||||
|
||||
[h4 Example:]
|
||||
```
|
||||
#include <boost/polymorphic_pointer_cast.hpp>
|
||||
|
||||
class Fruit { public: virtual ~Fruit(){} };
|
||||
class Banana : public Fruit {};
|
||||
|
||||
// Use one of these:
|
||||
using FruitPtr = Fruit*;
|
||||
using FruitPtr = std::shared_ptr<Fruit>;
|
||||
using FruitPtr = boost::shared_ptr<Fruit>;
|
||||
using FruitPtr = boost::intrusive_ptr<Fruit>;
|
||||
|
||||
void f(FruitPtr fruit) {
|
||||
// ... logic which leads us to believe it is a banana
|
||||
auto banana = boost::polymorphic_pointer_downcast<Banana>(fruit);
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Synopsis]
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
// Throws: std::bad_cast if ( dynamic_cast<Derived>(x) == 0 )
|
||||
// Returns: dynamic_cast<Derived>(x)
|
||||
template <class Derived, class Base>
|
||||
constexpr Derived polymorphic_cast(Base* x);
|
||||
|
||||
// Effects: assert( dynamic_cast<Derived>(x) == x );
|
||||
// Returns: static_cast<Derived>(x)
|
||||
template <class Derived, class Base>
|
||||
constexpr Derived polymorphic_downcast(Base* x);
|
||||
|
||||
// Effects: assert( dynamic_cast<Derived>(&x) == &x );
|
||||
// Returns: static_cast<Derived>(x)
|
||||
template <class Derived, class Base>
|
||||
constexpr Derived polymorphic_downcast(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_cast(Base x);
|
||||
|
||||
// Effects: assert( dynamic_pointer_cast<Derived>(x) == x );
|
||||
// Returns: static_pointer_cast<Derived>(x)
|
||||
template <class Derived, class Base>
|
||||
inline auto polymorphic_pointer_downcast(Base x);
|
||||
|
||||
}
|
||||
```
|
||||
[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.
|
||||
|
||||
`polymorphic_downcast` overload for references was contributed by Julien Delacroix.
|
||||
|
||||
An old `numeric_cast` that was contributed by [@http://www.boost.org/people/kevlin_henney.htm Kevlin Henney]
|
||||
is now superseded by the [@boost:numeric_conversion/doc/html/html/boost_numericconversion/improved_numeric_cast__.html Boost Numeric Conversion Library]
|
||||
[endsect]
|
||||
@@ -2,8 +2,14 @@
|
||||
// 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)
|
||||
#ifndef IMPLICIT_CAST_DWA200356_HPP
|
||||
# define IMPLICIT_CAST_DWA200356_HPP
|
||||
|
||||
#ifndef BOOST_IMPLICIT_CAST_DWA200356_HPP
|
||||
#define BOOST_IMPLICIT_CAST_DWA200356_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -11,7 +17,7 @@ namespace detail {
|
||||
|
||||
template<class T> struct icast_identity
|
||||
{
|
||||
typedef T type;
|
||||
using type = T;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
@@ -22,15 +28,11 @@ template<class T> struct icast_identity
|
||||
// The use of identity creates a non-deduced form, so that the
|
||||
// explicit template argument must be supplied
|
||||
template <typename T>
|
||||
inline T implicit_cast (typename boost::detail::icast_identity<T>::type x) {
|
||||
constexpr T implicit_cast (typename boost::detail::icast_identity<T>::type x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
// incomplete return type now is here
|
||||
//template <typename T>
|
||||
//void implicit_cast (...);
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // IMPLICIT_CAST_DWA200356_HPP
|
||||
#endif // BOOST_IMPLICIT_CAST_DWA200356_HPP
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// boost polymorphic_cast.hpp header file ----------------------------------------------//
|
||||
|
||||
// (C) Copyright Kevlin Henney and Dave Abrahams 1999.
|
||||
// (C) Copyright Boris Rasin 2014.
|
||||
// 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)
|
||||
@@ -8,9 +9,12 @@
|
||||
// See http://www.boost.org/libs/conversion for Documentation.
|
||||
|
||||
// Revision History
|
||||
// 10 Nov 14 polymorphic_pointer_downcast moved to a separate header,
|
||||
// minor improvements to stisfy latest Boost coding style
|
||||
// 08 Nov 14 Add polymorphic_pointer_downcast (Boris Rasin)
|
||||
// 09 Jun 14 "cast.hpp" was renamed to "polymorphic_cast.hpp" and
|
||||
// inclusion of numeric_cast was removed (Antony Polukhin)
|
||||
// 23 Jun 05 numeric_cast removed and redirected to the new verion (Fernando Cacciola)
|
||||
// 23 Jun 05 numeric_cast removed and redirected to the new version (Fernando Cacciola)
|
||||
// 02 Apr 01 Removed BOOST_NO_LIMITS workarounds and included
|
||||
// <boost/limits.hpp> instead (the workaround did not
|
||||
// actually compile when BOOST_NO_LIMITS was defined in
|
||||
@@ -27,7 +31,7 @@
|
||||
// 19 Oct 00 Fix numeric_cast for floating-point types (Dave Abrahams)
|
||||
// 15 Jul 00 Suppress numeric_cast warnings for GCC, Borland and MSVC
|
||||
// (Dave Abrahams)
|
||||
// 30 Jun 00 More MSVC6 wordarounds. See comments below. (Dave Abrahams)
|
||||
// 30 Jun 00 More MSVC6 workarounds. See comments below. (Dave Abrahams)
|
||||
// 28 Jun 00 Removed implicit_cast<>. See comment below. (Beman Dawes)
|
||||
// 27 Jun 00 More MSVC6 workarounds
|
||||
// 15 Jun 00 Add workarounds for MSVC6
|
||||
@@ -45,9 +49,24 @@
|
||||
#ifndef BOOST_POLYMORPHIC_CAST_HPP
|
||||
#define BOOST_POLYMORPHIC_CAST_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
# include <boost/assert.hpp>
|
||||
# include <boost/throw_exception.hpp>
|
||||
|
||||
# include <memory> // std::addressof
|
||||
# include <typeinfo>
|
||||
# include <type_traits>
|
||||
|
||||
#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
|
||||
#define BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST constexpr
|
||||
#else
|
||||
#define BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST inline
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -61,16 +80,16 @@ namespace boost
|
||||
// section 15.8 exercise 1, page 425.
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target polymorphic_cast(Source* x)
|
||||
BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST Target polymorphic_cast(Source* x)
|
||||
{
|
||||
Target tmp = dynamic_cast<Target>(x);
|
||||
if ( tmp == 0 ) throw std::bad_cast();
|
||||
if ( tmp == 0 ) boost::throw_exception( std::bad_cast() );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// polymorphic_downcast ----------------------------------------------------//
|
||||
|
||||
// BOOST_ASSERT() checked polymorphic downcast. Crosscasts prohibited.
|
||||
// BOOST_ASSERT() checked raw pointer polymorphic downcast. Crosscasts prohibited.
|
||||
|
||||
// WARNING: Because this cast uses BOOST_ASSERT(), it violates
|
||||
// the One Definition Rule if used in multiple translation units
|
||||
@@ -80,12 +99,34 @@ namespace boost
|
||||
// Contributed by Dave Abrahams
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target polymorphic_downcast(Source* x)
|
||||
BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST Target polymorphic_downcast(Source* x)
|
||||
{
|
||||
BOOST_ASSERT( dynamic_cast<Target>(x) == x ); // detect logic error
|
||||
return static_cast<Target>(x);
|
||||
}
|
||||
|
||||
// BOOST_ASSERT() checked reference polymorphic downcast. Crosscasts prohibited.
|
||||
|
||||
// WARNING: Because this cast uses BOOST_ASSERT(), it violates
|
||||
// the One Definition Rule if used in multiple translation units
|
||||
// where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER
|
||||
// NDEBUG are defined inconsistently.
|
||||
|
||||
// Contributed by Julien Delacroix
|
||||
|
||||
template <class Target, class Source>
|
||||
BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST typename std::enable_if<
|
||||
std::is_reference<Target>::value, Target
|
||||
>::type polymorphic_downcast(Source& x)
|
||||
{
|
||||
using target_pointer_type = typename std::remove_reference<Target>::type*;
|
||||
return *boost::polymorphic_downcast<target_pointer_type>(
|
||||
std::addressof(x)
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST
|
||||
|
||||
#endif // BOOST_POLYMORPHIC_CAST_HPP
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// boost polymorphic_pointer_cast.hpp header file ----------------------------------------------//
|
||||
// (C) Copyright Boris Rasin, 2014-2021.
|
||||
// (C) Copyright Antony Polukhin, 2014-2026.
|
||||
// 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)
|
||||
|
||||
// See http://www.boost.org/libs/conversion for Documentation.
|
||||
|
||||
#ifndef BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP
|
||||
#define BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
# include <boost/assert.hpp>
|
||||
# include <boost/pointer_cast.hpp>
|
||||
# include <boost/throw_exception.hpp>
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// See the documentation for descriptions of how to choose between
|
||||
// static_pointer_cast<>, dynamic_pointer_cast<>, polymorphic_pointer_cast<> and polymorphic_pointer_downcast<>
|
||||
|
||||
// polymorphic_pointer_downcast --------------------------------------------//
|
||||
|
||||
// BOOST_ASSERT() checked polymorphic downcast. Crosscasts prohibited.
|
||||
// Supports any type with static_pointer_cast/dynamic_pointer_cast functions:
|
||||
// built-in pointers, std::shared_ptr, boost::shared_ptr, boost::intrusive_ptr, etc.
|
||||
|
||||
// WARNING: Because this cast uses BOOST_ASSERT(), it violates
|
||||
// the One Definition Rule if used in multiple translation units
|
||||
// where BOOST_DISABLE_ASSERTS, BOOST_ENABLE_ASSERT_HANDLER
|
||||
// NDEBUG are defined inconsistently.
|
||||
|
||||
// Contributed by Boris Rasin
|
||||
|
||||
template <typename Target, typename Source>
|
||||
inline auto polymorphic_pointer_downcast (const Source& x)
|
||||
-> decltype(static_pointer_cast<Target>(x))
|
||||
{
|
||||
BOOST_ASSERT(dynamic_pointer_cast<Target> (x) == x);
|
||||
return static_pointer_cast<Target> (x);
|
||||
}
|
||||
|
||||
template <typename Target, typename Source>
|
||||
inline auto polymorphic_pointer_cast (const Source& x)
|
||||
-> decltype(dynamic_pointer_cast<Target>(x))
|
||||
{
|
||||
auto tmp = dynamic_pointer_cast<Target> (x);
|
||||
if ( !tmp ) boost::throw_exception( std::bad_cast() );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP
|
||||
+32
-42
@@ -1,49 +1,39 @@
|
||||
<html>
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (c) 2016 Mikhail Maximov
|
||||
vigorous.activity at gmail dot com
|
||||
|
||||
Copyright (c) Antony Polukhin, 2021-2026
|
||||
|
||||
Distributed under the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
boost-no-inspect
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Boost Conversion Library</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="0; url=../../doc/html/conversion.html">
|
||||
<title>Boost.Conversion</title>
|
||||
<style>
|
||||
.copyright
|
||||
{
|
||||
color: #666666;
|
||||
font-size: small;
|
||||
}
|
||||
body {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
a {
|
||||
color: #00f;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<h1><img border="0" src="../../boost.png" align="center" width="277" height="86">Boost
|
||||
Conversion Library</h1>
|
||||
|
||||
<p>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.</p>
|
||||
<p>To reduce coupling, particularly to standard library IOStreams, the Boost
|
||||
Conversion Library is
|
||||
supplied by several headers:</p>
|
||||
<ul>
|
||||
<li>The <a href="cast.htm">boost/cast</a> header provides <b>polymorphic_cast<></b>
|
||||
and <b>polymorphic_downcast<></b> to perform safe casting between
|
||||
polymorphic types.<br>
|
||||
</li>
|
||||
<li>The <a href="../../doc/html/boost_lexical_cast.html">boost/lexical_cast</a> header provides <b>lexical_cast<></b>
|
||||
general literal text conversions, such as an <code>int</code> represented as
|
||||
a <code>string</code>, or vice-versa.</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED"
|
||||
S-Format="%d %B, %Y" startspan -->June 23, 2005<!--webbot bot="Timestamp" endspan i-checksum="30348" -->
|
||||
</p>
|
||||
<p class="copyright">
|
||||
Copyright 2001 Beman Dawes.
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
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>)
|
||||
</p>
|
||||
<body>
|
||||
<p>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="../../doc/html/conversion.html">../../doc/html/conversion.html</a>
|
||||
</p>
|
||||
<p>
|
||||
© Antony Polukhin, 2014-2024
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
+2
-1
@@ -11,5 +11,6 @@
|
||||
],
|
||||
"maintainers": [
|
||||
"Antony Polukhin <antoshkka -at- gmail.com>"
|
||||
]
|
||||
],
|
||||
"cxxstd": "11"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2016-2026 Antony Polukhin
|
||||
# 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
|
||||
|
||||
include(BoostTest OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
|
||||
|
||||
if(NOT HAVE_BOOST_TEST)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(BOOST_TEST_LINK_LIBRARIES Boost::conversion Boost::core)
|
||||
|
||||
boost_test(TYPE run SOURCES cast_test.cpp)
|
||||
boost_test(TYPE run SOURCES implicit_cast.cpp)
|
||||
boost_test(TYPE compile-fail SOURCES implicit_cast_fail.cpp)
|
||||
boost_test(TYPE compile-fail SOURCES implicit_cast_fail2.cpp)
|
||||
boost_test(TYPE run SOURCES polymorphic_cast_test.cpp LINK_LIBRARIES Boost::smart_ptr)
|
||||
+7
-5
@@ -1,18 +1,20 @@
|
||||
# Copyright (C) 2001-2003 Douglas Gregor
|
||||
# Copyright (C) 2011-2014 Antony Polukhin
|
||||
# Copyright (C) Antony Polukhin, 2011-2024
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
|
||||
require-b2 5.0.1 ;
|
||||
import-search /boost/config/checks ;
|
||||
import config : requires ;
|
||||
import testing ;
|
||||
import feature ;
|
||||
|
||||
project
|
||||
: requirements
|
||||
<toolset>gcc-4.7:<cxxflags>-ftrapv
|
||||
<toolset>gcc-4.6:<cxxflags>-ftrapv
|
||||
<toolset>clang:<cxxflags>-ftrapv
|
||||
<library>/boost/conversion//boost_conversion
|
||||
[ requires cxx11_decltype ]
|
||||
# default to all warnings on:
|
||||
<warnings>all
|
||||
# set warnings as errors for those compilers we know we get warning free:
|
||||
@@ -24,6 +26,6 @@ test-suite conversion
|
||||
: [ run implicit_cast.cpp ]
|
||||
[ compile-fail implicit_cast_fail.cpp ]
|
||||
[ run cast_test.cpp ]
|
||||
[ run polymorphic_cast_test.cpp ]
|
||||
[ run polymorphic_cast_test.cpp : : : <library>/boost/smart_ptr//boost_smart_ptr ]
|
||||
[ compile-fail implicit_cast_fail2.cpp ]
|
||||
;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# Use, modification, and distribution are
|
||||
# subject to 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)
|
||||
#
|
||||
# Copyright Antony Polukhin, 2016-2025.
|
||||
|
||||
#
|
||||
# See https://svn.boost.org/trac/boost/wiki/TravisCoverals for description of this file
|
||||
# and how it can be used with Boost libraries.
|
||||
#
|
||||
# File revision #6
|
||||
|
||||
init:
|
||||
# boost-local/libs/ folder to put this library into. This may be useful, if you're for example running Travis
|
||||
# from `Boost.DLL` repo while Boost already has `dll` and with to replace `dll` with content of`Boost.DLL`.
|
||||
#
|
||||
# Otherwise just leave the default value - set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
|
||||
- set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
|
||||
|
||||
###############################################################################################################
|
||||
# From this point and below code is same for all the Boost libs
|
||||
###############################################################################################################
|
||||
|
||||
version: 1.84.{build}-{branch}
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
skip_tags: true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1,clang-win
|
||||
CXXSTD: 14,17
|
||||
ADDRMD: 32,64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\mingw\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 03,11,14,1z
|
||||
|
||||
before_build:
|
||||
- set BOOST_BRANCH=develop
|
||||
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
- echo "Testing %APPVEYOR_PROJECT_NAME%"
|
||||
# Cloning Boost libraries (fast nondeep cloning)
|
||||
- set BOOST=C:/boost-local
|
||||
- git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git %BOOST%
|
||||
- cd %BOOST%
|
||||
- git submodule update --init --depth 10 tools/build tools/boostdep
|
||||
|
||||
- rm -rf %BOOST%/libs/%BOOST_LIBS_FOLDER%
|
||||
- mv -f %APPVEYOR_BUILD_FOLDER% %BOOST%/libs/%BOOST_LIBS_FOLDER%
|
||||
- python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 2" %BOOST_LIBS_FOLDER%
|
||||
|
||||
build_script:
|
||||
- cmd /c bootstrap
|
||||
- b2.exe headers
|
||||
- cd %BOOST%/libs/%BOOST_LIBS_FOLDER%/test
|
||||
|
||||
after_build:
|
||||
before_test:
|
||||
test_script:
|
||||
- PATH=%ADDPATH%%PATH%
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
- echo "Running command ..\..\..\b2 -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release"
|
||||
- ..\..\..\b2.exe -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release cxxflags="-DBOOST_TRAVISCI_BUILD"
|
||||
|
||||
after_test:
|
||||
on_success:
|
||||
on_failure:
|
||||
on_finish:
|
||||
+56
-17
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/polymorphic_cast.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using std::cout;
|
||||
@@ -37,6 +38,48 @@ namespace
|
||||
};
|
||||
}
|
||||
|
||||
constexpr bool compile_time_polymorphic_cast_check() {
|
||||
#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
|
||||
Derived derived;
|
||||
Base* base = &derived;
|
||||
return polymorphic_cast<Derived*>(base) != nullptr;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static_assert(
|
||||
compile_time_polymorphic_cast_check(),
|
||||
"polymorphic_cast does not work at compile time"
|
||||
);
|
||||
|
||||
constexpr bool compile_time_polymorphic_downcast_check() {
|
||||
#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
|
||||
Derived derived;
|
||||
Base* base = &derived;
|
||||
return polymorphic_downcast<Derived*>(base) != nullptr;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static_assert(
|
||||
compile_time_polymorphic_downcast_check(),
|
||||
"polymorphic_downcast does not work at compile time"
|
||||
);
|
||||
|
||||
constexpr bool compile_time_polymorphic_downcast2_check() {
|
||||
#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
|
||||
Derived derived;
|
||||
Base& base = derived;
|
||||
Derived& derived_again = polymorphic_downcast<Derived&>(base);
|
||||
(void)derived_again;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static_assert(
|
||||
compile_time_polymorphic_downcast2_check(),
|
||||
"polymorphic_downcast does not work at compile time"
|
||||
);
|
||||
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
@@ -51,35 +94,31 @@ int main( int argc, char * argv[] )
|
||||
// test polymorphic_cast ---------------------------------------------------//
|
||||
|
||||
// tests which should succeed
|
||||
Base * base = new Derived;
|
||||
Base2 * base2 = 0;
|
||||
Derived * derived = 0;
|
||||
derived = polymorphic_downcast<Derived*>( base ); // downcast
|
||||
assert( derived->kind() == 'D' );
|
||||
Derived derived_instance;
|
||||
Base * base = &derived_instance;
|
||||
Derived * derived = polymorphic_downcast<Derived*>( base ); // downcast
|
||||
BOOST_TEST( derived->kind() == 'D' );
|
||||
|
||||
derived = 0;
|
||||
derived = polymorphic_cast<Derived*>( base ); // downcast, throw on error
|
||||
assert( derived->kind() == 'D' );
|
||||
BOOST_TEST( derived->kind() == 'D' );
|
||||
|
||||
base2 = polymorphic_cast<Base2*>( base ); // crosscast
|
||||
assert( base2->kind2() == '2' );
|
||||
Base2 * base2 = polymorphic_cast<Base2*>( base ); // crosscast
|
||||
BOOST_TEST( base2->kind2() == '2' );
|
||||
|
||||
// tests which should result in errors being detected
|
||||
int err_count = 0;
|
||||
base = new Base;
|
||||
Base base_instance;
|
||||
base = &base_instance;
|
||||
|
||||
if ( argc > 1 && *argv[1] == '1' )
|
||||
{ derived = polymorphic_downcast<Derived*>( base ); } // #1 assert failure
|
||||
|
||||
bool caught_exception = false;
|
||||
try { derived = polymorphic_cast<Derived*>( base ); }
|
||||
catch (std::bad_cast)
|
||||
catch (const std::bad_cast&)
|
||||
{ cout<<"caught bad_cast\n"; caught_exception = true; }
|
||||
if ( !caught_exception ) ++err_count;
|
||||
BOOST_TEST( caught_exception );
|
||||
// the following is just so generated code can be inspected
|
||||
if ( derived->kind() == 'B' ) ++err_count;
|
||||
BOOST_TEST( derived->kind() != 'B' );
|
||||
|
||||
cout << err_count << " errors detected\nTest "
|
||||
<< (err_count==0 ? "passed\n" : "failed\n");
|
||||
return err_count;
|
||||
return boost::report_errors();
|
||||
} // main
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/implicit_cast.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/type.hpp>
|
||||
|
||||
using boost::implicit_cast;
|
||||
using boost::type;
|
||||
|
||||
@@ -18,8 +19,8 @@ struct foo
|
||||
operator long() const { return 0; }
|
||||
};
|
||||
|
||||
typedef type<long> long_type;
|
||||
typedef type<foo> foo_type;
|
||||
using long_type = type<long>;
|
||||
using foo_type = type<foo>;
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -29,10 +30,14 @@ int main()
|
||||
type<foo> f = check_return(boost::implicit_cast<foo>("hello"));
|
||||
type<long> z = check_return(boost::implicit_cast<long>(foo("hello")));
|
||||
|
||||
// warning supression:
|
||||
// warning suppression:
|
||||
(void)x;
|
||||
(void)f;
|
||||
(void)z;
|
||||
|
||||
|
||||
constexpr long value = boost::implicit_cast<long>(42);
|
||||
BOOST_TEST(value == 42L);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
//
|
||||
// Test boost::polymorphic_cast, boost::polymorphic_downcast
|
||||
// Test boost::polymorphic_cast, boost::polymorphic_downcast and
|
||||
// boost::polymorphic_pointer_cast, boost::polymorphic_pointer_downcast
|
||||
//
|
||||
// Copyright 1999 Beman Dawes
|
||||
// Copyright 1999 Dave Abrahams
|
||||
// Copyright 2014 Peter Dimov
|
||||
// Copyright 2014 Boris Rasin, Antony Polukhin
|
||||
// Copyright 2023 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
@@ -12,18 +15,28 @@
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
#include <boost/polymorphic_cast.hpp>
|
||||
#include <boost/polymorphic_pointer_cast.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
static bool expect_assertion = false;
|
||||
static int assertion_failed_count = 0;
|
||||
|
||||
//assertion handler throws it to exit like assert, but to be able to catch it and stop
|
||||
//usage: BOOST_TEST_THROWS( function_with_assert(), expected_assertion );
|
||||
struct expected_assertion {};
|
||||
|
||||
// BOOST_ASSERT custom handler
|
||||
void boost::assertion_failed( char const * expr, char const * function, char const * file, long line )
|
||||
{
|
||||
if( expect_assertion )
|
||||
{
|
||||
++assertion_failed_count;
|
||||
throw expected_assertion();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -37,7 +50,7 @@ void boost::assertion_failed( char const * expr, char const * function, char con
|
||||
|
||||
//
|
||||
|
||||
struct Base
|
||||
struct Base : boost::intrusive_ref_counter<Base>
|
||||
{
|
||||
virtual ~Base() {}
|
||||
virtual std::string kind() { return "Base"; }
|
||||
@@ -97,11 +110,93 @@ static void test_polymorphic_cast()
|
||||
delete base;
|
||||
}
|
||||
|
||||
static void test_polymorphic_downcast()
|
||||
static void test_polymorphic_pointer_cast()
|
||||
{
|
||||
Base * base = new Derived;
|
||||
|
||||
Derived * derived = boost::polymorphic_downcast<Derived*>( base );
|
||||
Derived * derived;
|
||||
|
||||
try
|
||||
{
|
||||
derived = boost::polymorphic_pointer_cast<Derived>( base );
|
||||
|
||||
BOOST_TEST( derived != 0 );
|
||||
|
||||
if( derived != 0 )
|
||||
{
|
||||
BOOST_TEST_EQ( derived->kind(), "Derived" );
|
||||
}
|
||||
}
|
||||
catch( std::bad_cast const& )
|
||||
{
|
||||
BOOST_ERROR( "boost::polymorphic_pointer_cast<Derived>( base ) threw std::bad_cast" );
|
||||
}
|
||||
|
||||
Base2 * base2;
|
||||
|
||||
try
|
||||
{
|
||||
base2 = boost::polymorphic_pointer_cast<Base2>( base ); // crosscast
|
||||
|
||||
BOOST_TEST( base2 != 0 );
|
||||
|
||||
if( base2 != 0 )
|
||||
{
|
||||
BOOST_TEST_EQ( base2->kind2(), "Base2" );
|
||||
}
|
||||
}
|
||||
catch( std::bad_cast const& )
|
||||
{
|
||||
BOOST_ERROR( "boost::polymorphic_pointer_cast<Base2>( base ) threw std::bad_cast" );
|
||||
}
|
||||
|
||||
boost::shared_ptr<Base> sp_base( base );
|
||||
boost::shared_ptr<Base2> sp_base2;
|
||||
try
|
||||
{
|
||||
sp_base2 = boost::polymorphic_pointer_cast<Base2>( sp_base ); // crosscast
|
||||
|
||||
BOOST_TEST( sp_base2 != 0 );
|
||||
|
||||
if( sp_base2 != 0 )
|
||||
{
|
||||
BOOST_TEST_EQ( sp_base2->kind2(), "Base2" );
|
||||
}
|
||||
}
|
||||
catch( std::bad_cast const& )
|
||||
{
|
||||
BOOST_ERROR( "boost::polymorphic_pointer_cast<Base2>( sp_base ) threw std::bad_cast" );
|
||||
}
|
||||
|
||||
// we do not `delete base;` because sahred_ptr is holding base
|
||||
}
|
||||
|
||||
static void test_polymorphic_downcast()
|
||||
{
|
||||
Base *base_pointer = new Derived;
|
||||
|
||||
// test raw pointer cast
|
||||
Derived *derived_pointer = boost::polymorphic_downcast<Derived *>(base_pointer);
|
||||
|
||||
BOOST_TEST(derived_pointer != 0);
|
||||
|
||||
if (derived_pointer != 0)
|
||||
{
|
||||
BOOST_TEST_EQ(derived_pointer->kind(), "Derived");
|
||||
}
|
||||
|
||||
// test reference cast
|
||||
Derived& derived_ref = boost::polymorphic_downcast<Derived&>(*base_pointer);
|
||||
BOOST_TEST_EQ(derived_ref.kind(), "Derived");
|
||||
|
||||
delete base_pointer;
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_downcast_builtin()
|
||||
{
|
||||
Base * base = new Derived;
|
||||
|
||||
Derived * derived = boost::polymorphic_pointer_downcast<Derived>( base );
|
||||
|
||||
BOOST_TEST( derived != 0 );
|
||||
|
||||
@@ -110,11 +205,53 @@ static void test_polymorphic_downcast()
|
||||
BOOST_TEST_EQ( derived->kind(), "Derived" );
|
||||
}
|
||||
|
||||
// polymorphic_downcast can't do crosscasts
|
||||
// polymorphic_pointer_downcast can't do crosscasts
|
||||
|
||||
delete base;
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_downcast_boost_shared()
|
||||
{
|
||||
boost::shared_ptr<Base> base (new Derived);
|
||||
|
||||
boost::shared_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
|
||||
|
||||
BOOST_TEST( derived != 0 );
|
||||
|
||||
if( derived != 0 )
|
||||
{
|
||||
BOOST_TEST_EQ( derived->kind(), "Derived" );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_downcast_intrusive()
|
||||
{
|
||||
boost::intrusive_ptr<Base> base (new Derived);
|
||||
|
||||
boost::intrusive_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
|
||||
|
||||
BOOST_TEST( derived != 0 );
|
||||
|
||||
if( derived != 0 )
|
||||
{
|
||||
BOOST_TEST_EQ( derived->kind(), "Derived" );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_downcast_std_shared()
|
||||
{
|
||||
std::shared_ptr<Base> base (new Derived);
|
||||
|
||||
std::shared_ptr<Derived> derived = boost::polymorphic_pointer_downcast<Derived>( base );
|
||||
|
||||
BOOST_TEST( derived != 0 );
|
||||
|
||||
if( derived != 0 )
|
||||
{
|
||||
BOOST_TEST_EQ( derived->kind(), "Derived" );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_polymorphic_cast_fail()
|
||||
{
|
||||
Base * base = new Base;
|
||||
@@ -124,14 +261,57 @@ static void test_polymorphic_cast_fail()
|
||||
delete base;
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_cast_fail()
|
||||
{
|
||||
Base * base = new Base;
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( base ), std::bad_cast );
|
||||
delete base;
|
||||
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( boost::shared_ptr<Base>(new Base) ), std::bad_cast );
|
||||
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( std::shared_ptr<Base>(new Base) ), std::bad_cast );
|
||||
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( boost::intrusive_ptr<Base>(new Base) ), std::bad_cast );
|
||||
}
|
||||
|
||||
static void test_polymorphic_downcast_fail()
|
||||
{
|
||||
Base * base_pointer = new Base;
|
||||
|
||||
{
|
||||
// test raw pointer cast
|
||||
|
||||
int old_count = assertion_failed_count;
|
||||
expect_assertion = true;
|
||||
|
||||
BOOST_TEST_THROWS(boost::polymorphic_downcast<Derived *>(base_pointer), expected_assertion); // should assert
|
||||
|
||||
BOOST_TEST_EQ(assertion_failed_count, old_count + 1);
|
||||
expect_assertion = false;
|
||||
}
|
||||
{
|
||||
// test reference cast
|
||||
|
||||
int old_count = assertion_failed_count;
|
||||
expect_assertion = true;
|
||||
|
||||
BOOST_TEST_THROWS(boost::polymorphic_downcast<Derived &>(*base_pointer), expected_assertion); // should assert
|
||||
|
||||
BOOST_TEST_EQ(assertion_failed_count, old_count + 1);
|
||||
expect_assertion = false;
|
||||
}
|
||||
|
||||
delete base_pointer;
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_downcast_builtin_fail()
|
||||
{
|
||||
Base * base = new Base;
|
||||
|
||||
int old_count = assertion_failed_count;
|
||||
expect_assertion = true;
|
||||
|
||||
boost::polymorphic_downcast<Derived*>( base ); // should assert
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
|
||||
|
||||
BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
|
||||
expect_assertion = false;
|
||||
@@ -139,12 +319,65 @@ static void test_polymorphic_downcast_fail()
|
||||
delete base;
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_downcast_boost_shared_fail()
|
||||
{
|
||||
boost::shared_ptr<Base> base (new Base);
|
||||
|
||||
int old_count = assertion_failed_count;
|
||||
expect_assertion = true;
|
||||
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
|
||||
|
||||
BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
|
||||
expect_assertion = false;
|
||||
}
|
||||
|
||||
|
||||
static void test_polymorphic_pointer_downcast_std_shared_fail()
|
||||
{
|
||||
std::shared_ptr<Base> base (new Base);
|
||||
|
||||
int old_count = assertion_failed_count;
|
||||
expect_assertion = true;
|
||||
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion ); // should assert
|
||||
|
||||
BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
|
||||
expect_assertion = false;
|
||||
}
|
||||
|
||||
|
||||
static void test_polymorphic_pointer_downcast_intrusive_fail()
|
||||
{
|
||||
boost::intrusive_ptr<Base> base (new Base);
|
||||
|
||||
int old_count = assertion_failed_count;
|
||||
expect_assertion = true;
|
||||
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_downcast<Derived>( base ), expected_assertion); // should assert
|
||||
|
||||
BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
|
||||
expect_assertion = false;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_polymorphic_cast();
|
||||
test_polymorphic_pointer_cast();
|
||||
test_polymorphic_downcast();
|
||||
test_polymorphic_pointer_downcast_builtin();
|
||||
test_polymorphic_pointer_downcast_boost_shared();
|
||||
test_polymorphic_pointer_downcast_intrusive();
|
||||
test_polymorphic_cast_fail();
|
||||
test_polymorphic_pointer_cast_fail();
|
||||
test_polymorphic_downcast_fail();
|
||||
test_polymorphic_pointer_downcast_builtin_fail();
|
||||
test_polymorphic_pointer_downcast_boost_shared_fail();
|
||||
test_polymorphic_pointer_downcast_intrusive_fail();
|
||||
|
||||
test_polymorphic_pointer_downcast_std_shared();
|
||||
test_polymorphic_pointer_downcast_std_shared_fail();
|
||||
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user