mirror of
https://github.com/boostorg/conversion.git
synced 2026-08-04 04:24:11 +02:00
Compare commits
421 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 4e9021cac5 | |||
| ff7ea09a73 | |||
| 6943537150 | |||
| cf31a2ec00 | |||
| 800c10a4eb | |||
| df57f25807 | |||
| f0caf56d0b | |||
| 24d6ac1e87 | |||
| 8a03282736 | |||
| 40c42eb740 | |||
| 36945c35bd | |||
| a0922ab598 | |||
| 77a4a55af4 | |||
| 5c3878f015 | |||
| 5e93f4086c | |||
| e2a68fdec1 | |||
| ee91295ac4 | |||
| e3e4d3836a | |||
| d1a51b897d | |||
| 9e6aa219d3 | |||
| 1e65265b8f | |||
| 90b4286753 | |||
| 5a757dcece | |||
| 36bc5aea44 | |||
| ac7da550b4 | |||
| e8954f3868 | |||
| 1707131ac3 | |||
| 2f2c1a3443 | |||
| 91b77e7373 | |||
| e3dec04dd5 | |||
| b40bc02f94 | |||
| 07082420b3 | |||
| 57e4e87e3b | |||
| e913b7cb1c | |||
| c0c02e560e | |||
| bbd746d2ac | |||
| bf75439403 | |||
| edde5f442e | |||
| d78d334dbb | |||
| 39d1abe754 | |||
| 524232ebab | |||
| 472ebeff30 | |||
| 13f14db751 | |||
| 8a49514506 | |||
| c8bd860de6 | |||
| a98a74d3dd | |||
| f2e0225b1b | |||
| 701963d3c4 | |||
| ce7a54af7f | |||
| c2c4b884fe | |||
| 6f656adea3 | |||
| c359ed53b2 | |||
| 47041de63a | |||
| c58a55a512 | |||
| dd165b4b0f | |||
| b5552e351c | |||
| 297b115e6c | |||
| a2299ec1f9 | |||
| bf551ad8c9 | |||
| fac805ddf6 | |||
| 3ce36a2848 | |||
| 4ba64ea889 | |||
| d723c18fff | |||
| 6bd8edfa02 | |||
| 7e484c17f6 | |||
| 5f44bdcae8 | |||
| a65fcf571f | |||
| 13d98f02d0 | |||
| 91aa2ce64d | |||
| f7bd5e24c2 | |||
| 3af0af9405 | |||
| c3c44c208a | |||
| 93a01eba32 | |||
| b97f2542ec | |||
| 12fd711cc8 | |||
| 32d70a0764 | |||
| 1a0ffcadbf | |||
| ab0727fdac | |||
| 633b852b81 | |||
| 9fc1a66d27 | |||
| a4bd056b8e | |||
| 61938bc8d3 | |||
| 694f7b5033 | |||
| 335c868e9b | |||
| a15dbed640 | |||
| 5c8c897d30 | |||
| 3e4a1669f1 | |||
| cb9de2c55f | |||
| 89556c8a0f | |||
| 47bef9517f | |||
| 518203671c | |||
| 63b680c082 | |||
| 16890bf041 | |||
| 565e2882d3 | |||
| 24bc6ca6f2 | |||
| 4ad6f1bd4b | |||
| 5a6309db7a | |||
| 2333ee53f8 | |||
| dbda7689e0 | |||
| e15f179bfc | |||
| 82969ebb20 | |||
| 17f4b6fd4c | |||
| 2ea7487806 | |||
| cd5a55aab5 | |||
| f682bff3a7 | |||
| 1c37887f2b | |||
| 5c3159cd1c | |||
| c484325310 | |||
| 0920c53e23 | |||
| 42e7585dd4 | |||
| 7b6c4eed7d | |||
| 824fbd9b06 | |||
| 8d373a0c99 | |||
| 77eff6b47d | |||
| 8705038cd2 | |||
| bb224866a7 | |||
| 733438e072 | |||
| c43b86d7f1 | |||
| c290a26625 | |||
| d08477900d | |||
| 63acf4f174 | |||
| ce95319f03 | |||
| f67347e308 | |||
| d6a72e9ea5 | |||
| 46c6cc911b | |||
| 3c94791b1e | |||
| 80d480ca0b | |||
| e81d4dfdbb | |||
| 675d0bb451 | |||
| fe79553bf8 | |||
| 093e298c9d | |||
| d2361fe05a | |||
| b037563bf9 | |||
| 88244b57d4 | |||
| e3cd0ca7fa | |||
| 79d6468aeb | |||
| c6318e3819 | |||
| e691b15b77 | |||
| ca9c8d30bd | |||
| bb46dbc46c | |||
| d30dd9e3c8 | |||
| b1b5305984 | |||
| 15ab0d6385 | |||
| eb4ad73caf | |||
| d963842d70 | |||
| 9ff79f4df9 | |||
| 746d466e38 | |||
| 674e71fb7d | |||
| 35d592fc21 | |||
| 7881eb5666 | |||
| 8562b480f8 | |||
| 6ff6958204 | |||
| 1e58331baf | |||
| 2af8c47558 | |||
| deef894ae2 | |||
| 4a617adce1 | |||
| 969a913153 | |||
| 41a673db61 | |||
| acb746274f | |||
| dfb518997f | |||
| 93ee01ab69 | |||
| 4265f454e1 | |||
| 76b9f29c12 | |||
| a065884c59 | |||
| 676bde6e1f | |||
| 7e7f494dd1 | |||
| 83639bd9ae | |||
| 0dded6d3a7 | |||
| 25d880f5eb | |||
| b71fb9aada | |||
| d9baa71302 | |||
| 80e858b182 | |||
| 646b958a92 | |||
| 04f441e989 | |||
| e51cf081b3 | |||
| 7a48fea517 | |||
| c9863cd254 | |||
| 132663404b | |||
| a0cbfa8af6 | |||
| efe20fcf76 | |||
| 84d9706182 | |||
| 5ed7bfd280 | |||
| 51a6aacb57 | |||
| 7bdc45327a | |||
| a2e4606e6c | |||
| 9a6d983ee5 | |||
| d754143308 | |||
| 82abf7b54f | |||
| 085bd6f93c | |||
| 5d288580ee | |||
| 7112ded1b9 | |||
| 8627f8bb8a | |||
| f32fb4b5e5 | |||
| a9697b88fd | |||
| 2312691bde | |||
| 7dd63d08d6 | |||
| 1eda87448e | |||
| 4ddb0bfb95 | |||
| c07cbcee5c | |||
| 8c7c7b9237 | |||
| 3d60698843 | |||
| 3a62368d0e | |||
| d2ae7fdbd7 | |||
| e1caac418c | |||
| 2acef7aa44 | |||
| 8480a6d083 | |||
| 00f1246faf | |||
| 2f5d0c847b | |||
| eb66b40e67 | |||
| 5ebb13bbad | |||
| 4a4150d0be | |||
| 9955dcce51 | |||
| e8108e5066 | |||
| a9778ad460 | |||
| aba423d425 | |||
| 30e4efd062 | |||
| 19f316f768 | |||
| 9ac4e2bef1 | |||
| 2b76f558c1 | |||
| 0ee6400d5e | |||
| fd264b0583 | |||
| 8a756eae7b | |||
| c1c8485cb4 | |||
| c372f482a2 | |||
| fa7f4ba7a7 | |||
| 272e92ba7f | |||
| c6c501c769 | |||
| de3df54f80 | |||
| 27a7fac22e | |||
| fff0066392 | |||
| 0e2235dc75 | |||
| 6a8c22d5c3 | |||
| 6c5f31e7a5 | |||
| cd0167d6b8 | |||
| 1f7147d24b | |||
| ccaa3059e8 | |||
| b0b1ce9453 | |||
| 98d24e04f4 | |||
| a385c3ec99 | |||
| 920e36f6ba | |||
| dc9b364d6f | |||
| 95360b5df6 | |||
| 701d5f0bf0 | |||
| 266ebbcb88 | |||
| e41ef929d2 | |||
| c28efea0b3 | |||
| 00b609b498 | |||
| 2cfa78ab40 | |||
| b5583b88fa | |||
| 5c1dc5388c | |||
| fce9ad4e1b | |||
| febafb7cb8 | |||
| 5b6e39b2b8 | |||
| f5d825e77f | |||
| 04f73e5a89 | |||
| 65328d9716 | |||
| 79a141ce9d | |||
| 78adbeaab1 | |||
| dc151d2b5a | |||
| 23949682c1 | |||
| 0aaa89042a | |||
| b37f56f478 | |||
| 5055e842cf | |||
| c22d671409 | |||
| 9e764f3e49 | |||
| 8582e25571 | |||
| a77fc4c0bb | |||
| a3e690da32 | |||
| 7b37688ca8 | |||
| fa4a95c1dd | |||
| fb681bb0ea | |||
| 98a67d93f3 | |||
| 5fa1edeee0 | |||
| b72cb10ae6 | |||
| 4217a354f5 | |||
| 0c54d6a037 | |||
| 6c5fd3e86d | |||
| 2296357eaf | |||
| 39329bc5b9 | |||
| 33981b9400 | |||
| 2708853971 | |||
| 2ce20c872e | |||
| ae273a3e7b | |||
| 0d258ff7b1 | |||
| ae5cbbbec8 | |||
| e1dbc6ef04 | |||
| 49c0b2f333 | |||
| 0ad888867f | |||
| e9a5ac6d7a | |||
| 408cbf0dcb | |||
| 808f210c0d | |||
| 69cf3b2766 | |||
| ec8665d114 | |||
| 05036d3ae1 | |||
| 159b045ad7 | |||
| ee3f643c5e | |||
| d44a6fcf8b | |||
| 2cc7aedd28 | |||
| ac6e41d676 | |||
| 340f9b9e45 | |||
| 726f188aa4 | |||
| e70cf014ad | |||
| 0d6a924f94 | |||
| 4224fa5deb | |||
| b9a7ee6deb | |||
| d6eea4ef81 | |||
| 9c1f3650f2 | |||
| da5151abf6 | |||
| f986e8e588 | |||
| 959b7ab0b4 | |||
| 42cb6d66cf | |||
| 209644c177 | |||
| cf477316ed | |||
| 986ec16ecc | |||
| 2c41ed0473 | |||
| fcc28133c5 | |||
| 37d07617d1 | |||
| bfeb60c400 | |||
| de6746d67a | |||
| 78f1acc5ff | |||
| 67968d9b33 | |||
| c004fb5fc6 | |||
| ef439017ca | |||
| fb63ebd4cd | |||
| 0f46451c1d | |||
| 663635d124 | |||
| 4d69e9f2af | |||
| d23f722228 | |||
| e9767dc4e8 | |||
| 2b069eb3a3 | |||
| 36db66bd12 | |||
| 4b1ca7bdf6 | |||
| 0a605d1bb3 | |||
| 04de824ead | |||
| 115ad05af5 | |||
| ee7ea0011c | |||
| a2c7ddf5d9 | |||
| a7436ebacb | |||
| e797b09590 | |||
| 2fca4d02a1 | |||
| c17002aa73 | |||
| ae431bacf8 | |||
| 425e7cb367 | |||
| 453555619e | |||
| 0743b5982c | |||
| 795b7e1809 | |||
| c5bc634015 | |||
| e6c83d0665 | |||
| aac8fcb4b6 | |||
| abf3aa23de | |||
| 06e7d986d2 | |||
| d436099477 | |||
| 74fc01da7e | |||
| 80e9edcb29 | |||
| 17ca3a4493 | |||
| e5a0aec661 | |||
| 8cec2cc291 | |||
| 027a566e09 | |||
| 9a29a753e8 | |||
| cb2bd8076d | |||
| 1637edf8ca | |||
| 72d69ef6ad | |||
| 1470210523 | |||
| 0b19a0ae27 | |||
| 3ab685475c | |||
| e66d58e6de | |||
| e331fc2a21 | |||
| 2a65633517 | |||
| 7a388cb1a6 | |||
| 461dce3851 | |||
| cfe358b570 | |||
| caa875505e | |||
| 462025d8e6 |
+149
@@ -0,0 +1,149 @@
|
||||
# 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 2014-2018.
|
||||
|
||||
#
|
||||
# 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 #9
|
||||
|
||||
sudo: false
|
||||
language: cpp
|
||||
os: linux
|
||||
|
||||
env:
|
||||
global:
|
||||
# Autodetect Boost branch by using the following code: - BOOST_BRANCH=$TRAVIS_BRANCH
|
||||
# or just directly specify it
|
||||
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
|
||||
|
||||
# Files, which coverage results must be ignored (files from other projects).
|
||||
# Example: - IGNORE_COVERAGE='*/boost/progress.hpp */filesystem/src/*'
|
||||
- IGNORE_COVERAGE=''
|
||||
|
||||
# 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 - BOOST_LIBS_FOLDER=$(basename $TRAVIS_BUILD_DIR)
|
||||
- BOOST_LIBS_FOLDER=$(basename $TRAVIS_BUILD_DIR)
|
||||
|
||||
# Global options for sanitizers
|
||||
- UBSAN_OPTIONS=print_stacktrace=1
|
||||
- LSAN_OPTIONS=verbosity=1:log_threads=1
|
||||
|
||||
# `--coverage` flags required to generate coverage info for Coveralls
|
||||
matrix:
|
||||
include:
|
||||
- env: B2_ARGS='cxxstd=98,03,11,14,1z toolset=gcc-8 cxxflags="--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined -DBOOST_TRAVISCI_BUILD" linkflags="--coverage -lasan -lubsan"'
|
||||
name: "GCC-8"
|
||||
sudo: required # Required by leak sanitizer
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-8
|
||||
|
||||
- env: B2_ARGS='cxxstd=98,0x toolset=gcc-4.6 cxxflags="--coverage -DBOOST_TRAVISCI_BUILD" linkflags="--coverage"'
|
||||
name: "GCC-4.6"
|
||||
addons:
|
||||
apt:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: g++-4.6
|
||||
|
||||
# - env: B2_ARGS='cxxstd=98,03,11,14,1y toolset=gcc-8 cxxflags="--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined -DBOOST_TRAVISCI_BUILD -fno-exceptions" linkflags="--coverage -lasan -lubsan"'
|
||||
# name: "GCC-8, no exceptions"
|
||||
# sudo: required # Required by leak sanitizer
|
||||
# addons:
|
||||
# apt:
|
||||
# sources: ubuntu-toolchain-r-test
|
||||
# packages: g++-8
|
||||
|
||||
- env: B2_ARGS='cxxstd=98,03,11,14,1z toolset=clang-7 cxxflags="--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined -DBOOST_TRAVISCI_BUILD" linkflags="--coverage -fsanitize=address,leak,undefined"'
|
||||
name: "Clang-7"
|
||||
sudo: required # Required by leak sanitizer
|
||||
addons:
|
||||
apt:
|
||||
sources: llvm-toolchain-trusty-7
|
||||
packages: clang++-7
|
||||
|
||||
- env: B2_ARGS='cxxstd=03,11,14 toolset=clang-libc++ cxxflags="--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined -DBOOST_TRAVISCI_BUILD" linkflags="--coverage -fsanitize=address,leak,undefined"'
|
||||
name: "Clang-3.8, libc++"
|
||||
sudo: required # Required by leak sanitizer
|
||||
addons:
|
||||
apt:
|
||||
packages: libc++-dev
|
||||
|
||||
###############################################################################################################
|
||||
# From this point and below code is same for all the Boost libs
|
||||
###############################################################################################################
|
||||
|
||||
# Installing additional tools
|
||||
addons:
|
||||
apt:
|
||||
sources: git-core
|
||||
packages:
|
||||
- git
|
||||
- python-yaml
|
||||
|
||||
before_install:
|
||||
# Cloning minimal set of Boost libraries
|
||||
- BOOST=$HOME/boost-local
|
||||
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git $BOOST
|
||||
- cd $BOOST
|
||||
- git submodule update --init --depth 1 tools/build tools/boostdep
|
||||
|
||||
# Replacing Boost module with this project and installing Boost dependencies
|
||||
- echo "Testing $BOOST/libs/$BOOST_LIBS_FOLDER moved from $TRAVIS_BUILD_DIR, branch $BOOST_BRANCH"
|
||||
- rm -rf $BOOST/libs/$BOOST_LIBS_FOLDER || true
|
||||
- mv $TRAVIS_BUILD_DIR $BOOST/libs/$BOOST_LIBS_FOLDER
|
||||
- python tools/boostdep/depinst/depinst.py --git_args "--depth 1 --jobs 2" $BOOST_LIBS_FOLDER
|
||||
- git status
|
||||
|
||||
# Adding missing toolsets and preparing Boost headers
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
- |-
|
||||
echo "using gcc ;" >> ~/user-config.jam
|
||||
echo "using clang ;" >> ~/user-config.jam
|
||||
echo "using clang : 3.8 : clang++-3.8 ;" >> ~/user-config.jam
|
||||
echo "using clang : 4 : clang++-4.0 ;" >> ~/user-config.jam
|
||||
echo "using clang : 5 : clang++-5.0 ;" >> ~/user-config.jam
|
||||
echo "using clang : 6 : clang++-6.0 ;" >> ~/user-config.jam
|
||||
echo "using clang : 7 : clang++-7 ;" >> ~/user-config.jam
|
||||
echo "using clang : 8 : clang++-8 ;" >> ~/user-config.jam
|
||||
echo "using clang : libc++ : clang++-libc++ ;" >> ~/user-config.jam
|
||||
- cd $BOOST/libs/$BOOST_LIBS_FOLDER/test/
|
||||
|
||||
script:
|
||||
- sh -c "../../../b2 -j2 $B2_ARGS"
|
||||
|
||||
after_success:
|
||||
# Copying Coveralls data to a separate folder
|
||||
- mkdir -p $TRAVIS_BUILD_DIR/coverals
|
||||
- find ../../../bin.v2/ -name "*.gcda" -exec cp "{}" $TRAVIS_BUILD_DIR/coverals/ \;
|
||||
- find ../../../bin.v2/ -name "*.gcno" -exec cp "{}" $TRAVIS_BUILD_DIR/coverals/ \;
|
||||
- find ../../../bin.v2/ -name "*.da" -exec cp "{}" $TRAVIS_BUILD_DIR/coverals/ \;
|
||||
- find ../../../bin.v2/ -name "*.no" -exec cp "{}" $TRAVIS_BUILD_DIR/coverals/ \;
|
||||
- wget https://github.com/linux-test-project/lcov/archive/v1.12.zip
|
||||
- unzip v1.12.zip
|
||||
- LCOV="`pwd`/lcov-1.12/bin/lcov --gcov-tool gcov-6"
|
||||
|
||||
# Preparing Coveralls data by changind data format to a readable one
|
||||
- echo "$LCOV --directory $TRAVIS_BUILD_DIR/coverals --base-directory `pwd` --capture --output-file $TRAVIS_BUILD_DIR/coverals/coverage.info"
|
||||
- $LCOV --directory $TRAVIS_BUILD_DIR/coverals --base-directory `pwd` --capture --output-file $TRAVIS_BUILD_DIR/coverals/coverage.info
|
||||
|
||||
# ... erasing /test/ /example/ folder data
|
||||
- cd $BOOST
|
||||
- $LCOV --remove $TRAVIS_BUILD_DIR/coverals/coverage.info "/usr*" "*/$BOOST_LIBS_FOLDER/test/*" $IGNORE_COVERAGE "*/$BOOST_LIBS_FOLDER/tests/*" "*/$BOOST_LIBS_FOLDER/examples/*" "*/$BOOST_LIBS_FOLDER/example/*" -o $TRAVIS_BUILD_DIR/coverals/coverage.info
|
||||
|
||||
# ... erasing data that is not related to this project directly
|
||||
- OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$BOOST_LIBS_FOLDER\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
|
||||
- echo $OTHER_LIBS
|
||||
- eval "$LCOV --remove $TRAVIS_BUILD_DIR/coverals/coverage.info $OTHER_LIBS -o $TRAVIS_BUILD_DIR/coverals/coverage.info"
|
||||
|
||||
# Sending data to Coveralls
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- gem install coveralls-lcov
|
||||
- coveralls-lcov coverals/coverage.info
|
||||
@@ -0,0 +1,24 @@
|
||||
# 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
|
||||
#
|
||||
# NOTE: CMake support for Boost.Conversion is currently experimental at best
|
||||
# and the interface is likely to change in the future
|
||||
|
||||
cmake_minimum_required( VERSION 3.5 )
|
||||
project( BoostConversion 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::smart_ptr
|
||||
Boost::throw_exception
|
||||
Boost::type_traits
|
||||
Boost::typeof
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
# [Boost.Conversion](http://boost.org/libs/conversion)
|
||||
Boost.Conversion is one of the [Boost C++ Libraries](http://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://travis-ci.org/apolukhin/conversion) [](https://ci.appveyor.com/project/apolukhin/conversion/branch/develop) | [](https://coveralls.io/r/apolukhin/conversion?branch=develop) | [details...](http://www.boost.org/development/tests/develop/developer/conversion.html)
|
||||
Master branch: | [](https://travis-ci.org/apolukhin/conversion) [](https://ci.appveyor.com/project/apolukhin/conversion/branch/master) | [](https://coveralls.io/r/apolukhin/conversion?branch=master) | [details...](http://www.boost.org/development/tests/master/developer/conversion.html)
|
||||
|
||||
|
||||
[Open Issues](https://svn.boost.org/trac/boost/query?status=!closed&component=conversion&or&status=!closed&component=lexical_cast)
|
||||
|
||||
### License
|
||||
|
||||
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
|
||||
@@ -1,202 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
|
||||
<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/cast.hpp Documentation</title>
|
||||
</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/cast.hpp">boost/cast.hpp</a></h1>
|
||||
|
||||
<h2><a name="Cast Functions">Cast Functions</a></h2>
|
||||
|
||||
<p>The header <a href="../../boost/cast.hpp">boost/cast.hpp</a> provides
|
||||
<a href="#Polymorphic_cast"><b>polymorphic_cast</b></a>, <a href=
|
||||
"#Polymorphic_cast"><b>polymorphic_downcast</b></a>, and <a href=
|
||||
"#numeric_cast"><b>numeric_cast</b></a> function templates designed to
|
||||
complement the C++ built-in casts.</p>
|
||||
|
||||
<p>The program <a href="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 <b>Y</b> 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 <b>static_cast</b> 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 <b>polymorphic_downcast</b> template retains
|
||||
the efficiency of <b>static_cast</b> for non-debug compilations, but for
|
||||
debug compilations adds safety via an assert() that a <b>dynamic_cast</b>
|
||||
succeeds.</p>
|
||||
|
||||
<p>The C++ built-in <b>dynamic_cast</b> 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 <b>dynamic_cast</b>, 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 <b>polymorphic_cast</b>
|
||||
template performs a <b>dynamic_cast</b> on a pointer, and throws an
|
||||
exception if the <b>dynamic_cast</b> returns 0.</p>
|
||||
|
||||
<p>A <b>polymorphic_downcast</b> is preferred when debug-mode tests will
|
||||
cover 100% of the object types possibly cast and when non-debug-mode
|
||||
efficiency is an issue. If these two conditions are not present,
|
||||
<b>polymorphic_cast</b> is preferred. It must also be used for
|
||||
crosscasts. It does an assert( dynamic_cast<Derived>(x) == x )
|
||||
where x is the base pointer, ensuring that not only is a non-zero pointer
|
||||
returned, but also that it correct in the presence of multiple
|
||||
inheritance. <b>Warning:</b>: Because <b>polymorphic_downcast</b> uses
|
||||
assert(), it violates the one definition rule (ODR) if NDEBUG is
|
||||
inconsistently defined across translation units. [See ISO Std 3.2]</p>
|
||||
|
||||
<p>The C++ built-in <b>dynamic_cast</b> 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/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><a name="numeric_cast">numeric_cast</a></h3>
|
||||
|
||||
<p>A <b>static_cast</b> or implicit conversion will not detect failure to
|
||||
preserve range for numeric casts. The <b>numeric_cast</b> function
|
||||
templates are similar to <b>static_cast</b> and certain (dubious)
|
||||
implicit conversions in this respect, except that they detect loss of
|
||||
numeric range. An exception is thrown when a runtime value-preservation
|
||||
check fails.</p>
|
||||
|
||||
<p>The requirements on the argument and result types are:</p>
|
||||
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li>Both argument and result types are CopyConstructible [ISO Std
|
||||
20.1.3].</li>
|
||||
|
||||
<li>Both argument and result types are Numeric, defined by
|
||||
<code>std::numeric_limits<>::is_specialized</code> being
|
||||
true.</li>
|
||||
|
||||
<li>The argument can be converted to the result type using
|
||||
<b>static_cast</b>.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
|
||||
<h3>numeric_cast synopsis</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
namespace boost {
|
||||
|
||||
class bad_numeric_cast : public std::bad_cast {...};
|
||||
|
||||
template<typename Target, typename Source>
|
||||
inline Target numeric_cast(Source arg);
|
||||
// Throws: bad_numeric_cast unless, in converting arg from Source to Target,
|
||||
// there is no loss of negative range, and no underflow, and no
|
||||
// overflow, as determined by std::numeric_limits
|
||||
// Returns: static_cast<Target>(arg)
|
||||
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>numeric_cast example</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <boost/cast.hpp>
|
||||
using namespace boost::cast;
|
||||
|
||||
void ariane(double vx)
|
||||
{
|
||||
...
|
||||
unsigned short dx = numeric_cast<unsigned short>(vx);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>numeric_cast rationale</h3>
|
||||
|
||||
<p>The form of the throws condition is specified so that != is not a
|
||||
required operation.</p>
|
||||
|
||||
<h3>History</h3>
|
||||
|
||||
<p><b>polymorphic_cast</b> was suggested by Bjarne Stroustrup in "The C++
|
||||
Programming Language".<br>
|
||||
<b>polymorphic_downcast</b> was contributed by <a href=
|
||||
"../../people/dave_abrahams.htm">Dave Abrahams</a>.<b><br>
|
||||
numeric_cast</b> was contributed by <a href=
|
||||
"../../people/kevlin_henney.htm">Kevlin Henney</a>.</p>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
|
||||
-->06 January, 2001
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="38320"
|
||||
--></p>
|
||||
|
||||
<p>© Copyright boost.org 1999. Permission to copy, use, modify, sell
|
||||
and distribute this document is granted provided this copyright notice
|
||||
appears in all copies. This document is provided "as is" without express
|
||||
or implied warranty, and with no claim as to its suitability for any
|
||||
purpose.</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,197 @@
|
||||
[/
|
||||
Copyright 2016 Mikhail Maximov.
|
||||
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.6]
|
||||
[authors [Stroustrup, Bjarne], [Abrahams, Dave], [Rasin, Boris], [Polukhin, Antony]]
|
||||
[copyright 2001 Beman Dawes, 2014-2019 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 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<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]
|
||||
|
||||
[#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.
|
||||
|
||||
[#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.
|
||||
|
||||
[endsect]
|
||||
[section `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)
|
||||
|
||||
}
|
||||
```
|
||||
[endsect]
|
||||
[section `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);
|
||||
...
|
||||
}
|
||||
```
|
||||
[endsect]
|
||||
[section `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);
|
||||
...
|
||||
}
|
||||
```
|
||||
[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]
|
||||
@@ -1,384 +0,0 @@
|
||||
// boost cast.hpp header file ----------------------------------------------//
|
||||
|
||||
// (C) Copyright Kevlin Henney and Dave Abrahams 1999.
|
||||
// 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.
|
||||
|
||||
// Revision History
|
||||
// 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
|
||||
// any case, so we loose nothing). (John Maddock)
|
||||
// 21 Jan 01 Undid a bug I introduced yesterday. numeric_cast<> never
|
||||
// worked with stock GCC; trying to get it to do that broke
|
||||
// vc-stlport.
|
||||
// 20 Jan 01 Moved BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS to config.hpp.
|
||||
// Removed unused BOOST_EXPLICIT_TARGET macro. Moved
|
||||
// boost::detail::type to boost/type.hpp. Made it compile with
|
||||
// stock gcc again (Dave Abrahams)
|
||||
// 29 Nov 00 Remove nested namespace cast, cleanup spacing before Formal
|
||||
// Review (Beman Dawes)
|
||||
// 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)
|
||||
// 28 Jun 00 Removed implicit_cast<>. See comment below. (Beman Dawes)
|
||||
// 27 Jun 00 More MSVC6 workarounds
|
||||
// 15 Jun 00 Add workarounds for MSVC6
|
||||
// 2 Feb 00 Remove bad_numeric_cast ";" syntax error (Doncho Angelov)
|
||||
// 26 Jan 00 Add missing throw() to bad_numeric_cast::what(0 (Adam Levar)
|
||||
// 29 Dec 99 Change using declarations so usages in other namespaces work
|
||||
// correctly (Dave Abrahams)
|
||||
// 23 Sep 99 Change polymorphic_downcast assert to also detect M.I. errors
|
||||
// as suggested Darin Adler and improved by Valentin Bonnard.
|
||||
// 2 Sep 99 Remove controversial asserts, simplify, rename.
|
||||
// 30 Aug 99 Move to cast.hpp, replace value_cast with numeric_cast,
|
||||
// place in nested namespace.
|
||||
// 3 Aug 99 Initial version
|
||||
|
||||
#ifndef BOOST_CAST_HPP
|
||||
#define BOOST_CAST_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <cassert>
|
||||
# include <typeinfo>
|
||||
# include <boost/type.hpp>
|
||||
# include <boost/limits.hpp>
|
||||
# include <boost/detail/select_type.hpp>
|
||||
|
||||
// It has been demonstrated numerous times that MSVC 6.0 fails silently at link
|
||||
// time if you use a template function which has template parameters that don't
|
||||
// appear in the function's argument list.
|
||||
//
|
||||
// TODO: Add this to config.hpp?
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 // 1200 = VC6
|
||||
# define BOOST_EXPLICIT_DEFAULT_TARGET , ::boost::type<Target>* = 0
|
||||
# else
|
||||
# define BOOST_EXPLICIT_DEFAULT_TARGET
|
||||
# endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// See the documentation for descriptions of how to choose between
|
||||
// static_cast<>, dynamic_cast<>, polymorphic_cast<> and polymorphic_downcast<>
|
||||
|
||||
// polymorphic_cast --------------------------------------------------------//
|
||||
|
||||
// Runtime checked polymorphic downcasts and crosscasts.
|
||||
// Suggested in The C++ Programming Language, 3rd Ed, Bjarne Stroustrup,
|
||||
// section 15.8 exercise 1, page 425.
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target polymorphic_cast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
|
||||
{
|
||||
Target tmp = dynamic_cast<Target>(x);
|
||||
if ( tmp == 0 ) throw std::bad_cast();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// polymorphic_downcast ----------------------------------------------------//
|
||||
|
||||
// assert() checked polymorphic downcast. Crosscasts prohibited.
|
||||
|
||||
// WARNING: Because this cast uses assert(), it violates the One Definition
|
||||
// Rule if NDEBUG is inconsistently defined across translation units.
|
||||
|
||||
// Contributed by Dave Abrahams
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
|
||||
{
|
||||
assert( dynamic_cast<Target>(x) == x ); // detect logic error
|
||||
return static_cast<Target>(x);
|
||||
}
|
||||
|
||||
// implicit_cast -----------------------------------------------------------//
|
||||
//
|
||||
// Removed due to uncertain purpose. Use either numeric_cast (see below)
|
||||
// or static_cast according to the need.
|
||||
|
||||
// numeric_cast and related exception --------------------------------------//
|
||||
|
||||
// Contributed by Kevlin Henney
|
||||
|
||||
// bad_numeric_cast --------------------------------------------------------//
|
||||
|
||||
// exception used to indicate runtime numeric_cast failure
|
||||
class bad_numeric_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
// constructors, destructors and assignment operator defaulted
|
||||
|
||||
// function inlined for brevity and consistency with rest of library
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return "bad numeric cast: loss of range in numeric_cast";
|
||||
}
|
||||
};
|
||||
|
||||
// numeric_cast ------------------------------------------------------------//
|
||||
|
||||
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_SGI_CPP_LIMITS)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct signed_numeric_limits : std::numeric_limits<T>
|
||||
{
|
||||
static inline T min BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{
|
||||
return (std::numeric_limits<T>::min)() >= 0
|
||||
// unary minus causes integral promotion, thus the static_cast<>
|
||||
? static_cast<T>(-(std::numeric_limits<T>::max)())
|
||||
: (std::numeric_limits<T>::min)();
|
||||
};
|
||||
};
|
||||
|
||||
// Move to namespace boost in utility.hpp?
|
||||
template <class T, bool specialized>
|
||||
struct fixed_numeric_limits_base
|
||||
: public if_true< std::numeric_limits<T>::is_signed >
|
||||
::BOOST_NESTED_TEMPLATE then< signed_numeric_limits<T>,
|
||||
std::numeric_limits<T>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct fixed_numeric_limits
|
||||
: fixed_numeric_limits_base<T,(std::numeric_limits<T>::is_specialized)>
|
||||
{};
|
||||
|
||||
# ifdef BOOST_HAS_LONG_LONG
|
||||
// cover implementations which supply no specialization for long
|
||||
// long / unsigned long long. Not intended to be full
|
||||
// numeric_limits replacements, but good enough for numeric_cast<>
|
||||
template <>
|
||||
struct fixed_numeric_limits_base< ::boost::long_long_type, false>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_signed = true);
|
||||
static ::boost::long_long_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{
|
||||
# ifdef LONGLONG_MAX
|
||||
return LONGLONG_MAX;
|
||||
# else
|
||||
return 9223372036854775807LL; // hope this is portable
|
||||
# endif
|
||||
}
|
||||
|
||||
static ::boost::long_long_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{
|
||||
# ifdef LONGLONG_MIN
|
||||
return LONGLONG_MIN;
|
||||
# else
|
||||
return -( 9223372036854775807LL )-1; // hope this is portable
|
||||
# endif
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct fixed_numeric_limits_base< ::boost::ulong_long_type, false>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_signed = false);
|
||||
static ::boost::ulong_long_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{
|
||||
# ifdef ULONGLONG_MAX
|
||||
return ULONGLONG_MAX;
|
||||
# else
|
||||
return 0xffffffffffffffffULL; // hope this is portable
|
||||
# endif
|
||||
}
|
||||
|
||||
static ::boost::ulong_long_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
|
||||
};
|
||||
# endif
|
||||
} // namespace detail
|
||||
|
||||
// less_than_type_min -
|
||||
// x_is_signed should be numeric_limits<X>::is_signed
|
||||
// y_is_signed should be numeric_limits<Y>::is_signed
|
||||
// y_min should be numeric_limits<Y>::min()
|
||||
//
|
||||
// check(x, y_min) returns true iff x < y_min without invoking comparisons
|
||||
// between signed and unsigned values.
|
||||
//
|
||||
// "poor man's partial specialization" is in use here.
|
||||
template <bool x_is_signed, bool y_is_signed>
|
||||
struct less_than_type_min
|
||||
{
|
||||
template <class X, class Y>
|
||||
static bool check(X x, Y y_min)
|
||||
{ return x < y_min; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct less_than_type_min<false, true>
|
||||
{
|
||||
template <class X, class Y>
|
||||
static bool check(X, Y)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct less_than_type_min<true, false>
|
||||
{
|
||||
template <class X, class Y>
|
||||
static bool check(X x, Y)
|
||||
{ return x < 0; }
|
||||
};
|
||||
|
||||
// greater_than_type_max -
|
||||
// same_sign should be:
|
||||
// numeric_limits<X>::is_signed == numeric_limits<Y>::is_signed
|
||||
// y_max should be numeric_limits<Y>::max()
|
||||
//
|
||||
// check(x, y_max) returns true iff x > y_max without invoking comparisons
|
||||
// between signed and unsigned values.
|
||||
//
|
||||
// "poor man's partial specialization" is in use here.
|
||||
template <bool same_sign, bool x_is_signed>
|
||||
struct greater_than_type_max;
|
||||
|
||||
template<>
|
||||
struct greater_than_type_max<true, true>
|
||||
{
|
||||
template <class X, class Y>
|
||||
static inline bool check(X x, Y y_max)
|
||||
{ return x > y_max; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct greater_than_type_max<false, true>
|
||||
{
|
||||
// What does the standard say about this? I think it's right, and it
|
||||
// will work with every compiler I know of.
|
||||
template <class X, class Y>
|
||||
static inline bool check(X x, Y)
|
||||
{ return x >= 0 && static_cast<X>(static_cast<Y>(x)) != x; }
|
||||
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200
|
||||
// MSVC6 can't static_cast unsigned __int64 -> floating types
|
||||
# define BOOST_UINT64_CAST(src_type) \
|
||||
static inline bool check(src_type x, unsigned __int64) \
|
||||
{ \
|
||||
if (x < 0) return false; \
|
||||
unsigned __int64 y = static_cast<unsigned __int64>(x); \
|
||||
bool odd = y & 0x1; \
|
||||
__int64 div2 = static_cast<__int64>(y >> 1); \
|
||||
return ((static_cast<src_type>(div2) * 2.0) + odd) != x; \
|
||||
}
|
||||
|
||||
BOOST_UINT64_CAST(long double);
|
||||
BOOST_UINT64_CAST(double);
|
||||
BOOST_UINT64_CAST(float);
|
||||
# undef BOOST_UINT64_CAST
|
||||
# endif
|
||||
};
|
||||
|
||||
template<>
|
||||
struct greater_than_type_max<true, false>
|
||||
{
|
||||
template <class X, class Y>
|
||||
static inline bool check(X x, Y y_max)
|
||||
{ return x > y_max; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct greater_than_type_max<false, false>
|
||||
{
|
||||
// What does the standard say about this? I think it's right, and it
|
||||
// will work with every compiler I know of.
|
||||
template <class X, class Y>
|
||||
static inline bool check(X x, Y)
|
||||
{ return static_cast<X>(static_cast<Y>(x)) != x; }
|
||||
};
|
||||
|
||||
#else // use #pragma hacks if available
|
||||
|
||||
namespace detail
|
||||
{
|
||||
# if BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4018)
|
||||
# pragma warning(disable : 4146)
|
||||
#elif defined(__BORLANDC__)
|
||||
# pragma option push -w-8041
|
||||
# endif
|
||||
|
||||
// Move to namespace boost in utility.hpp?
|
||||
template <class T>
|
||||
struct fixed_numeric_limits : public std::numeric_limits<T>
|
||||
{
|
||||
static inline T min BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{
|
||||
return std::numeric_limits<T>::is_signed && (std::numeric_limits<T>::min)() >= 0
|
||||
? T(-(std::numeric_limits<T>::max)()) : (std::numeric_limits<T>::min)();
|
||||
}
|
||||
};
|
||||
|
||||
# if BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#elif defined(__BORLANDC__)
|
||||
# pragma option pop
|
||||
# endif
|
||||
} // namespace detail
|
||||
|
||||
#endif
|
||||
|
||||
template<typename Target, typename Source>
|
||||
inline Target numeric_cast(Source arg BOOST_EXPLICIT_DEFAULT_TARGET)
|
||||
{
|
||||
// typedefs abbreviating respective trait classes
|
||||
typedef detail::fixed_numeric_limits<Source> arg_traits;
|
||||
typedef detail::fixed_numeric_limits<Target> result_traits;
|
||||
|
||||
#if defined(BOOST_STRICT_CONFIG) \
|
||||
|| (!defined(__HP_aCC) || __HP_aCC > 33900) \
|
||||
&& (!defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) \
|
||||
|| defined(BOOST_SGI_CPP_LIMITS))
|
||||
// typedefs that act as compile time assertions
|
||||
// (to be replaced by boost compile time assertions
|
||||
// as and when they become available and are stable)
|
||||
typedef bool argument_must_be_numeric[arg_traits::is_specialized];
|
||||
typedef bool result_must_be_numeric[result_traits::is_specialized];
|
||||
|
||||
const bool arg_is_signed = arg_traits::is_signed;
|
||||
const bool result_is_signed = result_traits::is_signed;
|
||||
const bool same_sign = arg_is_signed == result_is_signed;
|
||||
|
||||
if (less_than_type_min<arg_is_signed, result_is_signed>::check(arg, (result_traits::min)())
|
||||
|| greater_than_type_max<same_sign, arg_is_signed>::check(arg, (result_traits::max)())
|
||||
)
|
||||
|
||||
#else // We need to use #pragma hacks if available
|
||||
|
||||
# if BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4018)
|
||||
#elif defined(__BORLANDC__)
|
||||
#pragma option push -w-8012
|
||||
# endif
|
||||
if ((arg < 0 && !result_traits::is_signed) // loss of negative range
|
||||
|| (arg_traits::is_signed && arg < (result_traits::min)()) // underflow
|
||||
|| arg > (result_traits::max)()) // overflow
|
||||
# if BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#elif defined(__BORLANDC__)
|
||||
#pragma option pop
|
||||
# endif
|
||||
#endif
|
||||
{
|
||||
throw bad_numeric_cast();
|
||||
}
|
||||
return static_cast<Target>(arg);
|
||||
} // numeric_cast
|
||||
|
||||
# undef BOOST_EXPLICIT_DEFAULT_TARGET
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_CAST_HPP
|
||||
Executable → Regular
+11
-10
@@ -5,17 +5,24 @@
|
||||
#ifndef IMPLICIT_CAST_DWA200356_HPP
|
||||
# define IMPLICIT_CAST_DWA200356_HPP
|
||||
|
||||
# include <boost/mpl/identity.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T> struct icast_identity
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// implementation originally suggested by C. Green in
|
||||
// http://lists.boost.org/MailArchives/boost/msg00886.php
|
||||
|
||||
// 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 mpl::identity<T>::type x) {
|
||||
inline T implicit_cast (typename boost::detail::icast_identity<T>::type x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -23,13 +30,7 @@ inline T implicit_cast (typename mpl::identity<T>::type x) {
|
||||
//template <typename T>
|
||||
//void implicit_cast (...);
|
||||
|
||||
// Macro for when you need a constant expression (Gennaro Prota)
|
||||
#define BOOST_IMPLICIT_CAST(dst_type, expr) \
|
||||
( sizeof( implicit_cast<dst_type>(expr) ) \
|
||||
, \
|
||||
static_cast<dst_type>(expr) \
|
||||
)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // IMPLICIT_CAST_DWA200356_HPP
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
#ifndef BOOST_LEXICAL_CAST_INCLUDED
|
||||
#define BOOST_LEXICAL_CAST_INCLUDED
|
||||
|
||||
// Boost lexical_cast.hpp header -------------------------------------------//
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
// See end of this header for rights and permissions.
|
||||
//
|
||||
// what: lexical_cast custom keyword cast
|
||||
// who: contributed by Kevlin Henney,
|
||||
// enhanced with contributions from Terje Slettebø,
|
||||
// with additional fixes and suggestions from Gennaro Prota,
|
||||
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
|
||||
// and other Boosters
|
||||
// when: November 2000, March 2003
|
||||
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
|
||||
#ifdef BOOST_NO_STRINGSTREAM
|
||||
#include <strstream>
|
||||
#else
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_STRINGSTREAM) || \
|
||||
defined(BOOST_NO_STD_WSTRING) || \
|
||||
defined(BOOST_NO_STD_LOCALE) || \
|
||||
defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
#define DISABLE_WIDE_CHAR_SUPPORT
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// exception used to indicate runtime lexical_cast failure
|
||||
class bad_lexical_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
bad_lexical_cast() :
|
||||
source(&typeid(void)), target(&typeid(void))
|
||||
{
|
||||
}
|
||||
bad_lexical_cast(
|
||||
const std::type_info &s,
|
||||
const std::type_info &t) :
|
||||
source(&s), target(&t)
|
||||
{
|
||||
}
|
||||
const std::type_info &source_type() const
|
||||
{
|
||||
return *source;
|
||||
}
|
||||
const std::type_info &target_type() const
|
||||
{
|
||||
return *target;
|
||||
}
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return "bad lexical cast: "
|
||||
"source type value could not be interpreted as target";
|
||||
}
|
||||
virtual ~bad_lexical_cast() throw()
|
||||
{
|
||||
}
|
||||
private:
|
||||
const std::type_info *source;
|
||||
const std::type_info *target;
|
||||
};
|
||||
|
||||
namespace detail // selectors for choosing stream character type
|
||||
{
|
||||
template<typename Type>
|
||||
struct stream_char
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
template<>
|
||||
struct stream_char<wchar_t>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stream_char<wchar_t *>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stream_char<const wchar_t *>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct stream_char<std::wstring>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename TargetChar, typename SourceChar>
|
||||
struct widest_char
|
||||
{
|
||||
typedef TargetChar type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct widest_char<char, wchar_t>
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
}
|
||||
|
||||
namespace detail // stream wrapper for handling lexical conversions
|
||||
{
|
||||
template<typename Target, typename Source>
|
||||
class lexical_stream
|
||||
{
|
||||
public:
|
||||
lexical_stream()
|
||||
{
|
||||
stream.unsetf(std::ios::skipws);
|
||||
|
||||
if(std::numeric_limits<Target>::is_specialized)
|
||||
stream.precision(std::numeric_limits<Target>::digits10 + 1);
|
||||
else if(std::numeric_limits<Source>::is_specialized)
|
||||
stream.precision(std::numeric_limits<Source>::digits10 + 1);
|
||||
}
|
||||
~lexical_stream()
|
||||
{
|
||||
#if defined(BOOST_NO_STRINGSTREAM)
|
||||
stream.freeze(false);
|
||||
#endif
|
||||
}
|
||||
bool operator<<(const Source &input)
|
||||
{
|
||||
return !(stream << input).fail();
|
||||
}
|
||||
template<typename InputStreamable>
|
||||
bool operator>>(InputStreamable &output)
|
||||
{
|
||||
return !is_pointer<InputStreamable>::value &&
|
||||
stream >> output &&
|
||||
(stream >> std::ws).eof();
|
||||
}
|
||||
bool operator>>(std::string &output)
|
||||
{
|
||||
#if defined(BOOST_NO_STRINGSTREAM)
|
||||
stream << '\0';
|
||||
#endif
|
||||
output = stream.str();
|
||||
return true;
|
||||
}
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
bool operator>>(std::wstring &output)
|
||||
{
|
||||
output = stream.str();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
typedef typename widest_char<
|
||||
typename stream_char<Target>::type,
|
||||
typename stream_char<Source>::type>::type char_type;
|
||||
|
||||
#if defined(BOOST_NO_STRINGSTREAM)
|
||||
std::strstream stream;
|
||||
#elif defined(BOOST_NO_STD_LOCALE)
|
||||
std::stringstream stream;
|
||||
#else
|
||||
std::basic_stringstream<char_type> stream;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Target, typename Source>
|
||||
Target lexical_cast(Source arg)
|
||||
{
|
||||
detail::lexical_stream<Target, Source> interpreter;
|
||||
Target result;
|
||||
|
||||
if(!(interpreter << arg && interpreter >> result))
|
||||
throw_exception(bad_lexical_cast(typeid(Target), typeid(Source)));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright Kevlin Henney, 2000-2003. All rights reserved.
|
||||
//
|
||||
// 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)
|
||||
|
||||
#undef DISABLE_WIDE_CHAR_SUPPORT
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
// 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)
|
||||
|
||||
// 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)
|
||||
// 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
|
||||
// any case, so we loose nothing). (John Maddock)
|
||||
// 21 Jan 01 Undid a bug I introduced yesterday. numeric_cast<> never
|
||||
// worked with stock GCC; trying to get it to do that broke
|
||||
// vc-stlport.
|
||||
// 20 Jan 01 Moved BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS to config.hpp.
|
||||
// Removed unused BOOST_EXPLICIT_TARGET macro. Moved
|
||||
// boost::detail::type to boost/type.hpp. Made it compile with
|
||||
// stock gcc again (Dave Abrahams)
|
||||
// 29 Nov 00 Remove nested namespace cast, cleanup spacing before Formal
|
||||
// Review (Beman Dawes)
|
||||
// 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)
|
||||
// 28 Jun 00 Removed implicit_cast<>. See comment below. (Beman Dawes)
|
||||
// 27 Jun 00 More MSVC6 workarounds
|
||||
// 15 Jun 00 Add workarounds for MSVC6
|
||||
// 2 Feb 00 Remove bad_numeric_cast ";" syntax error (Doncho Angelov)
|
||||
// 26 Jan 00 Add missing throw() to bad_numeric_cast::what(0 (Adam Levar)
|
||||
// 29 Dec 99 Change using declarations so usages in other namespaces work
|
||||
// correctly (Dave Abrahams)
|
||||
// 23 Sep 99 Change polymorphic_downcast assert to also detect M.I. errors
|
||||
// as suggested Darin Adler and improved by Valentin Bonnard.
|
||||
// 2 Sep 99 Remove controversial asserts, simplify, rename.
|
||||
// 30 Aug 99 Move to cast.hpp, replace value_cast with numeric_cast,
|
||||
// place in nested namespace.
|
||||
// 3 Aug 99 Initial version
|
||||
|
||||
#ifndef BOOST_POLYMORPHIC_CAST_HPP
|
||||
#define BOOST_POLYMORPHIC_CAST_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/assert.hpp>
|
||||
# include <boost/throw_exception.hpp>
|
||||
# include <typeinfo>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// See the documentation for descriptions of how to choose between
|
||||
// static_cast<>, dynamic_cast<>, polymorphic_cast<> and polymorphic_downcast<>
|
||||
|
||||
// polymorphic_cast --------------------------------------------------------//
|
||||
|
||||
// Runtime checked polymorphic downcasts and crosscasts.
|
||||
// Suggested in The C++ Programming Language, 3rd Ed, Bjarne Stroustrup,
|
||||
// section 15.8 exercise 1, page 425.
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target polymorphic_cast(Source* x)
|
||||
{
|
||||
Target tmp = dynamic_cast<Target>(x);
|
||||
if ( tmp == 0 ) boost::throw_exception( std::bad_cast() );
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// polymorphic_downcast ----------------------------------------------------//
|
||||
|
||||
// BOOST_ASSERT() checked 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 Dave Abrahams
|
||||
|
||||
template <class Target, class Source>
|
||||
inline Target polymorphic_downcast(Source* x)
|
||||
{
|
||||
BOOST_ASSERT( dynamic_cast<Target>(x) == x ); // detect logic error
|
||||
return static_cast<Target>(x);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_POLYMORPHIC_CAST_HPP
|
||||
@@ -0,0 +1,78 @@
|
||||
// boost polymorphic_pointer_cast.hpp header file ----------------------------------------------//
|
||||
// (C) Copyright Boris Rasin and Antony Polukhin 2014-2019.
|
||||
// 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>
|
||||
# include <boost/assert.hpp>
|
||||
# include <boost/pointer_cast.hpp>
|
||||
# include <boost/throw_exception.hpp>
|
||||
# include <boost/utility/declval.hpp>
|
||||
# ifdef BOOST_NO_CXX11_DECLTYPE
|
||||
# include <boost/typeof/typeof.hpp>
|
||||
# endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename Target, typename Source>
|
||||
struct dynamic_pointer_cast_result
|
||||
{
|
||||
#ifdef BOOST_NO_CXX11_DECLTYPE
|
||||
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, dynamic_pointer_cast<Target>(boost::declval<Source>()))
|
||||
typedef typename nested::type type;
|
||||
#else
|
||||
typedef decltype(dynamic_pointer_cast<Target>(boost::declval<Source>())) type;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Target, typename Source>
|
||||
inline typename detail::dynamic_pointer_cast_result<Target, Source>::type
|
||||
polymorphic_pointer_downcast (const Source& x)
|
||||
{
|
||||
BOOST_ASSERT(dynamic_pointer_cast<Target> (x) == x);
|
||||
return static_pointer_cast<Target> (x);
|
||||
}
|
||||
|
||||
template <typename Target, typename Source>
|
||||
inline typename detail::dynamic_pointer_cast_result<Target, Source>::type
|
||||
polymorphic_pointer_cast (const Source& x)
|
||||
{
|
||||
typename detail::dynamic_pointer_cast_result<Target, Source>::type 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
|
||||
+31
-35
@@ -1,39 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (c) 2016 Mikhail Maximov
|
||||
vigorous.activity at gmail dot com
|
||||
|
||||
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)
|
||||
-->
|
||||
<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 4.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>
|
||||
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, and <b> numeric_cast</b><i><></i> to perform safe casting
|
||||
between numeric types.<br>
|
||||
</li>
|
||||
<li>The <a href="lexical_cast.htm">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 -->06 January, 2001<!--webbot bot="Timestamp" endspan i-checksum="38320" -->
|
||||
</p>
|
||||
|
||||
<body>
|
||||
<p>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="../../doc/html/conversion.html">../../doc/html/conversion.html</a>
|
||||
</p>
|
||||
<p>
|
||||
© 2014 Antony Polukhin
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,223 +0,0 @@
|
||||
<!-- saved from url=(0022)http://internet.e-mail -->
|
||||
<!doctype html public "-//W3C//DTD HTML Transitional 4.0//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>lexical_cast</title>
|
||||
<meta name="author" content="Kevlin Henney, mailto:kevlin@curbralan.com">
|
||||
<meta name="generator" content="Microsoft FrontPage 4.0">
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" width="277" height="86">Header
|
||||
<a href="../../boost/lexical_cast.hpp">boost/lexical_cast.hpp</a></h1>
|
||||
<ul type="square">
|
||||
<li>
|
||||
<a href="#motivation">Motivation</a></li>
|
||||
<li>
|
||||
<a href="#examples">Examples</a></li>
|
||||
<li>
|
||||
<a href="#synopsis">Synopsis</a></li>
|
||||
<li>
|
||||
<a href="#lexical_cast"><code>lexical_cast</code></a></li>
|
||||
<li>
|
||||
<a href="#bad_lexical_cast"><code>bad_lexical_cast</code></a></li>
|
||||
<li>
|
||||
<a href="#changes">Changes</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2><a name="motivation">Motivation</a></h2>
|
||||
Sometimes a value must be converted to a literal text form, such as an <code>int</code>
|
||||
represented as a <code>string</code>, or vice-versa, when a <code>string</code>
|
||||
is interpreted as an <code>int</code>. Such examples are common when converting
|
||||
between data types internal to a program and representation external to a
|
||||
program, such as windows and configuration files.
|
||||
<p>
|
||||
The standard C and C++ libraries offer a number of facilities for performing
|
||||
such conversions. However, they vary with their ease of use, extensibility, and
|
||||
safety.
|
||||
<p>
|
||||
For instance, there are a number of limitations with the family of standard C
|
||||
functions typified by <code>atoi</code>:
|
||||
<ul type="square">
|
||||
<li>
|
||||
Conversion is supported in one direction only: from text to internal data type.
|
||||
Converting the other way using the C library requires either the inconvenience
|
||||
and compromised safety of the <code>sprintf</code> function, or the loss of
|
||||
portability associated with non-standard functions such as <code>itoa</code>.
|
||||
</li>
|
||||
<li>
|
||||
The range of types supported is only a subset of the built-in numeric types,
|
||||
namely <code>int</code>, <code>long</code>, and <code>double</code>.
|
||||
</li>
|
||||
<li>
|
||||
The range of types cannot be extended in a uniform manner. For instance,
|
||||
conversion from string representation to <code>complex</code> or <code>rational</code>.
|
||||
</li>
|
||||
</ul>
|
||||
The standard C functions typified by <code>strtol</code> have the same basic
|
||||
limitations, but offer finer control over the conversion process. However, for
|
||||
the common case such control is often either not required or not used. The <code>scanf</code>
|
||||
family of functions offer even greater control, but also lack safety and ease
|
||||
of use.
|
||||
<p>
|
||||
The standard C++ library offers <code>stringstream</code> for the kind of
|
||||
in-core formatting being discussed. It offers a great deal of control over the
|
||||
formatting and conversion of I/O to and from arbitrary types through text.
|
||||
However, for simple conversions direct use of <code>stringstream</code> can be
|
||||
either clumsy (with the introduction of extra local variables and the loss of
|
||||
infix-expression convenience) or obscure (where <code>stringstream</code>
|
||||
objects are created as temporary objects in an expression). Facets provide a
|
||||
comprehensive concept and facility for controlling textual representation, but
|
||||
their perceived complexity and high entry level requires an extreme degree of
|
||||
involvement for simple conversions, and excludes all but a few programmers.
|
||||
<p>
|
||||
The <code>lexical_cast</code> function template offers a convenient and
|
||||
consistent form for supporting common conversions to and from arbitrary types
|
||||
when they are represented as text. The simplification it offers is in
|
||||
expression-level convenience for such conversions. For more involved
|
||||
conversions, such as where precision or formatting need tighter control than is
|
||||
offered by the default behavior of <code>lexical_cast</code>, the conventional <code>
|
||||
stringstream</code> approach is recommended. Where the conversions are
|
||||
numeric to numeric, <code><a href="cast.htm#numeric_cast">numeric_cast</a></code>
|
||||
may offer more reasonable behavior than <code>lexical_cast</code>.
|
||||
<p>
|
||||
For a good discussion of the options and issues involved in string-based
|
||||
formatting, including comparison of <code>stringstream</code>, <code>lexical_cast</code>,
|
||||
and others, see Herb Sutter's article, <a href="http://www.gotw.ca/publications/mill19.htm">
|
||||
<i>The String Formatters of Manor Farm</i></a>.
|
||||
<p>
|
||||
<hr>
|
||||
<h2><a name="examples">Examples</a></h2>
|
||||
The following example treats command line arguments as a sequence of numeric
|
||||
data: <blockquote>
|
||||
<pre>
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
using boost::lexical_cast;
|
||||
using boost::bad_lexical_cast;
|
||||
|
||||
std::vector<short> args;
|
||||
|
||||
while(*++argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
args.push_back(lexical_cast<short>(*argv));
|
||||
}
|
||||
catch(bad_lexical_cast &)
|
||||
{
|
||||
args.push_back(0);
|
||||
}
|
||||
}
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</blockquote>The following example uses numeric data in a string expression: <blockquote>
|
||||
<pre>
|
||||
void log_message(const std::string &);
|
||||
|
||||
void log_errno(int yoko)
|
||||
{
|
||||
log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko));
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h2><a name="synopsis">Synopsis</a></h2>
|
||||
Library features defined in <a href="../../boost/lexical_cast.hpp"><code>"boost/lexical_cast.hpp"</code></a>:
|
||||
<blockquote>
|
||||
<pre>
|
||||
namespace boost
|
||||
{
|
||||
class <a href="#bad_lexical_cast">bad_lexical_cast</a>;
|
||||
template<typename Target, typename Source>
|
||||
Target <a href="#lexical_cast">lexical_cast</a>(Source arg);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>Unit test defined in <a href="lexical_cast_test.cpp"><code>"lexical_cast_test.cpp"</code></a>.
|
||||
<p>
|
||||
<hr>
|
||||
<h2><a name="lexical_cast"><code>lexical_cast</code></a></h2>
|
||||
<blockquote>
|
||||
<pre>
|
||||
template<typename Target, typename Source>
|
||||
Target lexical_cast(Source arg);
|
||||
</pre>
|
||||
</blockquote>Returns the result of streaming <code>arg</code> into a
|
||||
standard library string-based stream and then out as a <code>Target</code> object.
|
||||
Where <code>Target</code> is either <code>std::string</code>
|
||||
or <code>std::wstring</code>, stream extraction takes the whole content
|
||||
of the string, including spaces, rather than relying on the default
|
||||
<code>operator>></code> behavior.
|
||||
If the conversion is unsuccessful, a <a href="#bad_lexical_cast">
|
||||
<code>bad_lexical_cast</code></a> exception is thrown.
|
||||
<p>
|
||||
The requirements on the argument and result types are:
|
||||
<ul type="square">
|
||||
<li>
|
||||
<code>Source</code> is <i>OutputStreamable</i>, meaning that an <code>operator<<</code>
|
||||
is defined that takes a <code>std::ostream</code> or <code>std::wostream</code> object on the
|
||||
left hand side and an instance of the argument type on the right.
|
||||
</li>
|
||||
<li>
|
||||
<code>Target</code> is <i>InputStreamable</i>, meaning that an <code>operator>></code>
|
||||
is defined that takes a <code>std::istream</code> or <code>std::wistream</code> object on the left hand side
|
||||
and an instance of the result type on the right.
|
||||
</li>
|
||||
<li>
|
||||
Both <code>Source</code> and <code>Target</code> are <i>CopyConstructible</i> [20.1.3].
|
||||
</li>
|
||||
<li>
|
||||
<code>Target</code> is <i>DefaultConstructible</i>, meaning that it is possible
|
||||
to <i>default-initialize</i> an object of that type [8.5, 20.1.4].
|
||||
</li>
|
||||
</ul>
|
||||
The character type of the underlying stream is assumed to be <code>char</code> unless
|
||||
either the <code>Source</code> or the <code>Target</code> requires wide-character
|
||||
streaming, in which case the underlying stream uses <code>wchar_t</code>.
|
||||
<code>Source</code> types that require wide-character streaming are <code>wchar_t</code>,
|
||||
<code>wchar_t *</code>, and <code>std::wstring</code>. <code>Target</code> types that
|
||||
require wide-character streaming are <code>wchar_t</code> and <code>std::wstring</code>.
|
||||
<p>
|
||||
Where a higher degree of control is required over conversions, <code>std::stringstream</code>
|
||||
and <code>std::wstringstream</code> offer a more appropriate path. Where non-stream-based conversions are
|
||||
required, <code>lexical_cast</code>
|
||||
is the wrong tool for the job and is not special-cased for such scenarios.
|
||||
<p>
|
||||
<hr>
|
||||
<h2><a name="bad_lexical_cast"><code>bad_lexical_cast</code></a></h2>
|
||||
<blockquote>
|
||||
<pre>
|
||||
class bad_lexical_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
... // <i>same member function interface as</i> std::exception
|
||||
};
|
||||
</pre>
|
||||
</blockquote>Exception used to indicate runtime <a href="#lexical_cast"><code>lexical_cast</code></a>
|
||||
failure.
|
||||
<hr>
|
||||
<h2><a name="changes">Changes</a></h2>
|
||||
<ul type="square">
|
||||
<li>The previous version of <code>lexical_cast</code> used the default stream precision for reading
|
||||
and writing floating-point numbers. For numerics that have a corresponding specialization of
|
||||
<code>std::numeric_limits</code>, the current version now chooses a precision to match.
|
||||
<li>The previous version of <code>lexical_cast</code> did not support conversion to or from any
|
||||
wide-character-based types. For compilers with full language and library support for wide characters,
|
||||
<code>lexical_cast</code> now supports conversions from <code>wchar_t</code>, <code>wchar_t *</code>,
|
||||
and <code>std::wstring</code> and to <code>wchar_t</code> and <code>std::wstring</code>.
|
||||
<li>The previous version of <code>lexical_cast</code> assumed that the conventional stream extractor
|
||||
operators were sufficient for reading values. However, string I/O is asymmetric, with the result
|
||||
that spaces play the role of I/O separators rather than string content. The current version fixes
|
||||
this error for <code>std::string</code> and, where supported, <code>std::wstring</code>:
|
||||
<code>lexical_cast<std::string>("Hello, World")</code> succeeds instead of failing with
|
||||
a <code>bad_lexical_cast</code> exception.
|
||||
<li>The previous version of <code>lexical_cast</code> allowed unsafe and meaningless conversions to
|
||||
pointers. The current version now throws a <code>bad_lexical_cast</code> for conversions to pointers:
|
||||
<code>lexical_cast<char *>("Goodbye, World")</code> now throws an exception instead of
|
||||
causing undefined behavior.
|
||||
</ul>
|
||||
<p>
|
||||
<hr>
|
||||
<div align="right"><small><i>© Copyright Kevlin Henney, 2000–2003</i></small></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,288 +0,0 @@
|
||||
// Unit test for boost::lexical_cast.
|
||||
//
|
||||
// See http://www.boost.org for most recent version, including documentation.
|
||||
//
|
||||
// Copyright Terje Slettebø and Kevlin Henney, 2003.
|
||||
//
|
||||
// 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 <boost/config.hpp>
|
||||
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#pragma warning(disable: 193 383 488 981 1418 1419)
|
||||
#elif defined(BOOST_MSVC)
|
||||
#pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800)
|
||||
#endif
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/test/floating_point_comparison.hpp>
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
#if defined(BOOST_NO_STRINGSTREAM) || \
|
||||
defined(BOOST_NO_STD_WSTRING) || \
|
||||
defined(BOOST_NO_STD_LOCALE) || \
|
||||
defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
#define DISABLE_WIDE_CHAR_SUPPORT
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
|
||||
void test_conversion_to_char();
|
||||
void test_conversion_to_int();
|
||||
void test_conversion_to_double();
|
||||
void test_conversion_to_bool();
|
||||
void test_conversion_to_string();
|
||||
void test_conversion_from_to_wchar_t_alias();
|
||||
void test_conversion_to_pointer();
|
||||
void test_conversion_from_wchar_t();
|
||||
void test_conversion_to_wchar_t();
|
||||
void test_conversion_from_wstring();
|
||||
void test_conversion_to_wstring();
|
||||
|
||||
unit_test_framework::test_suite *init_unit_test_suite(int, char **)
|
||||
{
|
||||
unit_test_framework::test_suite *suite =
|
||||
BOOST_TEST_SUITE("lexical_cast unit test");
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_char));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_int));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_double));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_bool));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_from_to_wchar_t_alias));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_pointer));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_string));
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_from_wchar_t));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_wchar_t));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_from_wstring));
|
||||
suite->add(BOOST_TEST_CASE(test_conversion_to_wstring));
|
||||
#endif
|
||||
return suite;
|
||||
}
|
||||
|
||||
void test_conversion_to_char()
|
||||
{
|
||||
BOOST_CHECK_EQUAL('A', lexical_cast<char>('A'));
|
||||
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(' '));
|
||||
BOOST_CHECK_EQUAL('1', lexical_cast<char>(1));
|
||||
BOOST_CHECK_EQUAL('0', lexical_cast<char>(0));
|
||||
BOOST_CHECK_THROW(lexical_cast<char>(123), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL('1', lexical_cast<char>(1.0));
|
||||
BOOST_CHECK_EQUAL('1', lexical_cast<char>(true));
|
||||
BOOST_CHECK_EQUAL('0', lexical_cast<char>(false));
|
||||
BOOST_CHECK_EQUAL('A', lexical_cast<char>("A"));
|
||||
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(" "));
|
||||
BOOST_CHECK_THROW(lexical_cast<char>(""), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<char>("Test"), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL('A', lexical_cast<char>(std::string("A")));
|
||||
BOOST_CHECK_EQUAL(' ', lexical_cast<char>(std::string(" ")));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<char>(std::string("")), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<char>(std::string("Test")), boost::bad_lexical_cast);
|
||||
}
|
||||
|
||||
void test_conversion_to_int()
|
||||
{
|
||||
BOOST_CHECK_EQUAL(1,lexical_cast<int>('1'));
|
||||
BOOST_CHECK_EQUAL(0,lexical_cast<int>('0'));
|
||||
BOOST_CHECK_THROW(lexical_cast<int>('A'),boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(1,lexical_cast<int>(1));
|
||||
BOOST_CHECK_EQUAL(
|
||||
(std::numeric_limits<int>::max)(),
|
||||
lexical_cast<int>((std::numeric_limits<int>::max)()));
|
||||
BOOST_CHECK_EQUAL(1,lexical_cast<int>(1.0));
|
||||
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(1.23), boost::bad_lexical_cast);
|
||||
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(1e20), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(1, lexical_cast<int>(true));
|
||||
BOOST_CHECK_EQUAL(0, lexical_cast<int>(false));
|
||||
BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<int>(" 123"), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(""), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<int>("Test"), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(123, lexical_cast<int>("123"));
|
||||
BOOST_CHECK_EQUAL(123,lexical_cast<int>(std::string("123")));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<int>(std::string(" 123")), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<int>(std::string("")), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<int>(std::string("Test")), boost::bad_lexical_cast);
|
||||
}
|
||||
|
||||
void test_conversion_to_double()
|
||||
{
|
||||
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>('1'));
|
||||
BOOST_CHECK_THROW(lexical_cast<double>('A'), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(1));
|
||||
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(1.23));
|
||||
BOOST_CHECK_CLOSE(
|
||||
(std::numeric_limits<double>::max)() / 2,
|
||||
lexical_cast<double>((std::numeric_limits<double>::max)() / 2),
|
||||
std::numeric_limits<double>::epsilon());
|
||||
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(true));
|
||||
BOOST_CHECK_EQUAL(0.0, lexical_cast<double>(false));
|
||||
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>("1.23"));
|
||||
BOOST_CHECK_THROW(lexical_cast<double>(""), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<double>("Test"), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(std::string("1.23")));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<double>(std::string("")), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<double>(std::string("Test")), boost::bad_lexical_cast);
|
||||
}
|
||||
|
||||
void test_conversion_to_bool()
|
||||
{
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>('1'));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>('0'));
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>('A'), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0));
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(123), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(1.0));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(0.0));
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(true));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(false));
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(""), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>("Test"), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>("1"));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>("0"));
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::string("1")));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::string("0")));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<bool>(std::string("")), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<bool>(std::string("Test")), boost::bad_lexical_cast);
|
||||
}
|
||||
|
||||
void test_conversion_to_string()
|
||||
{
|
||||
BOOST_CHECK_EQUAL("A", lexical_cast<std::string>('A'));
|
||||
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(' '));
|
||||
BOOST_CHECK_EQUAL("123", lexical_cast<std::string>(123));
|
||||
BOOST_CHECK_EQUAL("1.23", lexical_cast<std::string>(1.23));
|
||||
BOOST_CHECK_EQUAL("1.111111111", lexical_cast<std::string>(1.111111111));
|
||||
BOOST_CHECK_EQUAL("1",lexical_cast<std::string>(true));
|
||||
BOOST_CHECK_EQUAL("0",lexical_cast<std::string>(false));
|
||||
BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>("Test"));
|
||||
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(" "));
|
||||
BOOST_CHECK_EQUAL("", lexical_cast<std::string>(""));
|
||||
BOOST_CHECK_EQUAL("Test", lexical_cast<std::string>(std::string("Test")));
|
||||
BOOST_CHECK_EQUAL(" ", lexical_cast<std::string>(std::string(" ")));
|
||||
BOOST_CHECK_EQUAL("", lexical_cast<std::string>(std::string("")));
|
||||
}
|
||||
|
||||
void test_conversion_from_to_wchar_t_alias()
|
||||
{
|
||||
BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned short>("123"));
|
||||
BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned int>("123"));
|
||||
BOOST_CHECK_EQUAL(123u, lexical_cast<unsigned long>("123"));
|
||||
BOOST_CHECK_EQUAL(std::string("123"),
|
||||
lexical_cast<std::string>(static_cast<unsigned short>(123)));
|
||||
BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123u));
|
||||
BOOST_CHECK_EQUAL(std::string("123"), lexical_cast<std::string>(123ul));
|
||||
}
|
||||
|
||||
void test_conversion_to_pointer()
|
||||
{
|
||||
BOOST_CHECK_THROW(lexical_cast<char *>("Test"), boost::bad_lexical_cast);
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
BOOST_CHECK_THROW(lexical_cast<wchar_t *>("Test"), boost::bad_lexical_cast);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_from_wchar_t()
|
||||
{
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
BOOST_CHECK_EQUAL(1, lexical_cast<int>(L'1'));
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(L'A'), boost::bad_lexical_cast);
|
||||
|
||||
BOOST_CHECK_EQUAL(123, lexical_cast<int>(L"123"));
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(L""), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<int>(L"Test"), boost::bad_lexical_cast);
|
||||
|
||||
BOOST_CHECK_EQUAL(1.0, lexical_cast<double>(L'1'));
|
||||
BOOST_CHECK_THROW(lexical_cast<double>(L'A'), boost::bad_lexical_cast);
|
||||
|
||||
BOOST_CHECK_EQUAL(1.23, lexical_cast<double>(L"1.23"));
|
||||
BOOST_CHECK_THROW(lexical_cast<double>(L""), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<double>(L"Test"), boost::bad_lexical_cast);
|
||||
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L'1'));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L'0'));
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(L'A'), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(L"1"));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(L"0"));
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(L""), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<bool>(L"Test"), boost::bad_lexical_cast);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_to_wchar_t()
|
||||
{
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1));
|
||||
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0));
|
||||
BOOST_CHECK_THROW(lexical_cast<wchar_t>(123), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(1.0));
|
||||
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(0.0));
|
||||
BOOST_CHECK_EQUAL(L'1', lexical_cast<wchar_t>(true));
|
||||
BOOST_CHECK_EQUAL(L'0', lexical_cast<wchar_t>(false));
|
||||
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L'A'));
|
||||
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L' '));
|
||||
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(L"A"));
|
||||
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(L" "));
|
||||
BOOST_CHECK_THROW(lexical_cast<wchar_t>(L""), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(lexical_cast<wchar_t>(L"Test"), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_EQUAL(L'A', lexical_cast<wchar_t>(std::wstring(L"A")));
|
||||
BOOST_CHECK_EQUAL(L' ', lexical_cast<wchar_t>(std::wstring(L" ")));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<wchar_t>(std::wstring(L"")), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<wchar_t>(std::wstring(L"Test")), boost::bad_lexical_cast);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_from_wstring()
|
||||
{
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
BOOST_CHECK_EQUAL(123, lexical_cast<int>(std::wstring(L"123")));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<int>(std::wstring(L"")), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<int>(std::wstring(L"Test")), boost::bad_lexical_cast);
|
||||
|
||||
BOOST_CHECK_EQUAL(true, lexical_cast<bool>(std::wstring(L"1")));
|
||||
BOOST_CHECK_EQUAL(false, lexical_cast<bool>(std::wstring(L"0")));
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<bool>(std::wstring(L"")), boost::bad_lexical_cast);
|
||||
BOOST_CHECK_THROW(
|
||||
lexical_cast<bool>(std::wstring(L"Test")), boost::bad_lexical_cast);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversion_to_wstring()
|
||||
{
|
||||
#ifndef DISABLE_WIDE_CHAR_SUPPORT
|
||||
BOOST_CHECK(L"123" == lexical_cast<std::wstring>(123));
|
||||
BOOST_CHECK(L"1.23" == lexical_cast<std::wstring>(1.23));
|
||||
BOOST_CHECK(L"1.111111111" == lexical_cast<std::wstring>(1.111111111));
|
||||
BOOST_CHECK(L"1" == lexical_cast<std::wstring>(true));
|
||||
BOOST_CHECK(L"0" == lexical_cast<std::wstring>(false));
|
||||
BOOST_CHECK(L"A" == lexical_cast<std::wstring>(L'A'));
|
||||
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L' '));
|
||||
BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(L"Test"));
|
||||
BOOST_CHECK(L" " == lexical_cast<std::wstring>(L" "));
|
||||
BOOST_CHECK(L"" == lexical_cast<std::wstring>(L""));
|
||||
BOOST_CHECK(L"Test" == lexical_cast<std::wstring>(std::wstring(L"Test")));
|
||||
BOOST_CHECK(L" " == lexical_cast<std::wstring>(std::wstring(L" ")));
|
||||
BOOST_CHECK(L"" == lexical_cast<std::wstring>(std::wstring(L"")));
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"key": "conversion",
|
||||
"name": "Conversion",
|
||||
"authors": [
|
||||
"Dave Abrahams",
|
||||
"Kevlin Henney"
|
||||
],
|
||||
"description": "Polymorphic casts.",
|
||||
"category": [
|
||||
"Miscellaneous"
|
||||
],
|
||||
"maintainers": [
|
||||
"Antony Polukhin <antoshkka -at- gmail.com>"
|
||||
]
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
// boost utility cast test program -----------------------------------------//
|
||||
|
||||
// (C) Copyright Beman Dawes, Dave Abrahams 1999. 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 for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 28 Set 04 factored out numeric_cast<> test (Fernando Cacciola)
|
||||
// 20 Jan 01 removed use of <limits> for portability to raw GCC (David Abrahams)
|
||||
// 28 Jun 00 implicit_cast removed (Beman Dawes)
|
||||
// 30 Aug 99 value_cast replaced by numeric_cast
|
||||
// 3 Aug 99 Initial Version
|
||||
|
||||
#include <iostream>
|
||||
#include <climits>
|
||||
#include <cfloat> // for DBL_MAX (Peter Schmid)
|
||||
#include <boost/cast.hpp>
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
# if SCHAR_MAX == LONG_MAX
|
||||
# error "This test program doesn't work if SCHAR_MAX == LONG_MAX"
|
||||
# endif
|
||||
|
||||
using namespace boost;
|
||||
using std::cout;
|
||||
|
||||
|
||||
int test_main( int argc, char * argv[] )
|
||||
{
|
||||
|
||||
# ifdef NDEBUG
|
||||
cout << "NDEBUG is defined\n";
|
||||
# else
|
||||
cout << "NDEBUG is not defined\n";
|
||||
# endif
|
||||
|
||||
cout << "\nBeginning tests...\n";
|
||||
|
||||
// test implicit_cast and numeric_cast -------------------------------------//
|
||||
|
||||
// tests which should succeed
|
||||
long small_value = 1;
|
||||
long small_negative_value = -1;
|
||||
long large_value = LONG_MAX;
|
||||
long large_negative_value = LONG_MIN;
|
||||
signed char c = 0;
|
||||
|
||||
c = large_value; // see if compiler generates warning
|
||||
|
||||
c = numeric_cast<signed char>( small_value );
|
||||
BOOST_CHECK( c == 1 );
|
||||
c = 0;
|
||||
c = numeric_cast<signed char>( small_value );
|
||||
BOOST_CHECK( c == 1 );
|
||||
c = 0;
|
||||
c = numeric_cast<signed char>( small_negative_value );
|
||||
BOOST_CHECK( c == -1 );
|
||||
|
||||
// These tests courtesy of Joe R NWP Swatosh<joe.r.swatosh@usace.army.mil>
|
||||
BOOST_CHECK( 0.0f == numeric_cast<float>( 0.0 ) );
|
||||
BOOST_CHECK( 0.0 == numeric_cast<double>( 0.0 ) );
|
||||
|
||||
// tests which should result in errors being detected
|
||||
|
||||
bool caught_exception = false;
|
||||
try { c = numeric_cast<signed char>( large_value ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #1\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
|
||||
caught_exception = false;
|
||||
try { c = numeric_cast<signed char>( large_negative_value ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #2\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
|
||||
unsigned long ul;
|
||||
caught_exception = false;
|
||||
try { ul = numeric_cast<unsigned long>( large_negative_value ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #3\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
|
||||
caught_exception = false;
|
||||
try { ul = numeric_cast<unsigned long>( small_negative_value ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #4\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
|
||||
caught_exception = false;
|
||||
try { numeric_cast<int>( DBL_MAX ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
|
||||
BOOST_CHECK ( caught_exception );
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
// what: simple unit test framework
|
||||
// who: developed by Kevlin Henney
|
||||
// when: November 2000
|
||||
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.91
|
||||
//
|
||||
// ChangeLog:
|
||||
// 20 Jan 2001 - Fixed a warning for MSVC (Dave Abrahams)
|
||||
|
||||
#ifndef TEST_INCLUDED
|
||||
#define TEST_INCLUDED
|
||||
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <strstream> // for out-of-the-box g++
|
||||
#include <string>
|
||||
|
||||
namespace test // test tuple comprises name and nullary function (object)
|
||||
{
|
||||
template<typename string_type, typename function_type>
|
||||
struct test
|
||||
{
|
||||
string_type name;
|
||||
function_type action;
|
||||
|
||||
static test make(string_type name, function_type action)
|
||||
{
|
||||
test result; // MSVC aggreggate initializer bugs
|
||||
result.name = name;
|
||||
result.action = action;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace test // failure exception used to indicate checked test failures
|
||||
{
|
||||
class failure : public std::exception
|
||||
{
|
||||
public: // struction (default cases are OK)
|
||||
|
||||
failure(const std::string & why)
|
||||
: reason(why)
|
||||
{
|
||||
}
|
||||
|
||||
// std::~string has no exception-specification (could throw anything),
|
||||
// but we need to be compatible with std::~exception's empty one
|
||||
// see std::15.4p13 and std::15.4p3
|
||||
~failure() throw()
|
||||
{
|
||||
}
|
||||
|
||||
public: // usage
|
||||
|
||||
virtual const char * what() const throw()
|
||||
{
|
||||
return reason.c_str();
|
||||
}
|
||||
|
||||
private: // representation
|
||||
|
||||
std::string reason;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace test // not_implemented exception used to mark unimplemented tests
|
||||
{
|
||||
class not_implemented : public std::exception
|
||||
{
|
||||
public: // usage (default ctor and dtor are OK)
|
||||
|
||||
virtual const char * what() const throw()
|
||||
{
|
||||
return "not implemented";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace test // test utilities
|
||||
{
|
||||
inline void check(bool condition, const std::string & description)
|
||||
{
|
||||
if(!condition)
|
||||
{
|
||||
throw failure(description);
|
||||
}
|
||||
}
|
||||
|
||||
inline void check_true(bool value, const std::string & description)
|
||||
{
|
||||
check(value, "expected true: " + description);
|
||||
}
|
||||
|
||||
inline void check_false(bool value, const std::string & description)
|
||||
{
|
||||
check(!value, "expected false: " + description);
|
||||
}
|
||||
|
||||
template<typename lhs_type, typename rhs_type>
|
||||
void check_equal(
|
||||
const lhs_type & lhs, const rhs_type & rhs,
|
||||
const std::string & description)
|
||||
{
|
||||
check(lhs == rhs, "expected equal values: " + description);
|
||||
}
|
||||
|
||||
template<typename lhs_type, typename rhs_type>
|
||||
void check_unequal(
|
||||
const lhs_type & lhs, const rhs_type & rhs,
|
||||
const std::string & description)
|
||||
{
|
||||
check(lhs != rhs, "expected unequal values: " + description);
|
||||
}
|
||||
|
||||
inline void check_null(const void* ptr, const std::string & description)
|
||||
{
|
||||
check(!ptr, "expected null pointer: " + description);
|
||||
}
|
||||
|
||||
inline void check_non_null(const void* ptr, const std::string & description)
|
||||
{
|
||||
check(ptr != 0, "expected non-null pointer: " + description);
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_CHECK_THROW(expression, exception, description) \
|
||||
try \
|
||||
{ \
|
||||
expression; \
|
||||
throw ::test::failure(description); \
|
||||
} \
|
||||
catch(exception &) \
|
||||
{ \
|
||||
}
|
||||
|
||||
namespace test // memory tracking (enabled if test new and delete linked in)
|
||||
{
|
||||
class allocations
|
||||
{
|
||||
public: // singleton access
|
||||
|
||||
static allocations & instance()
|
||||
{
|
||||
static allocations singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public: // logging
|
||||
|
||||
void clear()
|
||||
{
|
||||
alloc_count = dealloc_count = 0;
|
||||
}
|
||||
|
||||
void allocation()
|
||||
{
|
||||
++alloc_count;
|
||||
}
|
||||
|
||||
void deallocation()
|
||||
{
|
||||
++dealloc_count;
|
||||
}
|
||||
|
||||
public: // reporting
|
||||
|
||||
unsigned long allocated() const
|
||||
{
|
||||
return alloc_count;
|
||||
}
|
||||
|
||||
unsigned long deallocated() const
|
||||
{
|
||||
return dealloc_count;
|
||||
}
|
||||
|
||||
bool balanced() const
|
||||
{
|
||||
return alloc_count == dealloc_count;
|
||||
}
|
||||
|
||||
private: // structors (default dtor is fine)
|
||||
|
||||
allocations()
|
||||
: alloc_count(0), dealloc_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
private: // prevention
|
||||
|
||||
allocations(const allocations &);
|
||||
allocations & operator=(const allocations &);
|
||||
|
||||
private: // state
|
||||
|
||||
unsigned long alloc_count, dealloc_count;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace test // tester is the driver class for a sequence of tests
|
||||
{
|
||||
template<typename test_iterator>
|
||||
class tester
|
||||
{
|
||||
public: // structors (default destructor is OK)
|
||||
|
||||
tester(test_iterator first_test, test_iterator after_last_test)
|
||||
: begin(first_test), end(after_last_test)
|
||||
{
|
||||
}
|
||||
|
||||
public: // usage
|
||||
|
||||
bool operator()(); // returns true if all tests passed
|
||||
|
||||
private: // representation
|
||||
|
||||
test_iterator begin, end;
|
||||
|
||||
private: // prevention
|
||||
|
||||
tester(const tester &);
|
||||
tester &operator=(const tester &);
|
||||
|
||||
};
|
||||
|
||||
template<typename test_iterator>
|
||||
bool tester<test_iterator>::operator()()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
unsigned long passed = 0, failed = 0, unimplemented = 0;
|
||||
|
||||
for(test_iterator current = begin; current != end; ++current)
|
||||
{
|
||||
cerr << "[" << current->name << "] " << flush;
|
||||
string result = "passed"; // optimistic
|
||||
|
||||
try
|
||||
{
|
||||
allocations::instance().clear();
|
||||
current->action();
|
||||
|
||||
if(!allocations::instance().balanced())
|
||||
{
|
||||
unsigned long allocated = allocations::instance().allocated();
|
||||
unsigned long deallocated = allocations::instance().deallocated();
|
||||
ostrstream report;
|
||||
report << "new/delete ("
|
||||
<< allocated << " allocated, "
|
||||
<< deallocated << " deallocated)"
|
||||
<< ends;
|
||||
const char * text = report.str();
|
||||
report.freeze(false);
|
||||
throw failure(text);
|
||||
}
|
||||
|
||||
++passed;
|
||||
}
|
||||
catch(const failure & caught)
|
||||
{
|
||||
(result = "failed: ") += caught.what();
|
||||
++failed;
|
||||
}
|
||||
catch(const not_implemented &)
|
||||
{
|
||||
result = "not implemented";
|
||||
++unimplemented;
|
||||
}
|
||||
catch(const exception & caught)
|
||||
{
|
||||
(result = "exception: ") += caught.what();
|
||||
++failed;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
result = "failed with unknown exception";
|
||||
++failed;
|
||||
}
|
||||
|
||||
cerr << result << endl;
|
||||
}
|
||||
|
||||
cerr << passed + failed << " tests: "
|
||||
<< passed << " passed, "
|
||||
<< failed << " failed";
|
||||
|
||||
if(unimplemented)
|
||||
{
|
||||
cerr << " (" << unimplemented << " not implemented)";
|
||||
}
|
||||
|
||||
cerr << endl;
|
||||
|
||||
return failed == 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Copyright Kevlin Henney, 2000. All rights reserved.
|
||||
//
|
||||
// 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)
|
||||
@@ -1,34 +0,0 @@
|
||||
# Signals library
|
||||
|
||||
# Copyright (C) 2001-2003 Douglas Gregor
|
||||
|
||||
# Permission to copy, use, sell and distribute this software is granted
|
||||
# provided this copyright notice appears in all copies. Permission to modify
|
||||
# the code and to distribute modified code is granted provided this copyright
|
||||
# notice appears in all copies, and a notice that the code was modified is
|
||||
# included with the copyright notice. This software is provided "as is"
|
||||
# without express or implied warranty, and with no claim as to its suitability
|
||||
# for any purpose.
|
||||
|
||||
# For more information, see http://www.boost.org/
|
||||
|
||||
|
||||
# Testing Jamfile autogenerated from XML source
|
||||
subproject libs/conversion/test ;
|
||||
|
||||
# bring in rules for testing
|
||||
import testing ;
|
||||
|
||||
# Make tests run by default.
|
||||
DEPENDS all : test ;
|
||||
|
||||
{
|
||||
test-suite conversion
|
||||
: [ run implicit_cast.cpp ]
|
||||
[ compile-fail implicit_cast_fail.cpp ]
|
||||
[ run ../cast_test.cpp ]
|
||||
[ run ../numeric_cast_test.cpp ]
|
||||
[ run ../lexical_cast_test.cpp ]
|
||||
;
|
||||
}
|
||||
|
||||
+21
-17
@@ -1,25 +1,29 @@
|
||||
# Signals library
|
||||
|
||||
# Copyright (C) 2001-2003 Douglas Gregor
|
||||
# Copyright (C) 2011-2014 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)
|
||||
#
|
||||
|
||||
# Permission to copy, use, sell and distribute this software is granted
|
||||
# provided this copyright notice appears in all copies. Permission to modify
|
||||
# the code and to distribute modified code is granted provided this copyright
|
||||
# notice appears in all copies, and a notice that the code was modified is
|
||||
# included with the copyright notice. This software is provided "as is"
|
||||
# without express or implied warranty, and with no claim as to its suitability
|
||||
# for any purpose.
|
||||
|
||||
# For more information, see http://www.boost.org/
|
||||
|
||||
# bring in rules for testing
|
||||
import testing ;
|
||||
import feature ;
|
||||
|
||||
project
|
||||
: requirements
|
||||
<toolset>gcc-4.7:<cxxflags>-ftrapv
|
||||
<toolset>gcc-4.6:<cxxflags>-ftrapv
|
||||
<toolset>clang:<cxxflags>-ftrapv
|
||||
# default to all warnings on:
|
||||
<warnings>all
|
||||
# set warnings as errors for those compilers we know we get warning free:
|
||||
<toolset>gcc:<cxxflags>-Wextra
|
||||
<toolset>gcc:<cxxflags>-Wno-uninitialized
|
||||
;
|
||||
|
||||
test-suite conversion
|
||||
: [ run implicit_cast.cpp ]
|
||||
[ compile-fail implicit_cast_fail.cpp ]
|
||||
[ run ../cast_test.cpp ]
|
||||
[ run ../lexical_cast_test.cpp ]
|
||||
[ run cast_test.cpp ]
|
||||
[ run polymorphic_cast_test.cpp ]
|
||||
[ compile-fail implicit_cast_fail2.cpp ]
|
||||
;
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
# 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-2019.
|
||||
|
||||
#
|
||||
# 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.71.{build}-{branch}
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
skip_tags: true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
|
||||
- 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 1 --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:
|
||||
@@ -14,13 +14,8 @@
|
||||
// 3 Aug 99 Initial Version
|
||||
|
||||
#include <iostream>
|
||||
#include <climits>
|
||||
#include <cfloat> // for DBL_MAX (Peter Schmid)
|
||||
#include <boost/cast.hpp>
|
||||
|
||||
# if SCHAR_MAX == LONG_MAX
|
||||
# error "This test program doesn't work if SCHAR_MAX == LONG_MAX"
|
||||
# endif
|
||||
#include <boost/polymorphic_cast.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using std::cout;
|
||||
@@ -57,35 +52,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,9 +4,8 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/implicit_cast.hpp>
|
||||
#include <cassert>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/type.hpp>
|
||||
|
||||
using boost::implicit_cast;
|
||||
using boost::type;
|
||||
|
||||
@@ -25,9 +24,15 @@ typedef type<foo> foo_type;
|
||||
int main()
|
||||
{
|
||||
type<long> x = check_return(boost::implicit_cast<long>(1));
|
||||
assert(boost::implicit_cast<long>(1) == 1L);
|
||||
BOOST_TEST(boost::implicit_cast<long>(1) == 1L);
|
||||
|
||||
type<foo> f = check_return(boost::implicit_cast<foo>("hello"));
|
||||
type<long> z = check_return(boost::implicit_cast<long>(foo("hello")));
|
||||
return 0;
|
||||
|
||||
// warning suppression:
|
||||
(void)x;
|
||||
(void)f;
|
||||
(void)z;
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/implicit_cast.hpp>
|
||||
#include <boost/type.hpp>
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using boost::implicit_cast;
|
||||
|
||||
@@ -16,7 +12,9 @@ struct foo
|
||||
explicit foo(char const*) {}
|
||||
};
|
||||
|
||||
int test_main(int, char*[])
|
||||
int main()
|
||||
{
|
||||
foo x = implicit_cast<foo>("foobar");
|
||||
(void)x; // warning suppression.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Test that implicit_cast requires a template argument
|
||||
//
|
||||
// Copyright 2014 Peter Dimov
|
||||
//
|
||||
// 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 <boost/implicit_cast.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
int x = boost::implicit_cast( 1 );
|
||||
(void)x;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#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
|
||||
{
|
||||
BOOST_ERROR( "unexpected assertion" );
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): assertion '" << expr << "' failed in function '"
|
||||
<< function << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
struct Base : boost::intrusive_ref_counter<Base>
|
||||
{
|
||||
virtual ~Base() {}
|
||||
virtual std::string kind() { return "Base"; }
|
||||
};
|
||||
|
||||
struct Base2
|
||||
{
|
||||
virtual ~Base2() {}
|
||||
virtual std::string kind2() { return "Base2"; }
|
||||
};
|
||||
|
||||
struct Derived : public Base, Base2
|
||||
{
|
||||
virtual std::string kind() { return "Derived"; }
|
||||
};
|
||||
|
||||
static void test_polymorphic_cast()
|
||||
{
|
||||
Base * base = new Derived;
|
||||
|
||||
Derived * derived;
|
||||
|
||||
try
|
||||
{
|
||||
derived = boost::polymorphic_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_cast<Derived*>( base ) threw std::bad_cast" );
|
||||
}
|
||||
|
||||
Base2 * base2;
|
||||
|
||||
try
|
||||
{
|
||||
base2 = boost::polymorphic_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_cast<Base2*>( base ) threw std::bad_cast" );
|
||||
}
|
||||
|
||||
delete base;
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_cast()
|
||||
{
|
||||
Base * base = new Derived;
|
||||
|
||||
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 = new Derived;
|
||||
|
||||
Derived * derived = boost::polymorphic_downcast<Derived*>( base );
|
||||
|
||||
BOOST_TEST( derived != 0 );
|
||||
|
||||
if( derived != 0 )
|
||||
{
|
||||
BOOST_TEST_EQ( derived->kind(), "Derived" );
|
||||
}
|
||||
|
||||
// polymorphic_downcast can't do crosscasts
|
||||
|
||||
delete base;
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_downcast_builtin()
|
||||
{
|
||||
Base * base = new Derived;
|
||||
|
||||
Derived * derived = boost::polymorphic_pointer_downcast<Derived>( base );
|
||||
|
||||
BOOST_TEST( derived != 0 );
|
||||
|
||||
if( derived != 0 )
|
||||
{
|
||||
BOOST_TEST_EQ( derived->kind(), "Derived" );
|
||||
}
|
||||
|
||||
// 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" );
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_SMART_PTR
|
||||
|
||||
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" );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void test_polymorphic_cast_fail()
|
||||
{
|
||||
Base * base = new Base;
|
||||
|
||||
BOOST_TEST_THROWS( boost::polymorphic_cast<Derived*>( base ), std::bad_cast );
|
||||
|
||||
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 );
|
||||
|
||||
#ifndef BOOST_NO_CXX11_SMART_PTR
|
||||
BOOST_TEST_THROWS( boost::polymorphic_pointer_cast<Derived>( std::shared_ptr<Base>(new Base) ), std::bad_cast );
|
||||
#endif
|
||||
|
||||
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 = new Base;
|
||||
|
||||
int old_count = assertion_failed_count;
|
||||
expect_assertion = true;
|
||||
|
||||
BOOST_TEST_THROWS( boost::polymorphic_downcast<Derived*>( base ), expected_assertion ); // should assert
|
||||
|
||||
BOOST_TEST_EQ( assertion_failed_count, old_count + 1 );
|
||||
expect_assertion = false;
|
||||
|
||||
delete base;
|
||||
}
|
||||
|
||||
static void test_polymorphic_pointer_downcast_builtin_fail()
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_SMART_PTR
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
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();
|
||||
|
||||
#ifndef BOOST_NO_CXX11_SMART_PTR
|
||||
test_polymorphic_pointer_downcast_std_shared();
|
||||
test_polymorphic_pointer_downcast_std_shared_fail();
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
Reference in New Issue
Block a user