forked from boostorg/type_index
Compare commits
117 Commits
boost-1.62
...
esp-idf-co
Author | SHA1 | Date | |
---|---|---|---|
bdfd7b91c2 | |||
cca370a918 | |||
97fc5b9838 | |||
0cc169ecd6 | |||
a3c6a957ee | |||
04cc1734ef | |||
f395836779 | |||
4f51b1f4eb | |||
a2ef72c907 | |||
331c26760e | |||
d6d07a8ce8 | |||
4468903f8f | |||
88c5d9a998 | |||
f0b87ea7d3 | |||
03794d6144 | |||
62154d3b19 | |||
b4014f385d | |||
0dc42bab8f | |||
a4726d239f | |||
f40f4731e1 | |||
754fb0f348 | |||
6fa4f57e7d | |||
c79f1c8d5d | |||
843ee6848b | |||
6fc5b35b00 | |||
84d68f32e2 | |||
1dacdb561e | |||
9862011b6b | |||
321749796e | |||
f2e395a7f3 | |||
9936c31851 | |||
560c7d2ef6 | |||
bf33e63feb | |||
2152466531 | |||
389f621450 | |||
0b65c1a8d8 | |||
216c21b728 | |||
afd1b6cdc8 | |||
d69a8a211b | |||
ebe74ba4ba | |||
ac4fec435f | |||
f68d6dc073 | |||
85f43ece0d | |||
a2de6a56f3 | |||
c585d74669 | |||
32909cb25a | |||
7af1661709 | |||
351cedf404 | |||
098c84481e | |||
d9d13b9574 | |||
44ca756e32 | |||
acb536a67e | |||
7654c26594 | |||
075b3682ae | |||
a60e25a74d | |||
cd1c905f87 | |||
f3da852bca | |||
a8fafd93f9 | |||
01944bf377 | |||
09f0bc23c5 | |||
718af3e8dc | |||
c9c1412a05 | |||
c2caa340ab | |||
da0a181117 | |||
be9f5a4b9b | |||
bd19ed1a87 | |||
727cdadc86 | |||
5bc4f54183 | |||
918e59c109 | |||
cd659212aa | |||
70e51a62e9 | |||
05feacf14b | |||
82ed016577 | |||
1a7226bc0f | |||
be08eda196 | |||
baa5019c90 | |||
4585bab3c3 | |||
93e7b2458b | |||
09ac338acc | |||
b0737f4169 | |||
be74716251 | |||
f82eab8882 | |||
af61d6b8ed | |||
d3d4e8d18a | |||
7f8af2a6e9 | |||
342d835289 | |||
5cacb67510 | |||
f2616bcd17 | |||
8c582362d0 | |||
f71d9eb3f2 | |||
cfcdcd647d | |||
8bee2f6939 | |||
40985de221 | |||
d8bdbad2ec | |||
c52fdfe30c | |||
7f840c882e | |||
b669f0244e | |||
d656e1879a | |||
b1ed011b6e | |||
4d1cf425e0 | |||
d6ca24ff3c | |||
4459af9532 | |||
b61a7423b7 | |||
1a918009fd | |||
045ab1d779 | |||
b6b23bad3a | |||
3bb646d19b | |||
9cd218bbc4 | |||
ad26256d09 | |||
5af925602e | |||
2fb667a6a0 | |||
12751e0f83 | |||
0b006b6af6 | |||
76cae485cb | |||
ee7b15a493 | |||
1dc8310826 | |||
b230140529 |
178
.github/workflows/ci.yml
vendored
Normal file
178
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/**
|
||||
|
||||
env:
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
|
||||
jobs:
|
||||
posix:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-7
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
cxxflags: "cxxflags=--coverage"
|
||||
linkflags: "linkflags=--coverage"
|
||||
gcov_tool: "gcov-7"
|
||||
- toolset: gcc-9
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
- toolset: gcc-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
|
||||
linkflags: "linkflags=--coverage -lasan -lubsan"
|
||||
launcher: "testing.launcher=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6"
|
||||
gcov_tool: "gcov-10"
|
||||
- toolset: clang
|
||||
compiler: clang++-7
|
||||
cxxstd: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-7
|
||||
- toolset: clang
|
||||
compiler: clang++-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: macos-10.15
|
||||
cxxflags: "cxxflags=-fsanitize=address,undefined -fno-sanitize-recover=undefined"
|
||||
linkflags: "linkflags=-fsanitize=address,undefined"
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
||||
echo LIBRARY: $LIBRARY
|
||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
||||
echo GITHUB_REF: $GITHUB_REF
|
||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
||||
REF=${REF#refs/heads/}
|
||||
echo REF: $REF
|
||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
||||
cd ..
|
||||
git clone -b $BOOST_BRANCH --depth 10 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
git submodule update --init --depth 10 --jobs 2 tools/boostdep tools/inspect libs/filesystem
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 3" filesystem
|
||||
rm -rf libs/$LIBRARY/*
|
||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
||||
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--depth 10 --jobs 3" $LIBRARY
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
./b2 -j4 variant=debug tools/inspect/build
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost-root
|
||||
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release "${{matrix.cxxflags}}" "${{matrix.linkflags}}" "${{matrix.launcher}}"
|
||||
dist/bin/inspect libs/$LIBRARY
|
||||
|
||||
- name: Prepare coverage data
|
||||
if: matrix.gcov_tool
|
||||
run: |
|
||||
mkdir -p $GITHUB_WORKSPACE/coveralls
|
||||
|
||||
echo -e "#!/bin/bash\nexec ${{matrix.gcov_tool}} \"\$@\"" > $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
|
||||
chmod +x $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
|
||||
wget https://github.com/linux-test-project/lcov/archive/v1.15.zip
|
||||
unzip v1.15.zip
|
||||
LCOV="`pwd`/lcov-1.15/bin/lcov --gcov-tool $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh"
|
||||
|
||||
echo "$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory `pwd`/libs/$LIBRARY/test --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info"
|
||||
$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory ../boost-root/ --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info
|
||||
$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info "/usr*" "*/$LIBRARY/test/*" ${{matrix.ignore_coverage}} "*/$LIBRARY/tests/*" "*/$LIBRARY/examples/*" "*/$LIBRARY/example/*" -o $GITHUB_WORKSPACE/coveralls/coverage.info
|
||||
|
||||
cd ../boost-root
|
||||
OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$LIBRARY\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
|
||||
echo $OTHER_LIBS
|
||||
eval "$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info $OTHER_LIBS -o $GITHUB_WORKSPACE/coveralls/coverage.info"
|
||||
|
||||
- name: Coveralls
|
||||
uses: coverallsapp/github-action@master
|
||||
if: matrix.gcov_tool
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path-to-lcov: ./coveralls/coverage.info
|
||||
parallel: true
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: msvc-14.1
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2016
|
||||
- toolset: msvc-14.2
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: gcc
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
addrmd: 64
|
||||
os: windows-2019
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
||||
echo LIBRARY: %LIBRARY%
|
||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
||||
echo GITHUB_REF: %GITHUB_REF%
|
||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
||||
set BOOST_BRANCH=develop
|
||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
||||
cd ..
|
||||
git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git boost-root
|
||||
cd boost-root
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
|
||||
git submodule update --init tools/boostdep
|
||||
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--jobs 3" %LIBRARY%
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
- name: Run tests
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
|
||||
|
||||
finish:
|
||||
needs: posix
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Coveralls Finished
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.github_token }}
|
||||
parallel-finished: true
|
117
.travis.yml
117
.travis.yml
@ -1,117 +0,0 @@
|
||||
# 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-2015.
|
||||
|
||||
#
|
||||
# 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 #5
|
||||
|
||||
sudo: false
|
||||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
# - clang
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
env:
|
||||
global:
|
||||
# Autodetect Boost branch by using the following code: - BRANCH_TO_TEST=$TRAVIS_BRANCH
|
||||
# or just directly specify it
|
||||
#- BRANCH_TO_TEST=$TRAVIS_BRANCH
|
||||
- BRANCH_TO_TEST=develop
|
||||
|
||||
# Files, which coverage results must be ignored (files from other projects).
|
||||
# Example: - IGNORE_COVERAGE='*/boost/progress.hpp */filesystem/src/*'
|
||||
- IGNORE_COVERAGE='*/numeric/conversion/converter_policies.hpp'
|
||||
|
||||
# Explicitly remove the following library from Boost. This may be usefull, if you're for example running Travis
|
||||
# from `Boost.DLL` repo, while Boost already has `dll`.
|
||||
#
|
||||
# By default is eaual to - BOOST_REMOVE=$(basename $TRAVIS_BUILD_DIR)
|
||||
# This will force to use local repo content, instead of the Boost's default.
|
||||
- BOOST_REMOVE=$(basename $TRAVIS_BUILD_DIR)
|
||||
|
||||
matrix:
|
||||
- CXX_FLAGS="--coverage -DBOOST_TRAVISCI_BUILD -std=c++98" LINK_FLAGS=--coverage TOOLSET=gcc
|
||||
- CXX_FLAGS="--coverage -DBOOST_TRAVISCI_BUILD -std=c++11" LINK_FLAGS=--coverage TOOLSET=gcc-5
|
||||
- CXX_FLAGS="--coverage -DBOOST_TRAVISCI_BUILD -std=c++1y" LINK_FLAGS=--coverage TOOLSET=gcc-5
|
||||
#- CXX_FLAGS="--coverage -DBOOST_TRAVISCI_BUILD -std=c++11 -stdlib=libc++" LINK_FLAGS="--coverage -stdlib=libc++" TOOLSET=clang
|
||||
#- CXX_FLAGS="--coverage -DBOOST_TRAVISCI_BUILD -std=c++1y -stdlib=libc++" LINK_FLAGS="--coverage -stdlib=libc++" TOOLSET=clang
|
||||
|
||||
###############################################################################################################
|
||||
# From this point and below code is same for all the Boost libs
|
||||
###############################################################################################################
|
||||
|
||||
|
||||
# Installing additional tools
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- valgrind
|
||||
- python-yaml
|
||||
- gcc-5
|
||||
- g++-5
|
||||
- lcov
|
||||
- clang
|
||||
- libc++-dev
|
||||
|
||||
before_install:
|
||||
# Set this to the name of the library
|
||||
- PROJECT_TO_TEST=`basename $TRAVIS_BUILD_DIR`
|
||||
# Cloning Boost libraries (fast nondeep cloning)
|
||||
- BOOST=$HOME/boost-local
|
||||
- echo "Testing $PROJECT_TO_TEST, to remove $BOOST/libs/$BOOST_REMOVE, testing branch $BRANCH_TO_TEST"
|
||||
- git init $BOOST
|
||||
- cd $BOOST
|
||||
- git remote add --no-tags -t $BRANCH_TO_TEST origin https://github.com/boostorg/boost.git
|
||||
- git fetch --depth=1
|
||||
- git checkout $BRANCH_TO_TEST
|
||||
- git submodule update --init --merge
|
||||
- git remote set-branches --add origin $BRANCH_TO_TEST
|
||||
- git pull --recurse-submodules
|
||||
- git submodule update --init
|
||||
- git checkout $BRANCH_TO_TEST
|
||||
- git submodule foreach "git reset --quiet --hard; git clean -fxd"
|
||||
- git reset --hard; git clean -fxd
|
||||
- git status
|
||||
- rm -rf $BOOST/libs/$BOOST_REMOVE
|
||||
- mv $TRAVIS_BUILD_DIR $BOOST/libs/$PROJECT_TO_TEST
|
||||
- TRAVIS_BUILD_DIR=$BOOST/libs/$PROJECT_TO_TEST
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
- cd $BOOST/libs/$PROJECT_TO_TEST/test/
|
||||
|
||||
script:
|
||||
# `--coverage` flags required to generate coverage info for Coveralls
|
||||
- ../../../b2 testing.launcher=valgrind address-model=64 architecture=x86 toolset=$TOOLSET cxxflags="$CXX_FLAGS" linkflags="$LINK_FLAGS"
|
||||
|
||||
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/ \;
|
||||
|
||||
# Preparing Coveralls data by changind data format to a readable one
|
||||
- lcov --directory $TRAVIS_BUILD_DIR/coverals --base-directory ./ --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*" "*/$PROJECT_TO_TEST/test/*" $IGNORE_COVERAGE "*/$PROJECT_TO_TEST/tests/*" "*/$PROJECT_TO_TEST/examples/*" "*/$PROJECT_TO_TEST/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\/$PROJECT_TO_TEST\/\*\"/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
|
47
CMakeLists.txt
Normal file
47
CMakeLists.txt
Normal file
@ -0,0 +1,47 @@
|
||||
# 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
|
||||
|
||||
if(NOT DEFINED IDF_TARGET)
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.20)
|
||||
project(boost_type_index VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
add_library(boost_type_index INTERFACE)
|
||||
add_library(Boost::type_index ALIAS boost_type_index)
|
||||
|
||||
target_include_directories(boost_type_index INTERFACE include)
|
||||
|
||||
target_link_libraries(boost_type_index
|
||||
INTERFACE
|
||||
Boost::config
|
||||
Boost::container_hash
|
||||
Boost::core
|
||||
Boost::preprocessor
|
||||
Boost::smart_ptr
|
||||
Boost::static_assert
|
||||
Boost::throw_exception
|
||||
Boost::type_traits
|
||||
)
|
||||
|
||||
else()
|
||||
|
||||
FILE(GLOB_RECURSE headers include/*.h include/*.hpp)
|
||||
|
||||
idf_component_register(
|
||||
SRCS
|
||||
${headers}
|
||||
INCLUDE_DIRS
|
||||
include
|
||||
REQUIRES
|
||||
boost_config
|
||||
boost_container_hash
|
||||
boost_core
|
||||
boost_preprocessor
|
||||
boost_smart_ptr
|
||||
boost_static_assert
|
||||
boost_throw_exception
|
||||
boost_type_traits
|
||||
)
|
||||
|
||||
endif()
|
14
README.md
14
README.md
@ -1,18 +1,16 @@
|
||||
#[Boost.TypeIndex](http://boost.org/libs/type_index)
|
||||
Boost.TypeIndex is a part of the [Boost C++ Libraries](http://github.com/boostorg). It is a runtime/compile time copyable type info.
|
||||
# [Boost.TypeIndex](https://boost.org/libs/type_index)
|
||||
Boost.TypeIndex is a part of the [Boost C++ Libraries](https://github.com/boostorg). It is a runtime/compile time copyable type info.
|
||||
|
||||
### Test results
|
||||
|
||||
@ | Build | Tests coverage | More info
|
||||
----------------|-------------- | -------------- |-----------
|
||||
Develop branch: | [](https://travis-ci.org/apolukhin/type_index) [](https://ci.appveyor.com/project/apolukhin/type-index/branch/develop) | [](https://coveralls.io/r/apolukhin/type_index?branch=develop) | [details...](http://www.boost.org/development/tests/develop/developer/type_index.html)
|
||||
Master branch: | [](https://travis-ci.org/apolukhin/type_index) [](https://ci.appveyor.com/project/apolukhin/type-index/branch/master) | [](https://coveralls.io/r/apolukhin/type_index?branch=master) | [details...](http://www.boost.org/development/tests/master/developer/type_index.html)
|
||||
Develop branch: | [](https://github.com/boostorg/type_index/actions/workflows/ci.yml) [](https://ci.appveyor.com/project/apolukhin/type-index/branch/develop) | [](https://coveralls.io/r/apolukhin/type_index?branch=develop) | [details...](https://www.boost.org/development/tests/develop/developer/type_index.html)
|
||||
Master branch: | [](https://github.com/boostorg/type_index/actions/workflows/ci.yml) [](https://ci.appveyor.com/project/apolukhin/type-index/branch/master) | [](https://coveralls.io/r/apolukhin/type_index?branch=master) | [details...](https://www.boost.org/development/tests/master/developer/type_index.html)
|
||||
|
||||
|
||||
[Open Issues](https://svn.boost.org/trac/boost/query?status=!closed&component=type_index)
|
||||
|
||||
[Latest developer documentation](http://boostorg.github.com/type_index/index.html)
|
||||
[Latest developer documentation](https://www.boost.org/doc/libs/develop/doc/html/boost_typeindex.html)
|
||||
|
||||
### License
|
||||
|
||||
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
|
||||
Distributed under the [Boost Software License, Version 1.0](https://boost.org/LICENSE_1_0.txt).
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright Antony Polukhin 2011-2016.
|
||||
# Copyright 2011-2022 Antony Polukhin.
|
||||
# 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)
|
||||
@ -11,6 +11,7 @@ doxygen autodoc
|
||||
:
|
||||
[ glob ../../../boost/type_index.hpp ]
|
||||
[ glob ../../../boost/type_index/*.hpp ]
|
||||
[ glob ../../../boost/type_index/runtime_cast/*.hpp ]
|
||||
:
|
||||
<doxygen:param>EXTRACT_ALL=NO
|
||||
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
||||
@ -35,3 +36,12 @@ boostbook standalone
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
|
||||
;
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc
|
||||
: type_index
|
||||
:
|
||||
: <dependency>autodoc
|
||||
: ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease ;
|
||||
explicit boostrelease ;
|
||||
|
@ -1,7 +1,7 @@
|
||||
[library Boost.TypeIndex
|
||||
[quickbook 1.6]
|
||||
[version 4.1]
|
||||
[copyright 2012-2016 Antony Polukhin]
|
||||
[copyright 2012-2022 Antony Polukhin]
|
||||
[category Language Features Emulation]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
@ -246,6 +246,10 @@ Depending on the `typeid()` availability TypeIndex library will choose an optima
|
||||
[macroref BOOST_TYPE_INDEX_REGISTER_CLASS] macro is a helper macro that places some virtual helper functions or
|
||||
expands to nothing.
|
||||
|
||||
[macroref BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS] macro is a helper macro that places the same
|
||||
helpers as BOOST_TYPE_INDEX_REGISTER_CLASS plus some additional helpers for boost::typeindex::runtime_cast
|
||||
to function.
|
||||
|
||||
Issues with cross module type comparison on a bugged compilers are bypassed by directly comparing strings with type
|
||||
(latest versions of those compilers resolved that issue using exactly the same approach).
|
||||
|
||||
@ -262,6 +266,9 @@ Issues with cross module type comparison on a bugged compilers are bypassed by d
|
||||
[import ../examples/inheritance.cpp]
|
||||
[section Getting through the inheritance to receive a real type name ] [type_index_derived_example] [endsect]
|
||||
|
||||
[import ../examples/runtime_cast.cpp]
|
||||
[section Using runtime_cast where RTTI is unavailable or undesirable ] [type_index_runtime_cast_example] [endsect]
|
||||
|
||||
[import ../examples/exact_types_match.cpp]
|
||||
[section Exact type matching: storing type with const, volatile and reference qualifiers] [type_index_exact_type_match_example] [endsect]
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2016 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
@ -6,6 +6,12 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
template <class T>
|
||||
void do_something(const T&) {}
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||
// Implementation of this function is not essential for the example
|
||||
template <std::size_t N>
|
||||
@ -62,6 +68,7 @@ namespace my_project {
|
||||
|
||||
// Actual implementation of the serialization goes below
|
||||
// ...
|
||||
do_something(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2016 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && (!defined(_MSC_VER) || (_MSC_VER > 1916))
|
||||
|
||||
//[type_index_constexpr14_sort_check_example
|
||||
/*`
|
||||
@ -55,7 +55,7 @@ constexpr bool is_asc_sorted(types<Lhs, Rhs, TN...>) noexcept {
|
||||
|
||||
// Using the newly created `is_asc_sorted` trait:
|
||||
template <class... T>
|
||||
void do_something(const types<T...>& t) noexcept {
|
||||
void do_something(const types<T...>& /*value*/) noexcept {
|
||||
static_assert(
|
||||
is_asc_sorted( types<T...>() ),
|
||||
"T... for do_something(const types<T...>& t) must be sorted ascending"
|
||||
@ -68,7 +68,7 @@ int main() {
|
||||
}
|
||||
//] [/type_index_constexpr14_sort_check_example]
|
||||
|
||||
#else // #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#else // #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && (!defined(_MSC_VER) || (_MSC_VER > 1916))
|
||||
|
||||
int main() {}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2014 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2015 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
@ -17,10 +17,14 @@
|
||||
#include <boost/type_index.hpp>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
|
||||
//<-
|
||||
// Making `#include <cassert>` visible in docs, while actually using hand-made check
|
||||
// instead of `assert`. This is required to verify correct behavior even if NDEBUG
|
||||
// is defined and to avoid `unused local variable` warnings with defined NDEBUG.
|
||||
//
|
||||
// boost-no-inspect
|
||||
#ifdef assert
|
||||
# undef assert
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2014 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/type_index/runtime_cast/register_runtime_class.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct A {
|
||||
@ -21,6 +22,7 @@ struct A {
|
||||
};
|
||||
struct B: public A { BOOST_TYPE_INDEX_REGISTER_CLASS };
|
||||
struct C: public B { BOOST_TYPE_INDEX_REGISTER_CLASS };
|
||||
struct D: public C { BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS) };
|
||||
|
||||
void print_real_type(const A& a) {
|
||||
std::cout << boost::typeindex::type_id_runtime(a).pretty_name() << '\n';
|
||||
@ -31,6 +33,15 @@ int main() {
|
||||
const A& c_as_a = c;
|
||||
print_real_type(c_as_a); // Outputs `struct C`
|
||||
print_real_type(B()); // Outputs `struct B`
|
||||
|
||||
/*`
|
||||
It's also possible to use type_id_runtime with the BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS, which adds additional
|
||||
information for runtime_cast to work.
|
||||
*/
|
||||
D d;
|
||||
const A& d_as_a = d;
|
||||
print_real_type(d_as_a); // Outputs `struct D`
|
||||
|
||||
}
|
||||
|
||||
//] [/type_index_derived_example]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2015 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
@ -11,12 +11,13 @@
|
||||
*/
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/unordered/unordered_set.hpp>
|
||||
//<-
|
||||
// Making `#include <cassert>` visible in docs, while actually using `BOOST_TEST`
|
||||
// instead of `assert`. This is required to verify correct behavior even if NDEBUG
|
||||
// is defined and to avoid `unused local variable` warnings with defined NDEBUG.
|
||||
//
|
||||
// boost-no-inspect
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#ifdef assert
|
||||
# undef assert
|
||||
@ -46,6 +47,9 @@ int main() {
|
||||
|
||||
// We have erased the `float` type, only `int` remains
|
||||
assert(*types.begin() == boost::typeindex::type_id<int>());
|
||||
//<-
|
||||
return boost::report_errors();
|
||||
//->
|
||||
}
|
||||
|
||||
//] [/type_index_registry_example]
|
||||
|
90
examples/runtime_cast.cpp
Normal file
90
examples/runtime_cast.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
//[type_index_runtime_cast_example
|
||||
/*`
|
||||
The following example shows that `runtime_cast` is able to find a valid pointer
|
||||
in various class hierarchies regardless of inheritance or type relation.
|
||||
|
||||
Example works with and without RTTI."
|
||||
*/
|
||||
|
||||
#include <boost/type_index/runtime_cast.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct A {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
virtual ~A()
|
||||
{}
|
||||
};
|
||||
|
||||
struct B {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
virtual ~B()
|
||||
{}
|
||||
};
|
||||
|
||||
struct C : A {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((A))
|
||||
};
|
||||
|
||||
struct D : B {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((B))
|
||||
};
|
||||
|
||||
struct E : C, D {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((C)(D))
|
||||
};
|
||||
|
||||
int main() {
|
||||
C c;
|
||||
A* a = &c;
|
||||
|
||||
if(C* cp = boost::typeindex::runtime_cast<C*>(a)) {
|
||||
std::cout << "Yes, a points to a C: "
|
||||
<< a << "->" << cp << '\n';
|
||||
}
|
||||
else {
|
||||
std::cout << "Error: Expected a to point to a C" << '\n';
|
||||
}
|
||||
|
||||
if(E* ce = boost::typeindex::runtime_cast<E*>(a)) {
|
||||
std::cout << "Error: Expected a to not points to an E: "
|
||||
<< a << "->" << ce << '\n';
|
||||
}
|
||||
else {
|
||||
std::cout << "But, a does not point to an E" << '\n';
|
||||
}
|
||||
|
||||
E e;
|
||||
C* cp2 = &e;
|
||||
if(D* dp = boost::typeindex::runtime_cast<D*>(cp2)) {
|
||||
std::cout << "Yes, we can cross-cast from a C* to a D* when we actually have an E: "
|
||||
<< cp2 << "->" << dp << '\n';
|
||||
}
|
||||
else {
|
||||
std::cout << "Error: Expected cp to point to a D" << '\n';
|
||||
}
|
||||
|
||||
/*`
|
||||
Alternatively, we can use runtime_pointer_cast so we don't need to specity the target as a pointer.
|
||||
This works for smart_ptr types too.
|
||||
*/
|
||||
A* ap = &e;
|
||||
if(B* bp = boost::typeindex::runtime_pointer_cast<B>(ap)) {
|
||||
std::cout << "Yes, we can cross-cast and up-cast at the same time."
|
||||
<< ap << "->" << bp << '\n';
|
||||
}
|
||||
else {
|
||||
std::cout << "Error: Expected ap to point to a B" << '\n';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//] [/type_index_runtime_cast_example]
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2014 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2015 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
@ -18,6 +18,7 @@
|
||||
#include <boost/type_index.hpp>
|
||||
//] [/type_index_my_type_index_worldwide_macro]
|
||||
|
||||
// boost-no-inspect
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#ifdef assert
|
||||
# undef assert
|
||||
@ -64,6 +65,9 @@ int main() {
|
||||
assert(worldwide.pretty_name() == "my_classes");
|
||||
assert(worldwide == my_type_index::type_id<my_classes>());
|
||||
//][/type_index_my_type_index_worldwide_usage]
|
||||
//<-
|
||||
return boost::report_errors();
|
||||
//->
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2013-2014 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
@ -47,11 +47,20 @@ namespace my_namespace { namespace detail {
|
||||
template <> struct typenum<my_classes>{ enum {value = 3}; };
|
||||
template <> struct typenum<my_string>{ enum {value = 4}; };
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4510 4512 4610) // non-copyable non-constructable type
|
||||
#endif
|
||||
|
||||
// my_typeinfo structure is used to save type number
|
||||
struct my_typeinfo {
|
||||
const char* const type_;
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
const my_typeinfo infos[5] = {
|
||||
{"void"}, {"my_class"}, {"my_struct"}, {"my_classes"}, {"my_string"}
|
||||
};
|
||||
@ -70,7 +79,15 @@ namespace my_namespace { namespace detail {
|
||||
`my_type_index` is a user created type_index class. If in doubt during this phase, you can always
|
||||
take a look at the `<boost/type_index/ctti_type_index.hpp>` or `<boost/type_index/stl_type_index.hpp>`
|
||||
files. Documentation for `type_index_facade` could be also useful.
|
||||
*/
|
||||
|
||||
/*`
|
||||
Since we are not going to override `type_index_facade::hash_code()` we must additionally include
|
||||
`<boost/container_hash/hash.hpp>`.
|
||||
*/
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
/*`
|
||||
See implementation of `my_type_index`:
|
||||
*/
|
||||
namespace my_namespace {
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2014.
|
||||
// Copyright 2012-2022 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)
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2013-2016.
|
||||
// Copyright 2013-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -22,6 +22,7 @@
|
||||
#include <boost/type_index/detail/compile_time_type_info.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2016.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -11,17 +11,30 @@
|
||||
|
||||
/// \file compile_time_type_info.hpp
|
||||
/// \brief Contains helper macros and implementation details of boost::typeindex::ctti_type_index.
|
||||
/// Not intended for inclusion from user's code.
|
||||
/// Not intended for inclusion from user's code.
|
||||
|
||||
#include <cstring>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/// @cond
|
||||
#if defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_constant_p)
|
||||
#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
|
||||
#endif
|
||||
#if __has_builtin(__builtin_strcmp)
|
||||
#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2)
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
|
||||
#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2)
|
||||
#endif
|
||||
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(begin_skip, end_skip, runtime_skip, runtime_skip_until) \
|
||||
namespace boost { namespace typeindex { namespace detail { \
|
||||
BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_begin = begin_skip; \
|
||||
@ -38,10 +51,10 @@
|
||||
#elif defined(BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING)
|
||||
# include <boost/preprocessor/facilities/expand.hpp>
|
||||
BOOST_PP_EXPAND( BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING )
|
||||
#elif defined(_MSC_VER) && defined (BOOST_NO_CXX11_NOEXCEPT)
|
||||
#elif defined(_MSC_VER) && !defined(__clang__) && defined (BOOST_NO_CXX11_NOEXCEPT)
|
||||
// sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "")
|
||||
#elif defined(_MSC_VER) && !defined (BOOST_NO_CXX11_NOEXCEPT)
|
||||
#elif defined(_MSC_VER) && !defined(__clang__) && !defined (BOOST_NO_CXX11_NOEXCEPT)
|
||||
// sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void) noexcept") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 19, false, "")
|
||||
#elif defined(__clang__) && defined(__APPLE__)
|
||||
@ -59,12 +72,26 @@
|
||||
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "int>::n() [T = int"
|
||||
// note: checked on 3.1, 3.4
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
|
||||
#elif defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static contexpr char boost::detail::ctti<T>::s() [with long unsigned int I = 0ul; T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(87, 1, false, "")
|
||||
#elif defined(__EDG__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static cha boost::detail::ctti<T>::s() [with I = 40U, T = ") - 1, sizeof("]") - 1
|
||||
// note: checked on 4.14
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(58, 1, false, "")
|
||||
#elif defined(__EDG__) && defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static const char *boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
|
||||
// note: checked on 4.14
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
|
||||
#elif defined(__GNUC__) && (__GNUC__ < 7) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static constexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0u; T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(81, 1, false, "")
|
||||
#elif defined(__GNUC__) && (__GNUC__ >= 7) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static constexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0; T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(80, 1, false, "")
|
||||
#elif defined(__GNUC__) && defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
|
||||
#elif defined(__ghs__)
|
||||
// sizeof("static const char *boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
|
||||
#else
|
||||
// Deafult code for other platforms... Just skip nothing!
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "")
|
||||
@ -72,7 +99,7 @@
|
||||
|
||||
#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
template <bool Condition>
|
||||
BOOST_CXX14_CONSTEXPR inline void assert_compile_time_legths() BOOST_NOEXCEPT {
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
@ -94,8 +121,19 @@ namespace boost { namespace typeindex { namespace detail {
|
||||
);
|
||||
}
|
||||
|
||||
template <std::size_t ArrayLength>
|
||||
BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::mpl::false_) BOOST_NOEXCEPT {
|
||||
#if defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT)
|
||||
BOOST_CXX14_CONSTEXPR BOOST_FORCEINLINE bool is_constant_string(const char* str) BOOST_NOEXCEPT {
|
||||
while (BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(*str)) {
|
||||
if (*str == '\0')
|
||||
return true;
|
||||
++str;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT)
|
||||
|
||||
template <unsigned int ArrayLength>
|
||||
BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::false_type) BOOST_NOEXCEPT {
|
||||
return begin;
|
||||
}
|
||||
|
||||
@ -127,17 +165,29 @@ namespace boost { namespace typeindex { namespace detail {
|
||||
return last1;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp(const char *v1, const char *v2) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp_loop(const char *v1, const char *v2) BOOST_NOEXCEPT {
|
||||
while (*v1 != '\0' && *v1 == *v2) {
|
||||
++v1;
|
||||
++v2;
|
||||
};
|
||||
}
|
||||
|
||||
return static_cast<int>(*v1) - *v2;
|
||||
}
|
||||
|
||||
template <std::size_t ArrayLength>
|
||||
BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::mpl::true_) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp(const char *v1, const char *v2) BOOST_NOEXCEPT {
|
||||
#if !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT) && defined(BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP)
|
||||
if (boost::typeindex::detail::is_constant_string(v1) && boost::typeindex::detail::is_constant_string(v2))
|
||||
return boost::typeindex::detail::constexpr_strcmp_loop(v1, v2);
|
||||
return BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(v1, v2);
|
||||
#elif !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
return boost::typeindex::detail::constexpr_strcmp_loop(v1, v2);
|
||||
#else
|
||||
return std::strcmp(v1, v2);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <unsigned int ArrayLength>
|
||||
BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::true_type) BOOST_NOEXCEPT {
|
||||
const char* const it = constexpr_search(
|
||||
begin, begin + ArrayLength,
|
||||
ctti_skip_until_runtime, ctti_skip_until_runtime + sizeof(ctti_skip_until_runtime) - 1
|
||||
@ -145,28 +195,28 @@ namespace boost { namespace typeindex { namespace detail {
|
||||
return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1);
|
||||
}
|
||||
|
||||
template <std::size_t ArrayLength>
|
||||
template <unsigned int ArrayLength>
|
||||
BOOST_CXX14_CONSTEXPR inline const char* skip_begining(const char* begin) BOOST_NOEXCEPT {
|
||||
assert_compile_time_legths<(ArrayLength > ctti_skip_size_at_begin + ctti_skip_size_at_end)>();
|
||||
return skip_begining_runtime<ArrayLength - ctti_skip_size_at_begin>(
|
||||
begin + ctti_skip_size_at_begin,
|
||||
boost::mpl::bool_<ctti_skip_more_at_runtime>()
|
||||
begin + ctti_skip_size_at_begin,
|
||||
boost::integral_constant<bool, ctti_skip_more_at_runtime>()
|
||||
);
|
||||
}
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
template <std::size_t... I>
|
||||
template <unsigned int... I>
|
||||
struct index_seq {};
|
||||
|
||||
template <typename Left, typename Right>
|
||||
struct make_index_sequence_join;
|
||||
|
||||
template <std::size_t... Left, std::size_t... Right>
|
||||
template <unsigned int... Left, unsigned int... Right>
|
||||
struct make_index_sequence_join<index_seq<Left...>, index_seq<Right...> > {
|
||||
typedef index_seq<Left..., Right...> type;
|
||||
};
|
||||
|
||||
template <std::size_t C, std::size_t D>
|
||||
template <unsigned int C, unsigned int D>
|
||||
struct make_index_seq_impl {
|
||||
typedef typename make_index_sequence_join<
|
||||
typename make_index_seq_impl<C, D / 2>::type,
|
||||
@ -174,19 +224,19 @@ namespace boost { namespace typeindex { namespace detail {
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <std::size_t C>
|
||||
template <unsigned int C>
|
||||
struct make_index_seq_impl<C, 0> {
|
||||
typedef index_seq<> type;
|
||||
};
|
||||
|
||||
template <std::size_t C>
|
||||
template <unsigned int C>
|
||||
struct make_index_seq_impl<C, 1> {
|
||||
typedef index_seq<C> type;
|
||||
};
|
||||
|
||||
template <char... C>
|
||||
struct cstring {
|
||||
static constexpr std::size_t size_ = sizeof...(C);
|
||||
static constexpr unsigned int size_ = sizeof...(C);
|
||||
static constexpr char data_[size_] = { C... };
|
||||
};
|
||||
|
||||
@ -203,12 +253,12 @@ namespace boost { namespace detail {
|
||||
/// This name must be as short as possible, to avoid code bloat
|
||||
template <class T>
|
||||
struct ctti {
|
||||
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
//helper functions
|
||||
template <std::size_t I>
|
||||
template <unsigned int I>
|
||||
constexpr static char s() BOOST_NOEXCEPT { // step
|
||||
constexpr std::size_t offset =
|
||||
constexpr unsigned int offset =
|
||||
(I >= 10u ? 1u : 0u)
|
||||
+ (I >= 100u ? 1u : 0u)
|
||||
+ (I >= 1000u ? 1u : 0u)
|
||||
@ -226,17 +276,17 @@ struct ctti {
|
||||
#endif
|
||||
}
|
||||
|
||||
template <std::size_t ...Indexes>
|
||||
template <unsigned int ...Indexes>
|
||||
constexpr static const char* impl(::boost::typeindex::detail::index_seq<Indexes...> ) BOOST_NOEXCEPT {
|
||||
return ::boost::typeindex::detail::cstring<s<Indexes>()...>::data_;
|
||||
}
|
||||
|
||||
template <std::size_t D = 0> // `D` means `Dummy`
|
||||
template <unsigned int D = 0> // `D` means `Dummy`
|
||||
constexpr static const char* n() BOOST_NOEXCEPT {
|
||||
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
constexpr std::size_t size = sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
|
||||
constexpr unsigned int size = sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
|
||||
#elif defined(__FUNCSIG__)
|
||||
constexpr std::size_t size = sizeof(__FUNCSIG__);
|
||||
constexpr unsigned int size = sizeof(__FUNCSIG__);
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
|| defined(__GNUC__) \
|
||||
|| (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
|
||||
@ -244,9 +294,9 @@ struct ctti {
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__)
|
||||
constexpr std::size_t size = sizeof(__PRETTY_FUNCTION__);
|
||||
constexpr unsigned int size = sizeof(__PRETTY_FUNCTION__);
|
||||
#else
|
||||
boost::typeindex::detail::failed_to_get_function_name();
|
||||
boost::typeindex::detail::failed_to_get_function_name<T>();
|
||||
#endif
|
||||
|
||||
boost::typeindex::detail::assert_compile_time_legths<
|
||||
@ -273,10 +323,11 @@ struct ctti {
|
||||
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__)
|
||||
|| defined(__DMC__) \
|
||||
|| defined(__clang__)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
|
||||
#else
|
||||
boost::typeindex::detail::failed_to_get_function_name();
|
||||
boost::typeindex::detail::failed_to_get_function_name<T>();
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
@ -286,4 +337,3 @@ struct ctti {
|
||||
}} // namespace boost::detail
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2013-2014.
|
||||
// Copyright 2013-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2013-2014.
|
||||
// Copyright 2013-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
28
include/boost/type_index/runtime_cast.hpp
Normal file
28
include/boost/type_index/runtime_cast.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_HPP
|
||||
#define BOOST_TYPE_INDEX_RUNTIME_CAST_HPP
|
||||
|
||||
/// \file runtime_cast.hpp
|
||||
/// \brief Contains the basic utilities necessary to fully emulate
|
||||
/// dynamic_cast for language level constructs (raw pointers and references).
|
||||
///
|
||||
/// boost::typeindex::runtime_cast is a drop in replacement for dynamic_cast
|
||||
/// that can be used in situations where traditional rtti is either unavailable
|
||||
/// or undesirable.
|
||||
|
||||
#include <boost/type_index/runtime_cast/register_runtime_class.hpp>
|
||||
#include <boost/type_index/runtime_cast/pointer_cast.hpp>
|
||||
#include <boost/type_index/runtime_cast/reference_cast.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_HPP
|
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_BOOST_SHARED_PTR_CAST_HPP
|
||||
#define BOOST_TYPE_INDEX_RUNTIME_CAST_BOOST_SHARED_PTR_CAST_HPP
|
||||
|
||||
/// \file boost_shared_ptr_cast.hpp
|
||||
/// \brief Contains the overload of boost::typeindex::runtime_pointer_cast for
|
||||
/// boost::shared_ptr types.
|
||||
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
template<class T> class shared_ptr;
|
||||
}
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \brief Creates a new instance of std::shared_ptr whose stored pointer is obtained from u's
|
||||
/// stored pointer using a runtime_cast.
|
||||
///
|
||||
/// The new shared_ptr will share ownership with u, except that it is empty if the runtime_cast
|
||||
/// performed by runtime_pointer_cast returns a null pointer.
|
||||
/// \tparam T The desired target type to return a pointer of.
|
||||
/// \tparam U A complete class type of the source instance pointed to from u.
|
||||
/// \return If there exists a valid conversion from U* to T*, returns a boost::shared_ptr<T>
|
||||
/// that points to an address suitably offset from u.
|
||||
/// If no such conversion exists, returns boost::shared_ptr<T>();
|
||||
template<typename T, typename U>
|
||||
boost::shared_ptr<T> runtime_pointer_cast(boost::shared_ptr<U> const& u) {
|
||||
T* value = detail::runtime_cast_impl<T>(u.get(), boost::is_base_and_derived<T, U>());
|
||||
if(value)
|
||||
return boost::shared_ptr<T>(u, value);
|
||||
return boost::shared_ptr<T>();
|
||||
}
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_BOOST_SHARED_PTR_CAST_HPP
|
@ -0,0 +1,57 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_DETAIL_RUNTIME_CAST_IMPL_HPP
|
||||
#define BOOST_TYPE_INDEX_RUNTIME_CAST_DETAIL_RUNTIME_CAST_IMPL_HPP
|
||||
|
||||
/// \file runtime_cast_impl.hpp
|
||||
/// \brief Contains the overload of boost::typeindex::runtime_cast for
|
||||
/// pointer types.
|
||||
///
|
||||
/// boost::typeindex::runtime_cast can be used to emulate dynamic_cast
|
||||
/// functionality on platorms that don't provide it or should the user
|
||||
/// desire opt in functionality instead of enabling it system wide.
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T, typename U>
|
||||
T* runtime_cast_impl(U* u, boost::true_type) BOOST_NOEXCEPT {
|
||||
return u;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
T const* runtime_cast_impl(U const* u, boost::true_type) BOOST_NOEXCEPT {
|
||||
return u;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
T* runtime_cast_impl(U* u, boost::false_type) BOOST_NOEXCEPT {
|
||||
return const_cast<T*>(static_cast<T const*>(
|
||||
u->boost_type_index_find_instance_(boost::typeindex::type_id<T>())
|
||||
));
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
T const* runtime_cast_impl(U const* u, boost::false_type) BOOST_NOEXCEPT {
|
||||
return static_cast<T const*>(u->boost_type_index_find_instance_(boost::typeindex::type_id<T>()));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_DETAIL_RUNTIME_CAST_IMPL_HPP
|
74
include/boost/type_index/runtime_cast/pointer_cast.hpp
Normal file
74
include/boost/type_index/runtime_cast/pointer_cast.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_POINTER_CAST_HPP
|
||||
#define BOOST_TYPE_INDEX_RUNTIME_CAST_POINTER_CAST_HPP
|
||||
|
||||
/// \file pointer_class.hpp
|
||||
/// \brief Contains the function overloads of boost::typeindex::runtime_cast for
|
||||
/// pointer types.
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \brief Safely converts pointers to classes up, down, and sideways along the inheritance hierarchy.
|
||||
/// \tparam T The desired target type. Like dynamic_cast, must be a pointer to complete class type.
|
||||
/// \tparam U A complete class type of the source instance, u.
|
||||
/// \return If there exists a valid conversion from U* to T, returns a T that points to
|
||||
/// an address suitably offset from u. If no such conversion exists, returns NULL.
|
||||
template<typename T, typename U>
|
||||
T runtime_cast(U* u) BOOST_NOEXCEPT {
|
||||
typedef typename boost::remove_pointer<T>::type impl_type;
|
||||
return detail::runtime_cast_impl<impl_type>(u, boost::is_base_and_derived<T, U>());
|
||||
}
|
||||
|
||||
/// \brief Safely converts pointers to classes up, down, and sideways along the inheritance hierarchy.
|
||||
/// \tparam T The desired target type. Like dynamic_cast, must be a pointer to complete class type.
|
||||
/// \tparam U A complete class type of the source instance, u.
|
||||
/// \return If there exists a valid conversion from U* to T, returns a T that points to
|
||||
/// an address suitably offset from u. If no such conversion exists, returns NULL.
|
||||
template<typename T, typename U>
|
||||
T runtime_cast(U const* u) BOOST_NOEXCEPT {
|
||||
typedef typename boost::remove_pointer<T>::type impl_type;
|
||||
return detail::runtime_cast_impl<impl_type>(u, boost::is_base_and_derived<T, U>());
|
||||
}
|
||||
|
||||
/// \brief Safely converts pointers to classes up, down, and sideways along the inheritance
|
||||
/// hierarchy.
|
||||
/// \tparam T The desired target type to return a pointer to.
|
||||
/// \tparam U A complete class type of the source instance, u.
|
||||
/// \return If there exists a valid conversion from U const* to T*, returns a T*
|
||||
/// that points to an address suitably offset from u.
|
||||
/// If no such conversion exists, returns NULL.
|
||||
template<typename T, typename U>
|
||||
T* runtime_pointer_cast(U* u) BOOST_NOEXCEPT {
|
||||
return detail::runtime_cast_impl<T>(u, boost::is_base_and_derived<T, U>());
|
||||
}
|
||||
|
||||
/// \brief Safely converts pointers to classes up, down, and sideways along the inheritance
|
||||
/// hierarchy.
|
||||
/// \tparam T The desired target type to return a pointer to.
|
||||
/// \tparam U A complete class type of the source instance, u.
|
||||
/// \return If there exists a valid conversion from U const* to T const*, returns a T const*
|
||||
/// that points to an address suitably offset from u.
|
||||
/// If no such conversion exists, returns NULL.
|
||||
template<typename T, typename U>
|
||||
T const* runtime_pointer_cast(U const* u) BOOST_NOEXCEPT {
|
||||
return detail::runtime_cast_impl<T>(u, boost::is_base_and_derived<T, U>());
|
||||
}
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_POINTER_CAST_HPP
|
66
include/boost/type_index/runtime_cast/reference_cast.hpp
Normal file
66
include/boost/type_index/runtime_cast/reference_cast.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_REFERENCE_CAST_HPP
|
||||
#define BOOST_TYPE_INDEX_RUNTIME_CAST_REFERENCE_CAST_HPP
|
||||
|
||||
/// \file reference_cast.hpp
|
||||
/// \brief Contains the overload of boost::typeindex::runtime_cast for
|
||||
/// reference types.
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \brief Indicates that runtime_cast was unable to perform the desired cast operation
|
||||
/// because the source instance was not also an instance of the target type.
|
||||
struct bad_runtime_cast : std::exception
|
||||
{};
|
||||
|
||||
/// \brief Safely converts references to classes up, down, and sideways along the inheritance hierarchy.
|
||||
/// \tparam T The desired target type. Like dynamic_cast, must be a pointer to complete class type.
|
||||
/// \tparam U A complete class type of the source instance, u.
|
||||
/// \return If there exists a valid conversion from U& to T, returns a T that references an address
|
||||
/// suitably offset from u. If no such conversion exists, throws boost::typeindex::bad_runtime_cast.
|
||||
template<typename T, typename U>
|
||||
typename boost::add_reference<T>::type runtime_cast(U& u) {
|
||||
typedef typename boost::remove_reference<T>::type impl_type;
|
||||
impl_type* value = detail::runtime_cast_impl<impl_type>(
|
||||
boost::addressof(u), boost::is_base_and_derived<T, U>());
|
||||
if(!value)
|
||||
BOOST_THROW_EXCEPTION(bad_runtime_cast());
|
||||
return *value;
|
||||
}
|
||||
|
||||
/// \brief Safely converts references to classes up, down, and sideways along the inheritance hierarchy.
|
||||
/// \tparam T The desired target type. Like dynamic_cast, must be a pointer to complete class type.
|
||||
/// \tparam U A complete class type of the source instance, u.
|
||||
/// \return If there exists a valid conversion from U const& to T const, returns a T const that references an address
|
||||
/// suitably offset from u. If no such conversion exists, throws boost::typeindex::bad_runtime_cast.
|
||||
template<typename T, typename U>
|
||||
typename boost::add_reference<const T>::type runtime_cast(U const& u) {
|
||||
typedef typename boost::remove_reference<T>::type impl_type;
|
||||
impl_type* value = detail::runtime_cast_impl<impl_type>(
|
||||
boost::addressof(u), boost::is_base_and_derived<T, U>());
|
||||
if(!value)
|
||||
BOOST_THROW_EXCEPTION(bad_runtime_cast());
|
||||
return *value;
|
||||
}
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_REFERENCE_CAST_HPP
|
138
include/boost/type_index/runtime_cast/register_runtime_class.hpp
Normal file
138
include/boost/type_index/runtime_cast/register_runtime_class.hpp
Normal file
@ -0,0 +1,138 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_REGISTER_RUNTIME_CLASS_HPP
|
||||
#define BOOST_TYPE_INDEX_RUNTIME_CAST_REGISTER_RUNTIME_CLASS_HPP
|
||||
|
||||
/// \file register_runtime_class.hpp
|
||||
/// \brief Contains the macros BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST and
|
||||
/// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
inline type_index runtime_class_construct_type_id(T const*) {
|
||||
return type_id<T>();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
/// @cond
|
||||
|
||||
#define BOOST_TYPE_INDEX_CHECK_BASE_(r, data, Base) \
|
||||
if(void const* ret_val = this->Base::boost_type_index_find_instance_(idx)) return ret_val;
|
||||
|
||||
/// @endcond
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS
|
||||
/// \brief Macro used to make a class compatible with boost::typeindex::runtime_cast
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS generates a virtual function
|
||||
/// in the current class that, when combined with the supplied base class information, allows
|
||||
/// boost::typeindex::runtime_cast to accurately convert between dynamic types of instances of
|
||||
/// the current class.
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS also adds support for boost::typeindex::type_id_runtime
|
||||
/// by including BOOST_TYPE_INDEX_REGISTER_CLASS. It is typical that these features are used together,
|
||||
/// but in the event that BOOST_TYPE_INDEX_REGISTER_CLASS is undesirable in the current class,
|
||||
/// BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST is provided.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
/// struct base1 {
|
||||
/// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
/// virtual ~base1();
|
||||
/// };
|
||||
///
|
||||
/// struct base2 {
|
||||
/// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
/// virtual ~base2();
|
||||
/// };
|
||||
///
|
||||
/// struct derived1 : base1 {
|
||||
/// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((base1))
|
||||
/// };
|
||||
///
|
||||
/// struct derived2 : base1, base2 {
|
||||
/// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((base1)(base2))
|
||||
/// };
|
||||
///
|
||||
/// ...
|
||||
///
|
||||
/// base1* pb1 = get_object();
|
||||
/// if(derived2* pb2 = boost::typeindex::runtime_cast<derived2*>(pb1)) {
|
||||
/// assert(boost::typeindex::type_id_runtime(*pb1)) == boost::typeindex::type_id<derived2>());
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// \param base_class_seq A Boost.Preprocessor sequence of the current class' direct bases, or
|
||||
/// BOOST_TYPE_INDEX_NO_BASE_CLASS if this class has no direct base classes.
|
||||
#define BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(base_class_seq) \
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS \
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST(base_class_seq)
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST
|
||||
/// \brief Macro used to make a class compatible with boost::typeindex::runtime_cast without including
|
||||
/// support for boost::typeindex::type_id_runtime.
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST is provided as an alternative to BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS
|
||||
/// in the event that support for boost::typeindex::type_id_runtime is undesirable.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
/// struct base1 {
|
||||
/// BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
/// virtual ~base1();
|
||||
/// };
|
||||
///
|
||||
/// struct base2 {
|
||||
/// BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
/// virtual ~base2();
|
||||
/// };
|
||||
///
|
||||
/// struct derived1 : base1 {
|
||||
/// BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base1))
|
||||
/// };
|
||||
///
|
||||
/// struct derived2 : base1, base2 {
|
||||
/// BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base1)(base2))
|
||||
/// };
|
||||
///
|
||||
/// ...
|
||||
///
|
||||
/// base1* pb1 = get_object();
|
||||
/// if(derived2* pb2 = boost::typeindex::runtime_cast<derived2*>(pb1))
|
||||
/// { /* can't call boost::typeindex::type_id_runtime(*pb1) here */ }
|
||||
/// \endcode
|
||||
///
|
||||
/// \param base_class_seq A Boost.Preprocessor sequence of the current class' direct bases, or
|
||||
/// BOOST_TYPE_INDEX_NO_BASE_CLASS if this class has no direct base classes.
|
||||
#define BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST(base_class_seq) \
|
||||
virtual void const* boost_type_index_find_instance_(boost::typeindex::type_index const& idx) const BOOST_NOEXCEPT { \
|
||||
if(idx == boost::typeindex::detail::runtime_class_construct_type_id(this)) \
|
||||
return this; \
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_INDEX_CHECK_BASE_, _, base_class_seq) \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_NO_BASE_CLASS
|
||||
/// \brief Instructs BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS and BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST
|
||||
/// that this class has no base classes.
|
||||
#define BOOST_TYPE_INDEX_NO_BASE_CLASS BOOST_PP_SEQ_NIL
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_REGISTER_RUNTIME_CLASS_HPP
|
@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_STD_SHARED_PTR_CAST_HPP
|
||||
#define BOOST_TYPE_INDEX_RUNTIME_CAST_STD_SHARED_PTR_CAST_HPP
|
||||
|
||||
/// \file std_shared_ptr_cast.hpp
|
||||
/// \brief Contains the overload of boost::typeindex::runtime_pointer_cast for
|
||||
/// std::shared_ptr types.
|
||||
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <memory>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \brief Creates a new instance of std::shared_ptr whose stored pointer is obtained from u's
|
||||
/// stored pointer using a runtime_cast.
|
||||
///
|
||||
/// The new shared_ptr will share ownership with u, except that it is empty if the runtime_cast
|
||||
/// performed by runtime_pointer_cast returns a null pointer.
|
||||
/// \tparam T The desired target type to return a pointer of.
|
||||
/// \tparam U A complete class type of the source instance pointed to from u.
|
||||
/// \return If there exists a valid conversion from U* to T*, returns a std::shared_ptr<T>
|
||||
/// that points to an address suitably offset from u.
|
||||
/// If no such conversion exists, returns std::shared_ptr<T>();
|
||||
template<typename T, typename U>
|
||||
std::shared_ptr<T> runtime_pointer_cast(std::shared_ptr<U> const& u) {
|
||||
T* value = detail::runtime_cast_impl<T>(u.get(), boost::is_base_and_derived<T, U>());
|
||||
if(value)
|
||||
return std::shared_ptr<T>(u, value);
|
||||
return std::shared_ptr<T>();
|
||||
}
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_STD_SHARED_PTR_CAST_HPP
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2013-2015.
|
||||
// Copyright 2013-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -32,19 +32,26 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/is_volatile.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER > 1600) \
|
||||
|| (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) \
|
||||
|| (defined(__GNUC__) && __GNUC__ > 4 && __cplusplus >= 201103)
|
||||
# define BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
|
||||
#else
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
# include <boost/type_traits/is_signed.hpp>
|
||||
# include <boost/type_traits/make_signed.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
# include <boost/type_traits/type_identity.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
@ -174,7 +181,7 @@ inline std::string stl_type_index::pretty_name() const {
|
||||
|
||||
|
||||
inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
|
||||
#if _MSC_VER > 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||
#ifdef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
|
||||
return data_->hash_code();
|
||||
#else
|
||||
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
|
||||
@ -191,13 +198,13 @@ inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
|
||||
|| (defined(__sgi) && defined(__host_mips)) \
|
||||
|| (defined(__hpux) && defined(__HP_aCC)) \
|
||||
|| (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
|
||||
# define BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
# define BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
|
||||
# endif
|
||||
|
||||
/// @endcond
|
||||
|
||||
inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
#ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
|
||||
return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
|
||||
#else
|
||||
return !!(*data_ == *rhs.data_);
|
||||
@ -205,17 +212,14 @@ inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEP
|
||||
}
|
||||
|
||||
inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
#ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
|
||||
return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
|
||||
#else
|
||||
return !!data_->before(*rhs.data_);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
#undef BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
#endif
|
||||
|
||||
#undef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
|
||||
|
||||
|
||||
template <class T>
|
||||
@ -228,10 +232,10 @@ inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT {
|
||||
|
||||
// Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
|
||||
// in typeid() expressions. Full template specialization for 'integral' fixes that issue:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
|
||||
boost::is_signed<no_cvr_prefinal_t>,
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
|
||||
boost::is_signed<no_cvr_prefinal_t>::value,
|
||||
boost::make_signed<no_cvr_prefinal_t>,
|
||||
boost::mpl::identity<no_cvr_prefinal_t>
|
||||
boost::type_identity<no_cvr_prefinal_t>
|
||||
>::type no_cvr_prefinal_lazy_t;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t;
|
||||
@ -248,8 +252,8 @@ namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
|
||||
boost::mpl::or_<boost::is_reference<T>, boost::is_const<T>, boost::is_volatile<T> >,
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
|
||||
boost::is_reference<T>::value || boost::is_const<T>::value || boost::is_volatile<T>::value,
|
||||
detail::cvr_saver<T>,
|
||||
T
|
||||
>::type type;
|
||||
@ -269,4 +273,6 @@ inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEX
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#undef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2013-2015.
|
||||
// Copyright 2013-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -10,6 +10,7 @@
|
||||
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
@ -25,11 +26,6 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// Forward declaration from #include <boost/functional/hash_fwd.hpp>
|
||||
namespace boost {
|
||||
template <class It> std::size_t hash_range(It, It);
|
||||
}
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \class type_index_facade
|
||||
@ -103,7 +99,8 @@ public:
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Hash code of a type. By default hashes types by raw_name().
|
||||
/// \note <boost/functional/hash.hpp> has to be included if this function is used.
|
||||
/// \note Derived class header \b must include <boost/container_hash/hash.hpp>, \b unless this function is redefined in
|
||||
/// Derived class to not use boost::hash_range().
|
||||
inline std::size_t hash_code() const BOOST_NOEXCEPT {
|
||||
const char* const name_raw = derived().raw_name();
|
||||
return boost::hash_range(name_raw, name_raw + std::strlen(name_raw));
|
||||
@ -288,7 +285,7 @@ inline std::basic_ostream<CharT, TriatT>& operator<<(
|
||||
#endif // BOOST_NO_IOSTREAM
|
||||
|
||||
/// This free function is used by Boost's unordered containers.
|
||||
/// \note <boost/functional/hash.hpp> has to be included if this function is used.
|
||||
/// \note <boost/container_hash/hash.hpp> has to be included if this function is used.
|
||||
template <class Derived, class TypeInfo>
|
||||
inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) BOOST_NOEXCEPT {
|
||||
return static_cast<Derived const&>(lhs).hash_code();
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (c) 2014 Antony Polukhin
|
||||
Copyright 2014-2022 Antony Polukhin
|
||||
antoshkka at gmail dot com
|
||||
|
||||
Distributed under the Boost Software License,
|
||||
@ -10,7 +10,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="0; url=../../doc/html/boost_typeindex.html">
|
||||
<meta http-equiv="refresh" content="0; url=https://www.boost.org/doc/libs/master/doc/html/boost_typeindex.html">
|
||||
<title>Boost.TypeIndex</title>
|
||||
<style>
|
||||
body {
|
||||
@ -26,10 +26,10 @@
|
||||
<body>
|
||||
<p>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="../../doc/html/boost_typeindex.html">../../doc/html/boost_typeindex.html</a>
|
||||
<a href="https://www.boost.org/doc/libs/master/doc/html/boost_typeindex.html">https://www.boost.org/doc/libs/master/doc/html/boost_typeindex.html</a>
|
||||
</p>
|
||||
<p>
|
||||
© 2014 Antony Polukhin
|
||||
© 2014-2022 Antony Polukhin
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -10,5 +10,6 @@
|
||||
"description": "Runtime/Compile time copyable type info.",
|
||||
"category": [
|
||||
"Emulation"
|
||||
]
|
||||
],
|
||||
"cxxstd": "03"
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2012-2014 Antony Polukhin
|
||||
# Copyright 2012-2022 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)
|
||||
@ -13,9 +13,9 @@ compat = <define>BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY ;
|
||||
|
||||
# Making own `nortti` that is link compatible.
|
||||
# We explicitly define BOOST_NO_RTTI because it sometimes can not be detected by build system.
|
||||
nortti = <toolset>gcc:"<cxxflags>-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>clang:"<cxxflags>-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>intel:"<cxxflags>-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>darwin:"<cxxflags>-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>msvc:<cxxflags>/GR- ;
|
||||
nortti = <toolset>gcc:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>clang:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>intel:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>darwin:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>msvc:<cxxflags>"/GR-" ;
|
||||
|
||||
norttidefines = <toolset>gcc:"<cxxflags>-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>clang:"<cxxflags>-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>intel:"<cxxflags>-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>darwin:"<cxxflags>-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>msvc:<cxxflags>-DBOOST_NO_RTTI ;
|
||||
norttidefines = <toolset>gcc:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>clang:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>intel:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>darwin:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>msvc:<cxxflags>"-DBOOST_NO_RTTI" ;
|
||||
|
||||
|
||||
# Making libraries that CANNOT work between rtti-on/rtti-off modules
|
||||
@ -40,22 +40,27 @@ exe testing_crossmodule_anonymous_no_rtti : testing_crossmodule_anonymous.cpp te
|
||||
test-suite type_index
|
||||
:
|
||||
[ run type_index_test.cpp ]
|
||||
[ run type_index_runtime_cast_test.cpp ]
|
||||
[ run type_index_constexpr_test.cpp ]
|
||||
[ run type_index_test.cpp : : : <rtti>off $(norttidefines) : type_index_test_no_rtti ]
|
||||
[ run ctti_print_name.cpp : : : <test-info>always_show_run_output ]
|
||||
[ run testing_crossmodule.cpp test_lib_rtti ]
|
||||
[ run testing_crossmodule.cpp test_lib_nortti : : : <rtti>off $(norttidefines) : testing_crossmodule_no_rtti ]
|
||||
[ run testing_crossmodule_anonymous.cpp test_lib_anonymous_rtti ]
|
||||
[ run testing_crossmodule_anonymous.cpp test_lib_anonymous_rtti : : : <test-info>always_show_run_output ]
|
||||
[ run compare_ctti_stl.cpp ]
|
||||
[ run track_13621.cpp ]
|
||||
|
||||
[ compile-fail type_index_test_ctti_copy_fail.cpp ]
|
||||
[ compile-fail type_index_test_ctti_construct_fail.cpp ]
|
||||
[ compile type_index_test_ctti_alignment.cpp ]
|
||||
|
||||
# Mixing RTTI on and off
|
||||
[ link-fail testing_crossmodule.cpp test_lib_rtti : $(nortti) : link_fail_nortti_rtti ]
|
||||
# MSVC sometimes overrides the /GR-, without `detect_missmatch` this test may link
|
||||
[ link-fail testing_crossmodule.cpp test_lib_nortti : : link_fail_rtti_nortti ]
|
||||
|
||||
# MSVC sometimes overrides the /GR-, without `detect_missmatch` this test may link.
|
||||
# TODO: Disabled on MSVC. Enable again when there'll be an understanding of how to write this test correctly wor MSVC.
|
||||
[ link-fail testing_crossmodule.cpp test_lib_rtti : $(nortti) <toolset>msvc:<build>no : link_fail_nortti_rtti ]
|
||||
[ link-fail testing_crossmodule.cpp test_lib_nortti : <toolset>msvc:<build>no : link_fail_rtti_nortti ]
|
||||
|
||||
[ run testing_crossmodule.cpp test_lib_rtti_compat : : : $(nortti) $(compat) : testing_crossmodule_nortti_rtti_compat ]
|
||||
[ run testing_crossmodule.cpp test_lib_nortti_compat : : : $(compat) : testing_crossmodule_rtti_nortti_compat ]
|
||||
;
|
||||
|
@ -2,27 +2,26 @@
|
||||
# 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.
|
||||
# Copyright 2016-2022 Antony Polukhin.
|
||||
|
||||
#
|
||||
# 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 #1
|
||||
# File revision #6
|
||||
|
||||
init:
|
||||
- set BRANCH_TO_TEST=%APPVEYOR_REPO_BRANCH%
|
||||
- set BOOST_REMOVE=type_index
|
||||
|
||||
os: Visual Studio 2015
|
||||
configuration: Debug
|
||||
platform: x64
|
||||
# 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.61.{build}-{branch}
|
||||
version: 1.64.{build}-{branch}
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
@ -31,41 +30,59 @@ branches:
|
||||
|
||||
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
|
||||
ADDRMD: 32
|
||||
- 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 this to the name of the library
|
||||
- set PROJECT_TO_TEST=%APPVEYOR_PROJECT_NAME%
|
||||
- echo "Testing %PROJECT_TO_TEST%"
|
||||
- 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 init %BOOST%
|
||||
- git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git %BOOST%
|
||||
- cd %BOOST%
|
||||
- git remote add --no-tags -t %BRANCH_TO_TEST% origin https://github.com/boostorg/boost.git
|
||||
- git fetch --depth=1
|
||||
- git checkout %BRANCH_TO_TEST%
|
||||
- git submodule update --init --merge
|
||||
- git remote set-branches --add origin %BRANCH_TO_TEST%
|
||||
- git pull --recurse-submodules
|
||||
- git submodule update --init
|
||||
- git checkout %BRANCH_TO_TEST%
|
||||
#- git submodule foreach "git reset --quiet --hard"
|
||||
#- git submodule foreach "git clean -fxd"
|
||||
- git reset --hard
|
||||
- git clean -fxd
|
||||
- git status
|
||||
- rm -rf %BOOST%/libs/%BOOST_REMOVE%
|
||||
- mv %APPVEYOR_BUILD_FOLDER% %BOOST%/libs/%PROJECT_TO_TEST%
|
||||
- set TRAVIS_BUILD_DIR=%BOOST%/libs/%PROJECT_TO_TEST%
|
||||
- git submodule update --init --depth 10 tools/build tools/boostdep libs/unordered # Boost.TypeIndex examples need Boost.Unordered
|
||||
|
||||
- rm -rf %BOOST%/libs/%BOOST_LIBS_FOLDER%
|
||||
- mv -f %APPVEYOR_BUILD_FOLDER% %BOOST%/libs/%BOOST_LIBS_FOLDER%
|
||||
- python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 2" %BOOST_LIBS_FOLDER%
|
||||
|
||||
build_script:
|
||||
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
|
||||
- bootstrap.bat
|
||||
- cmd /c bootstrap
|
||||
- b2.exe headers
|
||||
- cd %BOOST%/libs/%PROJECT_TO_TEST%/test
|
||||
- cd %BOOST%/libs/%BOOST_LIBS_FOLDER%/test
|
||||
|
||||
after_build:
|
||||
before_test:
|
||||
test_script:
|
||||
- ..\..\..\b2.exe address-model=64 architecture=x86 cxxflags="-DBOOST_TRAVISCI_BUILD" -sBOOST_BUILD_PATH=.
|
||||
- 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:
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Klemens Morgenstern, 2012-2015.
|
||||
// Copyright 2019-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -31,26 +31,26 @@ struct my_template {};
|
||||
template<typename T>
|
||||
void compare()
|
||||
{
|
||||
typedef boost::typeindex::ctti_type_index ctti;
|
||||
typedef boost::typeindex::stl_type_index stl;
|
||||
BOOST_TEST_EQ(
|
||||
ctti::type_id<int>().pretty_name(),
|
||||
stl::type_id<int>().pretty_name()
|
||||
);
|
||||
typedef boost::typeindex::ctti_type_index ctti;
|
||||
typedef boost::typeindex::stl_type_index stl;
|
||||
BOOST_TEST_EQ(
|
||||
ctti::type_id<int>().pretty_name(),
|
||||
stl::type_id<int>().pretty_name()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
compare<void>();
|
||||
compare<int>();
|
||||
compare<double*>();
|
||||
compare<const double&>();
|
||||
compare<my_namespace1::my_class>();
|
||||
compare<void>();
|
||||
compare<int>();
|
||||
compare<double*>();
|
||||
compare<const double&>();
|
||||
compare<my_namespace1::my_class>();
|
||||
|
||||
compare<my_namespace3::my_template<
|
||||
my_namespace1::my_class,
|
||||
my_namespace2::my_class> >();
|
||||
compare<my_namespace3::my_template<
|
||||
my_namespace1::my_class,
|
||||
my_namespace2::my_class> >();
|
||||
|
||||
|
||||
return boost::report_errors();
|
||||
@ -60,7 +60,7 @@ int main()
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -17,6 +17,11 @@ namespace user_defined_namespace {
|
||||
class user_defined_class {};
|
||||
}
|
||||
|
||||
class empty
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
@ -31,6 +36,9 @@ int main()
|
||||
<< ctti_type_index::type_id<user_defined_namespace::user_defined_class>() << '\n';
|
||||
|
||||
|
||||
std::cout << "empty:"
|
||||
<< ctti_type_index::type_id<empty>() << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -31,7 +31,7 @@ boost::typeindex::type_index get_const_user_defined_class() {
|
||||
return boost::typeindex::type_id_with_cvr<const user_defined_namespace::user_defined>();
|
||||
}
|
||||
|
||||
#ifndef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
|
||||
// Just do nothing
|
||||
void accept_typeindex(const boost::typeindex::type_index&) {}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -31,7 +31,7 @@ TEST_LIB_DECL boost::typeindex::type_index get_user_defined_class();
|
||||
TEST_LIB_DECL boost::typeindex::type_index get_const_integer();
|
||||
TEST_LIB_DECL boost::typeindex::type_index get_const_user_defined_class();
|
||||
|
||||
#ifndef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
|
||||
// This is required for checking RTTI on/off linkage
|
||||
TEST_LIB_DECL void accept_typeindex(const boost::typeindex::type_index&);
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -41,7 +41,9 @@ void comparing_types_between_modules()
|
||||
BOOST_TEST_NE(t_int, test_lib::get_user_defined_class());
|
||||
BOOST_TEST_NE(t_const_int, test_lib::get_const_user_defined_class());
|
||||
|
||||
#ifndef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
// MSVC supports detect_missmatch pragma, but /GR- silently switch disable the link time check.
|
||||
// /GR- undefies the _CPPRTTI macro. Using it to detect working detect_missmatch pragma.
|
||||
#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
|
||||
test_lib::accept_typeindex(t_int);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -10,6 +10,8 @@
|
||||
#include <boost/type_index.hpp>
|
||||
#include "test_lib_anonymous.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define BOOST_CHECK_NE(x, y) BOOST_CHECK(x != y)
|
||||
|
||||
namespace {
|
||||
@ -21,8 +23,19 @@ void comparing_anonymous_types_between_modules()
|
||||
boost::typeindex::type_index t_const_userdef = boost::typeindex::type_id_with_cvr<const user_defined>();
|
||||
boost::typeindex::type_index t_userdef = boost::typeindex::type_id<user_defined>();
|
||||
|
||||
BOOST_TEST_NE(t_userdef, test_lib::get_anonymous_user_defined_class());
|
||||
BOOST_TEST_NE(t_const_userdef, test_lib::get_const_anonymous_user_defined_class());
|
||||
// Known to fail on Clang and old versions of GCC.
|
||||
//BOOST_TEST_NE(t_userdef, test_lib::get_anonymous_user_defined_class());
|
||||
//BOOST_TEST_NE(t_const_userdef, test_lib::get_const_anonymous_user_defined_class());
|
||||
|
||||
std::cout
|
||||
<< "t_userdef == " << t_userdef
|
||||
<< ", test_lib::get_anonymous_user_defined_class() == " << test_lib::get_anonymous_user_defined_class()
|
||||
<< '\n';
|
||||
std::cout
|
||||
<< "t_const_userdef == " << t_const_userdef
|
||||
<< ", test_lib::get_const_anonymous_user_defined_class() == " << test_lib::get_const_anonymous_user_defined_class()
|
||||
<< '\n';
|
||||
|
||||
BOOST_TEST_NE(t_const_userdef, test_lib::get_anonymous_user_defined_class());
|
||||
BOOST_TEST_NE(t_userdef, test_lib::get_const_anonymous_user_defined_class());
|
||||
}
|
||||
|
23
test/track_13621.cpp
Normal file
23
test/track_13621.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright 2018-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
class empty
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string name = boost::typeindex::ctti_type_index::type_id<empty>().pretty_name();
|
||||
BOOST_TEST(name.find("empty") != std::string::npos);
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2015-2016.
|
||||
// Copyright 2015-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -7,14 +7,10 @@
|
||||
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#define BOOST_TEST_LE(x, y) BOOST_TEST(x <= y)
|
||||
#define BOOST_TEST_GE(x, y) BOOST_TEST(x >= y)
|
||||
|
||||
const char* hello1 = "Hello word";
|
||||
const char* hello1_end = hello1 + sizeof("Hello word");
|
||||
@ -93,9 +89,19 @@ void constexpr_test() {
|
||||
using namespace boost::typeindex;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR ctti_type_index t_int0 = ctti_type_index::type_id<int>();
|
||||
(void)t_int0;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR ctti_type_index t_short0 = ctti_type_index::type_id<short>();
|
||||
(void)t_short0;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR ctti_type_index t_int1 = ctti_type_index::type_id<int>();
|
||||
(void)t_int1;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR ctti_type_index t_short1 = ctti_type_index::type_id<short>();
|
||||
(void)t_short1;
|
||||
|
||||
// Following tests are known to fail on _MSC_VER == 1916.
|
||||
#if !defined(_MSC_VER) || _MSC_VER > 1916
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool same0 = (t_int0 == t_int1);
|
||||
BOOST_TEST(same0);
|
||||
@ -137,6 +143,8 @@ void constexpr_test() {
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool not_in_namespace = !is_boost_namespace<std::string>();
|
||||
BOOST_TEST(not_in_namespace);
|
||||
|
||||
#endif // #if !defined(_MSC_VER) || _MSC_VER > 1916
|
||||
}
|
||||
|
||||
|
||||
|
296
test/type_index_runtime_cast_test.cpp
Normal file
296
test/type_index_runtime_cast_test.cpp
Normal file
@ -0,0 +1,296 @@
|
||||
//
|
||||
// Copyright Chris Glover, 2016.
|
||||
//
|
||||
// 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/type_index/runtime_cast.hpp>
|
||||
// #include <boost/type_index/runtime_reference_cast.hpp>
|
||||
|
||||
#include <boost/type_index/runtime_cast.hpp>
|
||||
#include <boost/type_index/runtime_cast/boost_shared_ptr_cast.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
# include <boost/type_index/runtime_cast/std_shared_ptr_cast.hpp>
|
||||
#endif
|
||||
|
||||
// Classes include a member variable "name" with the
|
||||
// name of the class hard coded so we can be sure that
|
||||
// the pointer offsets are all working, since we're doing
|
||||
// a cast from void* at some point.
|
||||
|
||||
#define IMPLEMENT_CLASS(type_name) \
|
||||
type_name() : name( #type_name ) {} \
|
||||
std::string name;
|
||||
|
||||
struct base {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
IMPLEMENT_CLASS(base)
|
||||
};
|
||||
|
||||
struct single_derived : base {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base))
|
||||
IMPLEMENT_CLASS(single_derived)
|
||||
};
|
||||
|
||||
struct base1 {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
IMPLEMENT_CLASS(base1)
|
||||
};
|
||||
|
||||
struct base2 {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
IMPLEMENT_CLASS(base2)
|
||||
};
|
||||
|
||||
struct multiple_derived : base1, base2 {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base1)(base2))
|
||||
IMPLEMENT_CLASS(multiple_derived)
|
||||
};
|
||||
|
||||
struct baseV1 : virtual base {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base))
|
||||
IMPLEMENT_CLASS(baseV1)
|
||||
};
|
||||
|
||||
struct baseV2 : virtual base {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base))
|
||||
IMPLEMENT_CLASS(baseV2)
|
||||
};
|
||||
|
||||
struct multiple_virtual_derived : baseV1, baseV2 {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((baseV1)(baseV2))
|
||||
IMPLEMENT_CLASS(multiple_virtual_derived)
|
||||
};
|
||||
|
||||
struct unrelated {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
IMPLEMENT_CLASS(unrelated)
|
||||
};
|
||||
|
||||
struct unrelated_with_base : base {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base))
|
||||
IMPLEMENT_CLASS(unrelated_with_base)
|
||||
};
|
||||
|
||||
struct unrelatedV1 : virtual base {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base))
|
||||
IMPLEMENT_CLASS(unrelatedV1)
|
||||
};
|
||||
|
||||
struct level1_a : base {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base))
|
||||
IMPLEMENT_CLASS(level1_a)
|
||||
};
|
||||
|
||||
struct level1_b : base {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((base))
|
||||
IMPLEMENT_CLASS(level1_b)
|
||||
};
|
||||
|
||||
struct level2 : level1_a, level1_b {
|
||||
BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST((level1_a)(level1_b))
|
||||
IMPLEMENT_CLASS(level2)
|
||||
};
|
||||
|
||||
struct reg_base {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
};
|
||||
|
||||
struct reg_derived : reg_base {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((reg_base))
|
||||
};
|
||||
|
||||
void no_base()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
base b;
|
||||
base* b2 = runtime_pointer_cast<base>(&b);
|
||||
BOOST_TEST_NE(b2, (base*)NULL);
|
||||
BOOST_TEST_EQ(b2->name, "base");
|
||||
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(&b), (unrelated*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<single_derived>(&b), (single_derived*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelatedV1>(&b), (unrelatedV1*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated_with_base>(&b), (unrelated_with_base*)NULL);
|
||||
}
|
||||
|
||||
void single_base()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
single_derived d;
|
||||
base* b = &d;
|
||||
single_derived* d2 = runtime_pointer_cast<single_derived>(b);
|
||||
BOOST_TEST_NE(d2, (single_derived*)NULL);
|
||||
BOOST_TEST_EQ(d2->name, "single_derived");
|
||||
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(&d), (unrelated*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(b), (unrelated*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated_with_base>(b), (unrelated_with_base*)NULL);
|
||||
}
|
||||
|
||||
void multiple_base()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
multiple_derived d;
|
||||
base1* b1 = &d;
|
||||
multiple_derived* d2 = runtime_pointer_cast<multiple_derived>(b1);
|
||||
BOOST_TEST_NE(d2, (multiple_derived*)NULL);
|
||||
BOOST_TEST_EQ(d2->name, "multiple_derived");
|
||||
|
||||
base2* b2 = runtime_pointer_cast<base2>(b1);
|
||||
BOOST_TEST_NE(b2, (base2*)NULL);
|
||||
BOOST_TEST_EQ(b2->name, "base2");
|
||||
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(&d), (unrelated*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(b1), (unrelated*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated_with_base>(b1), (unrelated_with_base*)NULL);
|
||||
}
|
||||
|
||||
void virtual_base()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
multiple_virtual_derived d;
|
||||
base* b = &d;
|
||||
multiple_virtual_derived* d2 = runtime_pointer_cast<multiple_virtual_derived>(b);
|
||||
baseV1* bv1 = runtime_pointer_cast<baseV1>(b);
|
||||
baseV2* bv2 = runtime_pointer_cast<baseV2>(b);
|
||||
|
||||
BOOST_TEST_NE(d2, (multiple_virtual_derived*)NULL);
|
||||
BOOST_TEST_EQ(d2->name, "multiple_virtual_derived");
|
||||
|
||||
BOOST_TEST_NE(bv1, (baseV1*)NULL);
|
||||
BOOST_TEST_EQ(bv1->name, "baseV1");
|
||||
|
||||
BOOST_TEST_NE(bv2, (baseV2*)NULL);
|
||||
BOOST_TEST_EQ(bv2->name, "baseV2");
|
||||
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(b), (unrelated*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(&d), (unrelated*)NULL);
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated_with_base>(b), (unrelated_with_base*)NULL);
|
||||
}
|
||||
|
||||
void pointer_interface()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
single_derived d;
|
||||
base* b = &d;
|
||||
single_derived* d2 = runtime_cast<single_derived*>(b);
|
||||
BOOST_TEST_NE(d2, (single_derived*)NULL);
|
||||
BOOST_TEST_EQ(d2->name, "single_derived");
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(b), (unrelated*)NULL);
|
||||
}
|
||||
|
||||
void reference_interface()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
single_derived d;
|
||||
base& b = d;
|
||||
single_derived& d2 = runtime_cast<single_derived&>(b);
|
||||
BOOST_TEST_EQ(d2.name, "single_derived");
|
||||
|
||||
try {
|
||||
unrelated& u = runtime_cast<unrelated&>(b);
|
||||
(void)u;
|
||||
BOOST_TEST(!"should throw bad_runtime_cast");
|
||||
}
|
||||
catch(boost::typeindex::bad_runtime_cast&) {
|
||||
}
|
||||
catch(...) {
|
||||
BOOST_TEST(!"should throw bad_runtime_cast");
|
||||
}
|
||||
}
|
||||
|
||||
void const_pointer_interface()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
const single_derived d;
|
||||
base const* b = &d;
|
||||
single_derived const* d2 = runtime_cast<single_derived const*>(b);
|
||||
BOOST_TEST_NE(d2, (single_derived*)NULL);
|
||||
BOOST_TEST_EQ(d2->name, "single_derived");
|
||||
BOOST_TEST_EQ(runtime_pointer_cast<unrelated>(b), (unrelated*)NULL);
|
||||
}
|
||||
|
||||
void const_reference_interface()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
const single_derived d;
|
||||
base const& b = d;
|
||||
single_derived const& d2 = runtime_cast<single_derived const&>(b);
|
||||
BOOST_TEST_EQ(d2.name, "single_derived");
|
||||
|
||||
try {
|
||||
unrelated const& u = runtime_cast<unrelated const&>(b);
|
||||
(void)u;
|
||||
BOOST_TEST(!"should throw bad_runtime_cast");
|
||||
}
|
||||
catch(boost::typeindex::bad_runtime_cast&) {
|
||||
}
|
||||
catch(...) {
|
||||
BOOST_TEST(!"should throw bad_runtime_cast");
|
||||
}
|
||||
}
|
||||
|
||||
void diamond_non_virtual()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
level2 inst;
|
||||
level1_a* l1a = &inst;
|
||||
base* b1 = l1a;
|
||||
level1_b* l1_b = runtime_cast<level1_b*>(b1);
|
||||
BOOST_TEST_NE(l1_b, (level1_b*)NULL);
|
||||
BOOST_TEST_EQ(l1_b->name, "level1_b");
|
||||
}
|
||||
|
||||
void boost_shared_ptr()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
boost::shared_ptr<single_derived> d = boost::make_shared<single_derived>();
|
||||
boost::shared_ptr<base> b = d;
|
||||
boost::shared_ptr<single_derived> d2 = runtime_pointer_cast<single_derived>(b);
|
||||
BOOST_TEST_NE(d2, boost::shared_ptr<single_derived>());
|
||||
BOOST_TEST_EQ(d2->name, "single_derived");
|
||||
}
|
||||
|
||||
void std_shared_ptr()
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
using namespace boost::typeindex;
|
||||
std::shared_ptr<single_derived> d = std::make_shared<single_derived>();
|
||||
std::shared_ptr<base> b = d;
|
||||
std::shared_ptr<single_derived> d2 = runtime_pointer_cast<single_derived>(b);
|
||||
BOOST_TEST_NE(d2, std::shared_ptr<single_derived>());
|
||||
BOOST_TEST_EQ(d2->name, "single_derived");
|
||||
#endif
|
||||
}
|
||||
|
||||
void register_runtime_class()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
reg_derived rd;
|
||||
reg_base* rb = &rd;
|
||||
reg_derived* prd = runtime_pointer_cast<reg_derived>(rb);
|
||||
BOOST_TEST_NE(prd, (reg_derived*)NULL);
|
||||
BOOST_TEST_EQ(type_id_runtime(*prd), type_id<reg_derived>());
|
||||
}
|
||||
|
||||
int main() {
|
||||
no_base();
|
||||
single_derived();
|
||||
multiple_base();
|
||||
virtual_base();
|
||||
pointer_interface();
|
||||
reference_interface();
|
||||
const_pointer_interface();
|
||||
const_reference_interface();
|
||||
diamond_non_virtual();
|
||||
boost_shared_ptr();
|
||||
std_shared_ptr();
|
||||
register_runtime_class();
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -7,13 +7,9 @@
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#define BOOST_TEST_LE(x, y) BOOST_TEST(x <= y)
|
||||
#define BOOST_TEST_GE(x, y) BOOST_TEST(x >= y)
|
||||
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2015.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
Reference in New Issue
Block a user