forked from boostorg/type_index
Compare commits
181 Commits
boost-1.56
...
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 | |||
6cf5288a8c | |||
4453acf867 | |||
b6b23bad3a | |||
3bb646d19b | |||
9cd218bbc4 | |||
ad26256d09 | |||
5af925602e | |||
2fb667a6a0 | |||
12751e0f83 | |||
0b006b6af6 | |||
76cae485cb | |||
ee7b15a493 | |||
1dc8310826 | |||
b230140529 | |||
31ec1d2524 | |||
40e9bd336a | |||
767c724983 | |||
24708cc109 | |||
57205874ae | |||
1b4a85764f | |||
1976355e8f | |||
0efc48e16c | |||
e96a6e8f80 | |||
8e3466ece5 | |||
8b6c3facb3 | |||
ffb98af0dd | |||
9122022faf | |||
18dbaea6ee | |||
6dabf11504 | |||
7bd788c5d7 | |||
2d87bc6194 | |||
36efa3969b | |||
551535f8cf | |||
3f004511a2 | |||
30bb93bd23 | |||
7f2b9fd31a | |||
c9f1370d0c | |||
1ec4460244 | |||
1ed55a2f12 | |||
1c685fa119 | |||
37484c19ec | |||
bb02f97414 | |||
b9db462091 | |||
cf4f09b520 | |||
5de7f5def6 | |||
1c8190cc62 | |||
6ff2a75da3 | |||
58b0f69e52 | |||
478da3512a | |||
a373a4c7ed | |||
34835b90e3 | |||
236fdc8dba | |||
1ff942f329 | |||
f58844637c | |||
9fede62a7c | |||
48d50ae178 | |||
743b2a8851 | |||
7e2a538eb5 | |||
e5e105013a | |||
d7ec25e56b | |||
c0f75c27fa | |||
3e6695971d | |||
8d3127935d | |||
d585fc3673 | |||
6b5d2743c5 | |||
8558fd66ef | |||
8ddc5feac4 | |||
8b7534889b | |||
697e09bda9 | |||
242d9a0bed | |||
99f58714d1 | |||
7b04caa160 | |||
4d221d4f71 | |||
806a192df1 | |||
1633adfee4 | |||
c3a26dff9a |
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
|
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()
|
19
README.md
19
README.md
@ -1,9 +1,16 @@
|
||||
type_index
|
||||
==========
|
||||
# [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.
|
||||
|
||||
Runtime/Compile time copyable type info.
|
||||
Documantation available at: http://www.boost.org/
|
||||
Latest developer documentation is available at: http://boostorg.github.com/type_index/index.html
|
||||
### Test results
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt).
|
||||
@ | Build | Tests coverage | More info
|
||||
----------------|-------------- | -------------- |-----------
|
||||
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)
|
||||
|
||||
|
||||
[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](https://boost.org/LICENSE_1_0.txt).
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright Antony Polukhin 2011-2013.
|
||||
# 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
|
||||
@ -20,6 +21,7 @@ doxygen autodoc
|
||||
<doxygen:param>MACRO_EXPANSION=YES
|
||||
<doxygen:param>"PREDEFINED=\"stl_type_info=std::type_info\" \\
|
||||
\"BOOST_TYPE_INDEX_DOXYGEN_INVOKED\" \\
|
||||
\"BOOST_CXX14_CONSTEXPR=constexpr\" \\
|
||||
\"detail::stl_type_info=std::type_info\""
|
||||
<xsl:param>"boost.doxygen.reftitle=Boost.TypeIndex Header Reference"
|
||||
;
|
||||
@ -34,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.0]
|
||||
[copyright 2012-2014 Antony Polukhin]
|
||||
[version 4.1]
|
||||
[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,19 +266,28 @@ 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]
|
||||
|
||||
[import ../examples/table_of_names.cpp]
|
||||
[section Table of raw_name() and pretty_name() outputs with and without RTTI ] [type_index_names_table] [endsect]
|
||||
|
||||
[import ../examples/constexpr14_namespace_check.cpp]
|
||||
[section C++14: Checking namespace at compile time ] [type_index_constexpr14_namespace_example] [endsect]
|
||||
|
||||
[import ../examples/constexpr14_sort_check.cpp]
|
||||
[section C++14: Checking lexigraphical order of provided types ] [type_index_constexpr14_sort_check_example] [endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[xinclude autodoc.xml]
|
||||
|
||||
[section Making a custom type_index]
|
||||
|
||||
Sometimes there may be a need to create your own type info system. This may be usefull if you wish to store some more info about types (PODness, size of a type, pointers to common functions...) or if you have an idea of a more compact types representations.
|
||||
Sometimes there may be a need to create your own type info system. This may be useful if you wish to store some more info about types (PODness, size of a type, pointers to common functions...) or if you have an idea of a more compact types representations.
|
||||
|
||||
[import ../examples/user_defined_typeinfo.hpp]
|
||||
[import ../examples/user_defined_typeinfo.cpp]
|
||||
@ -353,7 +366,9 @@ TypeIndex has been tested and successfully work on many compilers.
|
||||
assert(foo_a() != foo_b()); // will fail on some compilers
|
||||
```
|
||||
|
||||
*Compilers that have that limitation:* GCC, CLANG.
|
||||
*Compilers that have that limitation:* GCC, CLANG, Intel.
|
||||
|
||||
*Test:* you can test this issue by runing the `testing_crossmodule_anonymous_no_rtti` that can be build if you run `../../../b2` in `type_index/test/` folder.
|
||||
]
|
||||
|
||||
[section Define the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro]
|
||||
@ -378,7 +393,7 @@ function signature including template parameters.
|
||||
If the output of `boost::typeindex::ctti_type_index::type_id<int>().name()`
|
||||
* returns not just `int` but also a lot of text around the `int`
|
||||
* or does not return type at all
|
||||
then you are usng a compiler that was not tested with this library and you need to setup the
|
||||
then you are using a compiler that was not tested with this library and you need to setup the
|
||||
[macroref BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING] macro.
|
||||
|
||||
Here is a short instruction:
|
||||
@ -394,7 +409,7 @@ Here is a short instruction:
|
||||
* `skip_at_begin` is equal to `skip_at_begin` at step 2
|
||||
* `skip_at_end` is equal to `skip_at_end` at step 2
|
||||
* `"T = "` is equal to characters that are right before the `int` in output
|
||||
# (optional, but highly recomended) [@http://www.boost.org/support/bugs.html create ticket] with
|
||||
# (optional, but highly recommended) [@http://www.boost.org/support/bugs.html create ticket] with
|
||||
feature request to add your compiler to supported compilers list. Include
|
||||
parameters provided to `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` macro.
|
||||
|
||||
@ -415,7 +430,7 @@ Another example:
|
||||
`boost::typeindex::ctti_type_index::type_id<int>().raw_name()` returns
|
||||
"static const char *boost::detail::ctti<int>::n() [T = int]"". Then you shall set
|
||||
`skip_at_begin` to `sizeof("static const char *boost::detail::ctti<") - 1`
|
||||
and `skip_at_end` to `sizeof("]") - 1` and last parameter of macto to "T = ".
|
||||
and `skip_at_end` to `sizeof("]") - 1` and last parameter of macro to "T = ".
|
||||
|
||||
``
|
||||
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (39, 1, true, "T = ")
|
||||
@ -463,5 +478,6 @@ In order of helping and advising:
|
||||
* Peter Dimov for writing source codes in late 2007, that gave me an idea of how to emulate RTTI.
|
||||
* Agustín Bergé K-ballo for helping with docs and fixing a lot of typos.
|
||||
* Niall Douglas for generating a lot of great ideas, reviewing the sources and being the review manager for the library.
|
||||
* All the library reviewers, especially Andrey Semashev, for making good notes and proposing improvements to the library.
|
||||
|
||||
[endsect]
|
||||
|
99
examples/constexpr14_namespace_check.cpp
Normal file
99
examples/constexpr14_namespace_check.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
#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>
|
||||
constexpr bool starts_with(const char* name, const char (&ns)[N]) noexcept {
|
||||
for (std::size_t i = 0; i < N - 1; ++i)
|
||||
if (name[i] != ns[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//[type_index_constexpr14_namespace_example
|
||||
/*`
|
||||
The following example shows that `boost::typeindex::ctti_type_index` is usable at compile time on
|
||||
a C++14 compatible compilers.
|
||||
|
||||
In this example we'll create and use a constexpr function that checks namespace of the provided type.
|
||||
*/
|
||||
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
|
||||
// Helper function that returns true if `name` starts with `substr`
|
||||
template <std::size_t N>
|
||||
constexpr bool starts_with(const char* name, const char (&substr)[N]) noexcept;
|
||||
|
||||
|
||||
// Function that returns true if `T` declared in namespace `ns`
|
||||
template <class T, std::size_t N>
|
||||
constexpr bool in_namespace(const char (&ns)[N]) noexcept {
|
||||
const char* name = boost::typeindex::ctti_type_index::type_id<T>().raw_name();
|
||||
|
||||
// Some compilers add `class ` or `struct ` before the namespace, so we need to skip those words first
|
||||
if (starts_with(name, "class ")) {
|
||||
name += sizeof("class ") - 1;
|
||||
} else if (starts_with(name, "struct ")) {
|
||||
name += sizeof("struct ") - 1;
|
||||
}
|
||||
|
||||
return starts_with(name, ns) && starts_with(name + N - 1, "::");
|
||||
}
|
||||
|
||||
/*`
|
||||
Now when we have that wonderfull function, we can do static assertions and other compile-time validations:
|
||||
*/
|
||||
|
||||
namespace my_project {
|
||||
struct serializer {
|
||||
template <class T>
|
||||
void serialize(const T& value) {
|
||||
static_assert(
|
||||
in_namespace<T>("my_project::types") || in_namespace<T>("my_project::types_ext"),
|
||||
"Only types from namespaces `my_project::types` and `my_project::types_ext` are allowed to be serialized using `my_project::serializer`"
|
||||
);
|
||||
|
||||
// Actual implementation of the serialization goes below
|
||||
// ...
|
||||
do_something(value);
|
||||
}
|
||||
};
|
||||
|
||||
namespace types {
|
||||
struct foo{};
|
||||
struct bar{};
|
||||
}
|
||||
} // namespace my_project
|
||||
|
||||
int main() {
|
||||
my_project::serializer s;
|
||||
my_project::types::foo f;
|
||||
my_project::types::bar b;
|
||||
|
||||
s.serialize(f);
|
||||
s.serialize(b);
|
||||
|
||||
// short sh = 0;
|
||||
// s.serialize(sh); // Fails the static_assert!
|
||||
}
|
||||
//] [/type_index_constexpr14_namespace_example]
|
||||
|
||||
#else // #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||
|
||||
int main() {}
|
||||
|
||||
#endif
|
||||
|
76
examples/constexpr14_sort_check.cpp
Normal file
76
examples/constexpr14_sort_check.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#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
|
||||
/*`
|
||||
The following example shows that `boost::typeindex::ctti_type_index` is usable at compile time on
|
||||
a C++14 compatible compilers to check order of template parameters.
|
||||
|
||||
Consider the situation when we have a function that accepts std::tuple, boost::variant or some other class that uses variadic templates:
|
||||
*/
|
||||
|
||||
template <class... T> class types{};
|
||||
|
||||
template <class... T>
|
||||
void do_something(const types<T...>& t) noexcept;
|
||||
|
||||
/*`
|
||||
Such functions may be very usefull, however they may significantly increase the size of the resulting program. Each instantionation of such function with different templates order
|
||||
consumes space in the resulting program:
|
||||
|
||||
// Types are same, but different order leads to new instantionation of do_something function.
|
||||
types<bool, double, int>
|
||||
types<bool, int, double>
|
||||
types<int, bool, double>
|
||||
types<int, double, bool>
|
||||
types<double, int, bool>
|
||||
types<double, bool, int>
|
||||
|
||||
One of the ways to reduce instantinations count is to force the types to have some order:
|
||||
*/
|
||||
|
||||
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
|
||||
// Implementing type trait that returns true if the types are sorted lexographicaly
|
||||
template <class... T>
|
||||
constexpr bool is_asc_sorted(types<T...>) noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Lhs, class Rhs, class... TN>
|
||||
constexpr bool is_asc_sorted(types<Lhs, Rhs, TN...>) noexcept {
|
||||
using namespace boost::typeindex;
|
||||
return ctti_type_index::type_id<Lhs>() <= ctti_type_index::type_id<Rhs>()
|
||||
&& is_asc_sorted(types<Rhs, TN...>());
|
||||
}
|
||||
|
||||
|
||||
// Using the newly created `is_asc_sorted` trait:
|
||||
template <class... T>
|
||||
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"
|
||||
);
|
||||
}
|
||||
|
||||
int main() {
|
||||
do_something( types<bool, double, int>() );
|
||||
// do_something( types<bool, int, double>() ); // Fails the static_assert!
|
||||
}
|
||||
//] [/type_index_constexpr14_sort_check_example]
|
||||
|
||||
#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() {}
|
||||
|
||||
#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
|
||||
|
@ -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
|
||||
@ -17,7 +17,24 @@
|
||||
#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
|
||||
#define assert(X) if (!(X)) std::exit(__LINE__)
|
||||
/* !Comment block is not closed intentionaly!
|
||||
//->
|
||||
#include <cassert>
|
||||
//<-
|
||||
!Closing comment block! */
|
||||
//->
|
||||
|
||||
class type_erased_unary_function {
|
||||
void* function_ptr_;
|
||||
@ -50,7 +67,7 @@ int main() {
|
||||
int i = 100;
|
||||
|
||||
// An attempt to convert stored function to a function accepting reference
|
||||
func.call<int&>(i); // Will throw, because types `int&` and `int` missmatch
|
||||
func.call<int&>(i); // Will throw, because types `int&` and `int` mismatch
|
||||
|
||||
assert(false);
|
||||
} catch (const std::runtime_error& /*e*/) {}
|
||||
|
@ -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-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
|
||||
@ -11,9 +11,24 @@
|
||||
*/
|
||||
|
||||
#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
|
||||
#endif
|
||||
#define assert(X) BOOST_TEST(X)
|
||||
/* !Comment block is not closed intentionaly!
|
||||
//->
|
||||
#include <cassert>
|
||||
//<-
|
||||
!Closing comment block! */
|
||||
//->
|
||||
|
||||
int main() {
|
||||
boost::unordered_set<boost::typeindex::type_index> types;
|
||||
@ -32,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
|
||||
@ -73,15 +73,15 @@ int main() {
|
||||
|
||||
[table:id Table of names
|
||||
[[Type] [RTTI & raw_name] [RTTI & pretty_name] [noRTTI & raw_name]]
|
||||
[[User defined type][`17user_defined_type`] [`user_defined_type`] [`user_defined_type]`] ]
|
||||
[[In anonymous namespace][`N12_GLOBAL__N_112in_anon_typeE`] [`(anonymous namespace)::in_anon_type`] [`{anonymous}::in_anon_type]`] ]
|
||||
[[In ns3::{anonymous}::ns4 namespace][`N3ns312_GLOBAL__N_13ns412in_anon_typeE`] [`ns3::(anonymous namespace)::ns4::in_anon_type`] [`ns3::{anonymous}::ns4::in_anon_type]`] ]
|
||||
[[Template class][`5templIsiE`] [`templ<short, int>`] [`templ<short int, int>]`] ]
|
||||
[[Template class (full specialization)][`5templIiiE`] [`templ<int, int>`] [`templ<int, int>]`] ]
|
||||
[[Template class with templae classes][`5templIS_IcaES_Ii17user_defined_typeEE`] [`templ<templ<char, signed char>, templ<int, user_defined_type> >`] [`templ<templ<char, signed char>, templ<int, user_defined_type> >]`] ]
|
||||
[[User defined type][`17user_defined_type`] [`user_defined_type`] [`user_defined_type]`] ]
|
||||
[[In anonymous namespace][`N12_GLOBAL__N_112in_anon_typeE`] [`(anonymous namespace)::in_anon_type`] [`{anonymous}::in_anon_type]`] ]
|
||||
[[In ns3::{anonymous}::ns4 namespace][`N3ns312_GLOBAL__N_13ns412in_anon_typeE`] [`ns3::(anonymous namespace)::ns4::in_anon_type`] [`ns3::{anonymous}::ns4::in_anon_type]`] ]
|
||||
[[Template class][`5templIsiE`] [`templ<short, int>`] [`templ<short int, int>]`] ]
|
||||
[[Template class (full specialization)][`5templIiiE`] [`templ<int, int>`] [`templ<int, int>]`] ]
|
||||
[[Template class with template classes][`5templIS_IcaES_Ii17user_defined_typeEE`] [`templ<templ<char, signed char>, templ<int, user_defined_type> >`] [`templ<templ<char, signed char>, templ<int, user_defined_type> >]`] ]
|
||||
]
|
||||
|
||||
We have not show the "noRTTI & pretty_name" column in the table becuse it is almost equal
|
||||
We have not show the "noRTTI & pretty_name" column in the table because it is almost equal
|
||||
to "noRTTI & raw_name" column.
|
||||
|
||||
[warning With RTTI off different classes with same names in anonymous namespace may collapse. See 'RTTI emulation limitations'. ]
|
||||
|
@ -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
|
||||
@ -18,10 +18,15 @@
|
||||
#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
|
||||
#endif
|
||||
#define assert(X) BOOST_TEST(X)
|
||||
|
||||
|
||||
using namespace my_namespace;
|
||||
#include <cassert>
|
||||
|
||||
int main() {
|
||||
//[type_index_my_type_index_usage
|
||||
@ -60,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)
|
||||
@ -22,14 +22,27 @@
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
|
||||
# include BOOST_TYPE_INDEX_USER_TYPEINDEX
|
||||
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
# pragma detect_mismatch( "boost__type_index__abi", "user defined type_index class is used: " BOOST_STRINGIZE(BOOST_TYPE_INDEX_USER_TYPEINDEX))
|
||||
# endif
|
||||
#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
|
||||
# include <boost/type_index/stl_type_index.hpp>
|
||||
# ifdef BOOST_NO_RTTI
|
||||
# if defined(BOOST_NO_RTTI) || defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)
|
||||
# include <boost/type_index/detail/stl_register_class.hpp>
|
||||
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - typeid() is used only for templates")
|
||||
# endif
|
||||
# else
|
||||
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is used")
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# include <boost/type_index/ctti_type_index.hpp>
|
||||
# include <boost/type_index/detail/ctti_register_class.hpp>
|
||||
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - using CTTI")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
@ -221,7 +234,7 @@ inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
|
||||
/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index.
|
||||
///
|
||||
/// Retunrs runtime information about specified type.
|
||||
/// Returns runtime information about specified type.
|
||||
///
|
||||
/// \b Requirements: RTTI available or Base and Derived classes must be marked with BOOST_TYPE_INDEX_REGISTER_CLASS.
|
||||
///
|
||||
@ -236,7 +249,7 @@ inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
/// std::cout << ti.pretty_name(); // Outputs 'Derived'
|
||||
/// \endcode
|
||||
///
|
||||
/// \param runtime_val Varaible which runtime type must be returned.
|
||||
/// \param runtime_val Variable which runtime type must be returned.
|
||||
/// \throw Nothing.
|
||||
/// \return boost::typeindex::type_index with information about the specified variable.
|
||||
template <class T>
|
||||
|
@ -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
|
||||
@ -10,9 +10,9 @@
|
||||
#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
|
||||
|
||||
/// \file ctti_type_index.hpp
|
||||
/// \brief Contains boost::typeindex::ctti_type_index class.
|
||||
/// \brief Contains boost::typeindex::ctti_type_index class that is constexpr if C++14 constexpr is supported by compiler.
|
||||
///
|
||||
/// boost::typeindex::ctti_type_index class can be used as a drop-in replacement
|
||||
/// boost::typeindex::ctti_type_index class can be used as a drop-in replacement
|
||||
/// for std::type_index.
|
||||
///
|
||||
/// It is used in situations when typeid() method is not available or
|
||||
@ -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>
|
||||
@ -35,10 +36,10 @@ namespace boost { namespace typeindex {
|
||||
namespace detail {
|
||||
|
||||
// That's the most trickiest part of the TypeIndex library:
|
||||
// 1) we do not whant to give user ability to manually construct and compare `struct-that-represents-type`
|
||||
// 2) we need to distinguish beteween `struct-that-represents-type` and `const char*`
|
||||
// 1) we do not want to give user ability to manually construct and compare `struct-that-represents-type`
|
||||
// 2) we need to distinguish between `struct-that-represents-type` and `const char*`
|
||||
// 3) we need a thread-safe way to have references to instances `struct-that-represents-type`
|
||||
// 4) we need a compile-time control to make shure that user does not copy or
|
||||
// 4) we need a compile-time control to make sure that user does not copy or
|
||||
// default construct `struct-that-represents-type`
|
||||
//
|
||||
// Solution would be the following:
|
||||
@ -72,15 +73,15 @@ private:
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Helper method for getting detail::ctti_data of a tempalte patameter T.
|
||||
/// Helper method for getting detail::ctti_data of a template parameter T.
|
||||
template <class T>
|
||||
inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
|
||||
// Standard C++11, 5.2.10 Reinterpret cast:
|
||||
// An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue
|
||||
// v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast<cv
|
||||
// v of type "pointer to T1" is converted to the type "pointer to cv T2", the result is static_cast<cv
|
||||
// T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment
|
||||
// requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type
|
||||
// “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment
|
||||
// "pointer to T1" to the type "pointer to T2" (where T1 and T2 are object types and where the alignment
|
||||
// requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer
|
||||
// value.
|
||||
//
|
||||
@ -89,37 +90,52 @@ inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
|
||||
}
|
||||
|
||||
/// \class ctti_type_index
|
||||
/// This class is a wrapper that pretends to work exactly like stl_type_index, but does
|
||||
/// This class is a wrapper that pretends to work exactly like stl_type_index, but does
|
||||
/// not require RTTI support. \b For \b description \b of \b functions \b see type_index_facade.
|
||||
///
|
||||
/// This class produces slightly longer type names, so consider using stl_type_index
|
||||
/// This class on C++14 compatible compilers has following functions marked as constexpr:
|
||||
/// * default constructor
|
||||
/// * copy constructors and assignemnt operations
|
||||
/// * class methods: name(), before(const ctti_type_index& rhs), equal(const ctti_type_index& rhs)
|
||||
/// * static methods type_id<T>(), type_id_with_cvr<T>()
|
||||
/// * comparison operators
|
||||
///
|
||||
/// This class produces slightly longer type names, so consider using stl_type_index
|
||||
/// in situations when typeid() is working.
|
||||
class ctti_type_index: public type_index_facade<ctti_type_index, detail::ctti_data> {
|
||||
const detail::ctti_data* data_;
|
||||
const char* data_;
|
||||
|
||||
inline std::size_t get_raw_name_length() const BOOST_NOEXCEPT;
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline explicit ctti_type_index(const char* data) BOOST_NOEXCEPT
|
||||
: data_(data)
|
||||
{}
|
||||
|
||||
public:
|
||||
typedef detail::ctti_data type_info_t;
|
||||
|
||||
inline ctti_type_index() BOOST_NOEXCEPT
|
||||
: data_(&ctti_construct<void>())
|
||||
BOOST_CXX14_CONSTEXPR inline ctti_type_index() BOOST_NOEXCEPT
|
||||
: data_(boost::detail::ctti<void>::n())
|
||||
{}
|
||||
|
||||
inline ctti_type_index(const type_info_t& data) BOOST_NOEXCEPT
|
||||
: data_(&data)
|
||||
: data_(reinterpret_cast<const char*>(&data))
|
||||
{}
|
||||
|
||||
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
|
||||
inline const char* raw_name() const BOOST_NOEXCEPT;
|
||||
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
|
||||
BOOST_CXX14_CONSTEXPR inline const char* raw_name() const BOOST_NOEXCEPT;
|
||||
BOOST_CXX14_CONSTEXPR inline const char* name() const BOOST_NOEXCEPT;
|
||||
inline std::string pretty_name() const;
|
||||
inline std::size_t hash_code() const BOOST_NOEXCEPT;
|
||||
|
||||
template <class T>
|
||||
inline static ctti_type_index type_id() BOOST_NOEXCEPT;
|
||||
BOOST_CXX14_CONSTEXPR inline bool equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT;
|
||||
BOOST_CXX14_CONSTEXPR inline bool before(const ctti_type_index& rhs) const BOOST_NOEXCEPT;
|
||||
|
||||
template <class T>
|
||||
inline static ctti_type_index type_id_with_cvr() BOOST_NOEXCEPT;
|
||||
BOOST_CXX14_CONSTEXPR inline static ctti_type_index type_id() BOOST_NOEXCEPT;
|
||||
|
||||
template <class T>
|
||||
BOOST_CXX14_CONSTEXPR inline static ctti_type_index type_id_with_cvr() BOOST_NOEXCEPT;
|
||||
|
||||
template <class T>
|
||||
inline static ctti_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
|
||||
@ -127,22 +143,35 @@ public:
|
||||
|
||||
|
||||
inline const ctti_type_index::type_info_t& ctti_type_index::type_info() const BOOST_NOEXCEPT {
|
||||
return *data_;
|
||||
return *reinterpret_cast<const detail::ctti_data*>(data_);
|
||||
}
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline bool ctti_type_index::equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT {
|
||||
const char* const left = raw_name();
|
||||
const char* const right = rhs.raw_name();
|
||||
return /*left == right ||*/ !boost::typeindex::detail::constexpr_strcmp(left, right);
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline bool ctti_type_index::before(const ctti_type_index& rhs) const BOOST_NOEXCEPT {
|
||||
const char* const left = raw_name();
|
||||
const char* const right = rhs.raw_name();
|
||||
return /*left != right &&*/ boost::typeindex::detail::constexpr_strcmp(left, right) < 0;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
inline ctti_type_index ctti_type_index::type_id() BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline ctti_type_index ctti_type_index::type_id() BOOST_NOEXCEPT {
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_t;
|
||||
return ctti_construct<no_cvr_t>();
|
||||
return ctti_type_index(boost::detail::ctti<no_cvr_t>::n());
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
inline ctti_type_index ctti_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
return ctti_construct<T>();
|
||||
BOOST_CXX14_CONSTEXPR inline ctti_type_index ctti_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
return ctti_type_index(boost::detail::ctti<T>::n());
|
||||
}
|
||||
|
||||
|
||||
@ -152,8 +181,13 @@ inline ctti_type_index ctti_type_index::type_id_runtime(const T& variable) BOOST
|
||||
}
|
||||
|
||||
|
||||
inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
|
||||
return reinterpret_cast<const char*>(data_);
|
||||
BOOST_CXX14_CONSTEXPR inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
|
||||
return data_;
|
||||
}
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR inline const char* ctti_type_index::name() const BOOST_NOEXCEPT {
|
||||
return data_;
|
||||
}
|
||||
|
||||
inline std::size_t ctti_type_index::get_raw_name_length() const BOOST_NOEXCEPT {
|
||||
|
@ -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
|
||||
@ -11,18 +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 <algorithm>
|
||||
#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; \
|
||||
@ -30,47 +42,66 @@
|
||||
BOOST_STATIC_CONSTEXPR bool ctti_skip_more_at_runtime = runtime_skip; \
|
||||
BOOST_STATIC_CONSTEXPR char ctti_skip_until_runtime[] = runtime_skip_until; \
|
||||
}}} /* namespace boost::typeindex::detail */ \
|
||||
/**/
|
||||
/**/
|
||||
/// @endcond
|
||||
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
/* Nothing to document. All the macro docs are moved to <boost/type_index.hpp> */
|
||||
#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)
|
||||
#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, "");
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "")
|
||||
#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__)
|
||||
// Someone made __clang_major__ equal to LLVM version rather than compiler version
|
||||
// on APPLE platform.
|
||||
//
|
||||
// Using less efficient solution because there is no good way to detect real version of Clang.
|
||||
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "???????????>::n() [T = int"
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ");
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
|
||||
#elif defined(__clang__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ == 0))
|
||||
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof(">::n()") - 1
|
||||
// note: checked on 3.0
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "");
|
||||
#elif defined(__clang__) && __clang_major__ == 3 && __clang_minor__ > 0
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "")
|
||||
#elif defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ > 0))
|
||||
// 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__)
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
|
||||
#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, "");
|
||||
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, "");
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "")
|
||||
#endif
|
||||
|
||||
#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
template <bool Condition>
|
||||
inline void assert_compile_time_legths() BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline void assert_compile_time_legths() BOOST_NOEXCEPT {
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
Condition,
|
||||
"TypeIndex library is misconfigured for your compiler. "
|
||||
@ -78,54 +109,9 @@ namespace boost { namespace typeindex { namespace detail {
|
||||
"'RTTI emulation limitations' of the documentation for more information."
|
||||
);
|
||||
}
|
||||
|
||||
template <std::size_t ArrayLength>
|
||||
inline const char* skip_begining_runtime(const char* begin, boost::mpl::false_) BOOST_NOEXCEPT {
|
||||
return begin;
|
||||
}
|
||||
|
||||
template <std::size_t ArrayLength>
|
||||
inline const char* skip_begining_runtime(const char* begin, boost::mpl::true_) BOOST_NOEXCEPT {
|
||||
const char* const it = std::search(
|
||||
begin, begin + ArrayLength,
|
||||
ctti_skip_until_runtime, ctti_skip_until_runtime + sizeof(ctti_skip_until_runtime) - 1
|
||||
);
|
||||
return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1);
|
||||
}
|
||||
|
||||
template <std::size_t ArrayLength>
|
||||
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>()
|
||||
);
|
||||
}
|
||||
}}} // namespace boost::typeindex::detail
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
/// Noncopyable type_info that does not require RTTI.
|
||||
/// CTTI == Compile Time Type Info.
|
||||
/// This name must be as short as posible, to avoid code bloat
|
||||
template <class T>
|
||||
struct ctti {
|
||||
|
||||
/// Returns raw name. Must be as short, as possible, to avoid code bloat
|
||||
static const char* n() BOOST_NOEXCEPT {
|
||||
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
|
||||
#elif defined(__FUNCSIG__)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__);
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
|| defined(__GNUC__) \
|
||||
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__)
|
||||
|
||||
return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
|
||||
#else
|
||||
template <class T>
|
||||
BOOST_CXX14_CONSTEXPR inline void failed_to_get_function_name() BOOST_NOEXCEPT {
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
sizeof(T) && false,
|
||||
"TypeIndex library could not detect your compiler. "
|
||||
@ -133,11 +119,221 @@ struct ctti {
|
||||
"correct compiler macro for getting the whole function name. "
|
||||
"Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that."
|
||||
);
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
template<class ForwardIterator1, class ForwardIterator2>
|
||||
BOOST_CXX14_CONSTEXPR inline ForwardIterator1 constexpr_search(
|
||||
ForwardIterator1 first1,
|
||||
ForwardIterator1 last1,
|
||||
ForwardIterator2 first2,
|
||||
ForwardIterator2 last2) BOOST_NOEXCEPT
|
||||
{
|
||||
if (first2 == last2) {
|
||||
return first1; // specified in C++11
|
||||
}
|
||||
|
||||
while (first1 != last1) {
|
||||
ForwardIterator1 it1 = first1;
|
||||
ForwardIterator2 it2 = first2;
|
||||
|
||||
while (*it1 == *it2) {
|
||||
++it1;
|
||||
++it2;
|
||||
if (it2 == last2) return first1;
|
||||
if (it1 == last1) return last1;
|
||||
}
|
||||
|
||||
++first1;
|
||||
}
|
||||
|
||||
return last1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1);
|
||||
}
|
||||
|
||||
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::integral_constant<bool, ctti_skip_more_at_runtime>()
|
||||
);
|
||||
}
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
template <unsigned int... I>
|
||||
struct index_seq {};
|
||||
|
||||
template <typename Left, typename Right>
|
||||
struct make_index_sequence_join;
|
||||
|
||||
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 <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,
|
||||
typename make_index_seq_impl<C + D / 2, (D + 1) / 2>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <unsigned int C>
|
||||
struct make_index_seq_impl<C, 0> {
|
||||
typedef index_seq<> type;
|
||||
};
|
||||
|
||||
template <unsigned int C>
|
||||
struct make_index_seq_impl<C, 1> {
|
||||
typedef index_seq<C> type;
|
||||
};
|
||||
|
||||
template <char... C>
|
||||
struct cstring {
|
||||
static constexpr unsigned int size_ = sizeof...(C);
|
||||
static constexpr char data_[size_] = { C... };
|
||||
};
|
||||
|
||||
template <char... C>
|
||||
constexpr char cstring<C...>::data_[];
|
||||
#endif
|
||||
|
||||
}}} // namespace boost::typeindex::detail
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
/// Noncopyable type_info that does not require RTTI.
|
||||
/// CTTI == Compile Time Type Info.
|
||||
/// 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 <unsigned int I>
|
||||
constexpr static char s() BOOST_NOEXCEPT { // step
|
||||
constexpr unsigned int offset =
|
||||
(I >= 10u ? 1u : 0u)
|
||||
+ (I >= 100u ? 1u : 0u)
|
||||
+ (I >= 1000u ? 1u : 0u)
|
||||
+ (I >= 10000u ? 1u : 0u)
|
||||
+ (I >= 100000u ? 1u : 0u)
|
||||
+ (I >= 1000000u ? 1u : 0u)
|
||||
;
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
return BOOST_TYPE_INDEX_FUNCTION_SIGNATURE[I + offset];
|
||||
#elif defined(__FUNCSIG__)
|
||||
return __FUNCSIG__[I + offset];
|
||||
#else
|
||||
return __PRETTY_FUNCTION__[I + offset];
|
||||
#endif
|
||||
}
|
||||
|
||||
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 <unsigned int D = 0> // `D` means `Dummy`
|
||||
constexpr static const char* n() BOOST_NOEXCEPT {
|
||||
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
constexpr unsigned int size = sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
|
||||
#elif defined(__FUNCSIG__)
|
||||
constexpr unsigned int size = sizeof(__FUNCSIG__);
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
|| defined(__GNUC__) \
|
||||
|| (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
|
||||
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__)
|
||||
constexpr unsigned int size = sizeof(__PRETTY_FUNCTION__);
|
||||
#else
|
||||
boost::typeindex::detail::failed_to_get_function_name<T>();
|
||||
#endif
|
||||
|
||||
boost::typeindex::detail::assert_compile_time_legths<
|
||||
(size > boost::typeindex::detail::ctti_skip_size_at_begin + boost::typeindex::detail::ctti_skip_size_at_end + sizeof("const *") - 1)
|
||||
>();
|
||||
static_assert(!boost::typeindex::detail::ctti_skip_more_at_runtime, "Skipping for GCC in C++14 mode is unsupported");
|
||||
|
||||
typedef typename boost::typeindex::detail::make_index_seq_impl<
|
||||
boost::typeindex::detail::ctti_skip_size_at_begin,
|
||||
size - sizeof("const *") + 1 - boost::typeindex::detail::ctti_skip_size_at_begin
|
||||
>::type idx_seq;
|
||||
return impl(idx_seq());
|
||||
}
|
||||
#else
|
||||
/// Returns raw name. Must be as short, as possible, to avoid code bloat
|
||||
BOOST_CXX14_CONSTEXPR static const char* n() BOOST_NOEXCEPT {
|
||||
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
|
||||
#elif defined(__FUNCSIG__)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__);
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
|| defined(__GNUC__) \
|
||||
|| (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
|
||||
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__) \
|
||||
|| defined(__clang__)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
|
||||
#else
|
||||
boost::typeindex::detail::failed_to_get_function_name<T>();
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
}} // 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-2014.
|
||||
// Copyright 2013-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -27,33 +27,31 @@
|
||||
#endif
|
||||
|
||||
#include <typeinfo>
|
||||
#include <cstring> // std::strcmp, std::strlen
|
||||
#include <cstring> // std::strcmp, std::strlen, std::strstr
|
||||
#include <stdexcept>
|
||||
#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>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
# include <cxxabi.h> // abi::__cxa_demangle
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MSVC)
|
||||
# include <boost/assert.hpp>
|
||||
# include <cstdlib> // std::free
|
||||
# include <algorithm> // std::find, std::search
|
||||
#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
|
||||
@ -133,66 +131,49 @@ inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
|
||||
return data_->name();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
class free_at_scope_exit {
|
||||
char* to_free_;
|
||||
|
||||
public:
|
||||
explicit free_at_scope_exit(char* to_free) BOOST_NOEXCEPT
|
||||
: to_free_(to_free)
|
||||
{}
|
||||
|
||||
~free_at_scope_exit() BOOST_NOEXCEPT {
|
||||
std::free(to_free_);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline std::string stl_type_index::pretty_name() const {
|
||||
static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
|
||||
static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
std::string ret = data_->name();
|
||||
std::string::size_type pos_beg = ret.find(cvr_saver_name);
|
||||
if (pos_beg == std::string::npos) {
|
||||
return ret;
|
||||
// In case of MSVC demangle() is a no-op, and name() already returns demangled name.
|
||||
// In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it.
|
||||
const boost::core::scoped_demangled_name demangled_name(data_->name());
|
||||
|
||||
const char* begin = demangled_name.get();
|
||||
if (!begin) {
|
||||
boost::throw_exception(std::runtime_error("Type name demangling failed"));
|
||||
}
|
||||
|
||||
const char* begin = ret.c_str() + pos_beg + sizeof(cvr_saver_name) - 1;
|
||||
const char* end = ret.c_str() + ret.size() - 1;
|
||||
#else
|
||||
int status = 0;
|
||||
char* demang = abi::__cxa_demangle(raw_name(), NULL, 0, &status);
|
||||
detail::free_at_scope_exit scope(demang);
|
||||
BOOST_ASSERT(!status);
|
||||
const std::size_t length = std::strlen(demang);
|
||||
const char* begin = std::search(
|
||||
demang, demang + length,
|
||||
cvr_saver_name, cvr_saver_name + sizeof(cvr_saver_name) - 1
|
||||
);
|
||||
const std::string::size_type len = std::strlen(begin);
|
||||
const char* end = begin + len;
|
||||
|
||||
if (begin == demang + length) {
|
||||
return std::string(demang, demang + length);
|
||||
}
|
||||
begin += sizeof(cvr_saver_name) - 1;
|
||||
const char* end = demang + length - 1;
|
||||
#endif
|
||||
while (*begin == ' ') { // begin is zero terminated
|
||||
++ begin;
|
||||
}
|
||||
if (len > cvr_saver_name_len) {
|
||||
const char* b = std::strstr(begin, cvr_saver_name);
|
||||
if (b) {
|
||||
b += cvr_saver_name_len;
|
||||
|
||||
while (end != begin && *end != '>') {
|
||||
-- end;
|
||||
}
|
||||
// Trim leading spaces
|
||||
while (*b == ' ') { // the string is zero terminated, we won't exceed the buffer size
|
||||
++ b;
|
||||
}
|
||||
|
||||
// we have cvr_saver_name somewhere at the start of the end
|
||||
while (end != begin && *(end - 1) == ' ') {
|
||||
-- end;
|
||||
}
|
||||
// Skip the closing angle bracket
|
||||
const char* e = end - 1;
|
||||
while (e > b && *e != '>') {
|
||||
-- e;
|
||||
}
|
||||
|
||||
if (begin >= end) {
|
||||
// Some strange error in demangled name parsing
|
||||
return begin;
|
||||
// Trim trailing spaces
|
||||
while (e > b && *(e - 1) == ' ') {
|
||||
-- e;
|
||||
}
|
||||
|
||||
if (b < e) {
|
||||
// Parsing seems to have succeeded, the type name is not empty
|
||||
begin = b;
|
||||
end = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::string(begin, end);
|
||||
@ -200,11 +181,11 @@ 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
|
||||
#else
|
||||
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -217,31 +198,28 @@ 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_;
|
||||
return !!(*data_ == *rhs.data_);
|
||||
#endif
|
||||
}
|
||||
|
||||
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>
|
||||
@ -253,11 +231,11 @@ inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT {
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
|
||||
// Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
|
||||
// in typeid() expressions. Full temaplte specialization for 'integral' fixes that issue:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
|
||||
boost::is_signed<no_cvr_prefinal_t>,
|
||||
// in typeid() expressions. Full template specialization for 'integral' fixes that issue:
|
||||
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;
|
||||
@ -274,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;
|
||||
@ -286,7 +264,7 @@ inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
|
||||
template <class T>
|
||||
inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_NO_RTTI
|
||||
#ifdef BOOST_NO_RTTI
|
||||
return value.boost_type_index_type_id_runtime_();
|
||||
#else
|
||||
return typeid(value);
|
||||
@ -295,6 +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-2014.
|
||||
// Copyright 2013-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -10,7 +10,7 @@
|
||||
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
@ -62,7 +62,7 @@ template <class Derived, class TypeInfo>
|
||||
class type_index_facade {
|
||||
private:
|
||||
/// @cond
|
||||
const Derived & derived() const BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR const Derived & derived() const BOOST_NOEXCEPT {
|
||||
return *static_cast<Derived const*>(this);
|
||||
}
|
||||
/// @endcond
|
||||
@ -70,13 +70,13 @@ public:
|
||||
typedef TypeInfo type_info_t;
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Name of a type. By default retuns Derived::raw_name().
|
||||
/// \return Name of a type. By default returns Derived::raw_name().
|
||||
inline const char* name() const BOOST_NOEXCEPT {
|
||||
return derived().raw_name();
|
||||
}
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides may throw.
|
||||
/// \return Human redable type name. By default retuns Derived::name().
|
||||
/// \return Human readable type name. By default returns Derived::name().
|
||||
inline std::string pretty_name() const {
|
||||
return derived().name();
|
||||
}
|
||||
@ -99,10 +99,11 @@ 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 = derived().raw_name();
|
||||
return boost::hash_range(name, name + std::strlen(name));
|
||||
const char* const name_raw = derived().raw_name();
|
||||
return boost::hash_range(name_raw, name_raw + std::strlen(name_raw));
|
||||
}
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
@ -150,34 +151,34 @@ protected:
|
||||
|
||||
/// @cond
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return static_cast<Derived const&>(lhs).equal(static_cast<Derived const&>(rhs));
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));;
|
||||
BOOST_CXX14_CONSTEXPR inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
@ -284,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,131 +0,0 @@
|
||||
From b59340efc30219492b095d2cfcdb8183b3e35b69 Mon Sep 17 00:00:00 2001
|
||||
From: Antony Polukhin <antoshkka@gmail.com>
|
||||
Date: Thu, 20 Feb 2014 17:06:44 +0400
|
||||
Subject: [PATCH 1/2] Boost.Any not can work without RTTI support.
|
||||
|
||||
---
|
||||
test/Jamfile.v2 | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
|
||||
index cd167dc..76f9e5a 100644
|
||||
--- a/test/Jamfile.v2
|
||||
+++ b/test/Jamfile.v2
|
||||
@@ -9,6 +9,7 @@
|
||||
test-suite any :
|
||||
[ run any_test.cpp ]
|
||||
[ run any_test_rv.cpp ]
|
||||
+ [ run any_test_rv.cpp : : : <rtti>off : any_test_rv_no_rtti ]
|
||||
[ compile-fail any_cast_cv_failed.cpp ]
|
||||
[ compile-fail any_test_temporary_to_ref_failed.cpp ]
|
||||
[ compile-fail any_test_cv_to_rv_failed.cpp ]
|
||||
--
|
||||
1.8.5.3
|
||||
|
||||
|
||||
From 62b9b01713fc50355f82e892bc0fd5618ce5c648 Mon Sep 17 00:00:00 2001
|
||||
From: Antony Polukhin <antoshkka@gmail.com>
|
||||
Date: Thu, 20 Feb 2014 17:30:42 +0400
|
||||
Subject: [PATCH 2/2] Boost.Any not can work without RTTI support.
|
||||
|
||||
---
|
||||
include/boost/any.hpp | 37 +++++++++++++------------------------
|
||||
1 file changed, 13 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/include/boost/any.hpp b/include/boost/any.hpp
|
||||
index a63fea4..bda00a2 100644
|
||||
--- a/include/boost/any.hpp
|
||||
+++ b/include/boost/any.hpp
|
||||
@@ -15,9 +15,9 @@
|
||||
// when: July 2001, April 2013 - May 2013
|
||||
|
||||
#include <algorithm>
|
||||
-#include <typeinfo>
|
||||
|
||||
#include "boost/config.hpp"
|
||||
+#include <boost/type_index.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
@@ -29,17 +29,6 @@
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
|
||||
-// See boost/python/type_id.hpp
|
||||
-// TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp
|
||||
-# if defined(__GNUC__) \
|
||||
- || defined(_AIX) \
|
||||
- || ( defined(__sgi) && defined(__host_mips)) \
|
||||
- || (defined(__hpux) && defined(__HP_aCC)) \
|
||||
- || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
|
||||
-# define BOOST_AUX_ANY_TYPE_ID_NAME
|
||||
-#include <cstring>
|
||||
-# endif
|
||||
-
|
||||
namespace boost
|
||||
{
|
||||
class any
|
||||
@@ -144,9 +133,9 @@ namespace boost
|
||||
any().swap(*this);
|
||||
}
|
||||
|
||||
- const std::type_info & type() const BOOST_NOEXCEPT
|
||||
+ const boost::typeind::type_info& type() const BOOST_NOEXCEPT
|
||||
{
|
||||
- return content ? content->type() : typeid(void);
|
||||
+ return content ? content->type() : boost::typeind::type_id<void>().type_info();
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
@@ -165,7 +154,7 @@ namespace boost
|
||||
|
||||
public: // queries
|
||||
|
||||
- virtual const std::type_info & type() const BOOST_NOEXCEPT = 0;
|
||||
+ virtual const boost::typeind::type_info& type() const BOOST_NOEXCEPT = 0;
|
||||
|
||||
virtual placeholder * clone() const = 0;
|
||||
|
||||
@@ -189,9 +178,9 @@ namespace boost
|
||||
#endif
|
||||
public: // queries
|
||||
|
||||
- virtual const std::type_info & type() const BOOST_NOEXCEPT
|
||||
+ virtual const boost::typeind::type_info& type() const BOOST_NOEXCEPT
|
||||
{
|
||||
- return typeid(ValueType);
|
||||
+ return boost::typeind::type_id<ValueType>().type_info();
|
||||
}
|
||||
|
||||
virtual placeholder * clone() const
|
||||
@@ -232,7 +221,12 @@ namespace boost
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
- class BOOST_SYMBOL_VISIBLE bad_any_cast : public std::bad_cast
|
||||
+ class BOOST_SYMBOL_VISIBLE bad_any_cast :
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
+ public std::bad_cast
|
||||
+#else
|
||||
+ public std::exception
|
||||
+#endif
|
||||
{
|
||||
public:
|
||||
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
@@ -245,12 +239,7 @@ namespace boost
|
||||
template<typename ValueType>
|
||||
ValueType * any_cast(any * operand) BOOST_NOEXCEPT
|
||||
{
|
||||
- return operand &&
|
||||
-#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
|
||||
- std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0
|
||||
-#else
|
||||
- operand->type() == typeid(ValueType)
|
||||
-#endif
|
||||
+ return operand && operand->type() == boost::typeind::type_id<ValueType>()
|
||||
? &static_cast<any::holder<ValueType> *>(operand->content)->held
|
||||
: 0;
|
||||
}
|
||||
--
|
||||
1.8.5.3
|
||||
|
@ -1,60 +0,0 @@
|
||||
From 6f71069e85fab36d9b95d53ddb6d80b8d1bdb6b0 Mon Sep 17 00:00:00 2001
|
||||
From: Antony Polukhin <antoshkka@gmail.com>
|
||||
Date: Thu, 20 Feb 2014 18:33:20 +0400
|
||||
Subject: [PATCH] Use TypeIndex in Boost.Function to remove duplicate code and
|
||||
improve code performance
|
||||
|
||||
---
|
||||
include/boost/function/function_base.hpp | 22 +---------------------
|
||||
test/Jamfile.v2 | 2 ++
|
||||
2 files changed, 3 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp
|
||||
index f3663d7..8fd2c8d 100644
|
||||
--- a/include/boost/function/function_base.hpp
|
||||
+++ b/include/boost/function/function_base.hpp
|
||||
@@ -44,27 +44,7 @@
|
||||
# pragma warning( disable : 4127 ) // "conditional expression is constant"
|
||||
#endif
|
||||
|
||||
-// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
|
||||
-#ifdef BOOST_NO_STD_TYPEINFO
|
||||
-// Embedded VC++ does not have type_info in namespace std
|
||||
-# define BOOST_FUNCTION_STD_NS
|
||||
-#else
|
||||
-# define BOOST_FUNCTION_STD_NS std
|
||||
-#endif
|
||||
-
|
||||
-// Borrowed from Boost.Python library: determines the cases where we
|
||||
-// need to use std::type_info::name to compare instead of operator==.
|
||||
-#if defined( BOOST_NO_TYPEID )
|
||||
-# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
|
||||
-#elif defined(__GNUC__) \
|
||||
- || defined(_AIX) \
|
||||
- || ( defined(__sgi) && defined(__host_mips))
|
||||
-# include <cstring>
|
||||
-# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \
|
||||
- (std::strcmp((X).name(),(Y).name()) == 0)
|
||||
-# else
|
||||
-# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
|
||||
-#endif
|
||||
+#define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) (boost::typeind::type_index((X))==(Y))
|
||||
|
||||
#if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG)
|
||||
# define BOOST_FUNCTION_TARGET_FIX(x) x
|
||||
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
|
||||
index 68895fa..12a00db 100644
|
||||
--- a/test/Jamfile.v2
|
||||
+++ b/test/Jamfile.v2
|
||||
@@ -21,6 +21,8 @@ import testing ;
|
||||
:
|
||||
[ run libs/function/test/function_test.cpp : : : : lib_function_test ]
|
||||
|
||||
+ [ run libs/function/test/function_test.cpp : : : <rtti>off : lib_function_test_no_rtti ]
|
||||
+
|
||||
[ run libs/function/test/function_n_test.cpp : : : : ]
|
||||
|
||||
[ run libs/function/test/allocator_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : : ]
|
||||
--
|
||||
1.8.5.3
|
||||
|
@ -1,70 +0,0 @@
|
||||
From 21f31f2ceb6d5669ca4e0bcc7b62cf1836eb7002 Mon Sep 17 00:00:00 2001
|
||||
From: Antony Polukhin <antoshkka@gmail.com>
|
||||
Date: Thu, 20 Feb 2014 17:26:24 +0400
|
||||
Subject: [PATCH] Boost.Variant not can work without RTTI support.
|
||||
|
||||
---
|
||||
include/boost/variant/variant.hpp | 19 +++++--------------
|
||||
1 file changed, 5 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/include/boost/variant/variant.hpp b/include/boost/variant/variant.hpp
|
||||
index 46c3ae3..8604ba9 100644
|
||||
--- a/include/boost/variant/variant.hpp
|
||||
+++ b/include/boost/variant/variant.hpp
|
||||
@@ -18,9 +18,7 @@
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <new> // for placement new
|
||||
|
||||
-#if !defined(BOOST_NO_TYPEID)
|
||||
-#include <typeinfo> // for typeid, std::type_info
|
||||
-#endif // BOOST_NO_TYPEID
|
||||
+#include "boost/type_index.hpp"
|
||||
|
||||
#include "boost/variant/detail/config.hpp"
|
||||
#include "boost/mpl/aux_/value_wknd.hpp"
|
||||
@@ -829,24 +827,19 @@ private:
|
||||
//
|
||||
// Generic static visitor that performs a typeid on the value it visits.
|
||||
//
|
||||
-
|
||||
-#if !defined(BOOST_NO_TYPEID)
|
||||
-
|
||||
class reflect
|
||||
- : public static_visitor<const std::type_info&>
|
||||
+ : public static_visitor<const boost::typeind::type_info&>
|
||||
{
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename T>
|
||||
- const std::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
+ const boost::typeind::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
{
|
||||
- return typeid(T);
|
||||
+ return boost::typeind::type_id<T>().type_info();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
-#endif // BOOST_NO_TYPEID
|
||||
-
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) class comparer
|
||||
//
|
||||
@@ -2155,13 +2148,11 @@ public: // queries
|
||||
return false;
|
||||
}
|
||||
|
||||
-#if !defined(BOOST_NO_TYPEID)
|
||||
- const std::type_info& type() const
|
||||
+ const boost::typeind::type_info& type() const
|
||||
{
|
||||
detail::variant::reflect visitor;
|
||||
return this->apply_visitor(visitor);
|
||||
}
|
||||
-#endif
|
||||
|
||||
public: // prevent comparison with foreign types
|
||||
|
||||
--
|
||||
1.8.5.3
|
||||
|
@ -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
|
||||
@ -35,24 +35,32 @@ obj test_lib_rtti_compat-obj : test_lib.cpp : <link>shared $(nortti) $(compat) ;
|
||||
lib test_lib_nortti_compat : test_lib_nortti_compat-obj : <link>shared $(nortti) $(compat) ;
|
||||
lib test_lib_rtti_compat : test_lib_rtti_compat-obj : <link>shared $(nortti) $(compat) ;
|
||||
|
||||
exe testing_crossmodule_anonymous_no_rtti : testing_crossmodule_anonymous.cpp test_lib_anonymous_nortti : <rtti>off $(norttidefines) ;
|
||||
|
||||
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_nortti : : : <rtti>off $(norttidefines) : testing_crossmodule_anonymous_no_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-, that's why the following tests is disabled
|
||||
#[ 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 ]
|
||||
;
|
||||
|
90
test/appveyor.yml
Normal file
90
test/appveyor.yml
Normal file
@ -0,0 +1,90 @@
|
||||
# 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 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 #6
|
||||
|
||||
init:
|
||||
# boost-local/libs/ folder to put this library into. This may be useful, if you're for example running Travis
|
||||
# from `Boost.DLL` repo while Boost already has `dll` and with to replace `dll` with content of`Boost.DLL`.
|
||||
#
|
||||
# Otherwise just leave the default value - set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
|
||||
- set BOOST_LIBS_FOLDER=%APPVEYOR_PROJECT_NAME%
|
||||
|
||||
###############################################################################################################
|
||||
# From this point and below code is same for all the Boost libs
|
||||
###############################################################################################################
|
||||
|
||||
version: 1.64.{build}-{branch}
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
skip_tags: true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
|
||||
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 BOOST_BRANCH=develop
|
||||
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
- echo "Testing %APPVEYOR_PROJECT_NAME%"
|
||||
# Cloning Boost libraries (fast nondeep cloning)
|
||||
- set BOOST=C:/boost-local
|
||||
- git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git %BOOST%
|
||||
- cd %BOOST%
|
||||
- git submodule update --init --depth 10 tools/build tools/boostdep 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:
|
||||
- cmd /c bootstrap
|
||||
- b2.exe headers
|
||||
- cd %BOOST%/libs/%BOOST_LIBS_FOLDER%/test
|
||||
|
||||
after_build:
|
||||
before_test:
|
||||
test_script:
|
||||
- PATH=%ADDPATH%%PATH%
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
- echo "Running command ..\..\..\b2 -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release"
|
||||
- ..\..\..\b2.exe -j3 toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release cxxflags="-DBOOST_TRAVISCI_BUILD"
|
||||
|
||||
after_test:
|
||||
on_success:
|
||||
on_failure:
|
||||
on_finish:
|
67
test/compare_ctti_stl.cpp
Normal file
67
test/compare_ctti_stl.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
// 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
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
#include <boost/type_index/stl_type_index.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
|
||||
namespace my_namespace2 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
namespace my_namespace3
|
||||
{
|
||||
template<typename T, typename U>
|
||||
struct my_template {};
|
||||
|
||||
}
|
||||
|
||||
#if !defined( BOOST_NO_RTTI )
|
||||
|
||||
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()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
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> >();
|
||||
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright 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
|
||||
@ -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,3 +1,11 @@
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#define TEST_LIB_SOURCE
|
||||
#include "test_lib.hpp"
|
||||
|
||||
@ -23,9 +31,10 @@ boost::typeindex::type_index get_const_user_defined_class() {
|
||||
return boost::typeindex::type_id_with_cvr<const user_defined_namespace::user_defined>();
|
||||
}
|
||||
|
||||
|
||||
#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-2013.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -31,8 +31,10 @@ 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();
|
||||
|
||||
#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,3 +1,11 @@
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#define TEST_LIB_SOURCE
|
||||
#include "test_lib_anonymous.hpp"
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,17 +1,14 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
// 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)
|
||||
|
||||
#include <boost/test/minimal.hpp>
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include "test_lib.hpp"
|
||||
|
||||
#define BOOST_CHECK_EQUAL(x, y) BOOST_CHECK(x == y)
|
||||
#define BOOST_CHECK_NE(x, y) BOOST_CHECK(x != y)
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
namespace user_defined_namespace {
|
||||
class user_defined{};
|
||||
@ -22,10 +19,10 @@ void comparing_types_between_modules()
|
||||
boost::typeindex::type_index t_const_int = boost::typeindex::type_id_with_cvr<const int>();
|
||||
boost::typeindex::type_index t_int = boost::typeindex::type_id<int>();
|
||||
|
||||
BOOST_CHECK_EQUAL(t_int, test_lib::get_integer());
|
||||
BOOST_CHECK_EQUAL(t_const_int, test_lib::get_const_integer());
|
||||
BOOST_CHECK_NE(t_const_int, test_lib::get_integer());
|
||||
BOOST_CHECK_NE(t_int, test_lib::get_const_integer());
|
||||
BOOST_TEST_EQ(t_int, test_lib::get_integer());
|
||||
BOOST_TEST_EQ(t_const_int, test_lib::get_const_integer());
|
||||
BOOST_TEST_NE(t_const_int, test_lib::get_integer());
|
||||
BOOST_TEST_NE(t_int, test_lib::get_const_integer());
|
||||
|
||||
|
||||
boost::typeindex::type_index t_const_userdef
|
||||
@ -33,24 +30,28 @@ void comparing_types_between_modules()
|
||||
boost::typeindex::type_index t_userdef
|
||||
= boost::typeindex::type_id<user_defined_namespace::user_defined>();
|
||||
|
||||
BOOST_CHECK_EQUAL(t_userdef, test_lib::get_user_defined_class());
|
||||
BOOST_CHECK_EQUAL(t_const_userdef, test_lib::get_const_user_defined_class());
|
||||
BOOST_CHECK_NE(t_const_userdef, test_lib::get_user_defined_class());
|
||||
BOOST_CHECK_NE(t_userdef, test_lib::get_const_user_defined_class());
|
||||
BOOST_TEST_EQ(t_userdef, test_lib::get_user_defined_class());
|
||||
BOOST_TEST_EQ(t_const_userdef, test_lib::get_const_user_defined_class());
|
||||
BOOST_TEST_NE(t_const_userdef, test_lib::get_user_defined_class());
|
||||
BOOST_TEST_NE(t_userdef, test_lib::get_const_user_defined_class());
|
||||
|
||||
|
||||
BOOST_CHECK_NE(t_userdef, test_lib::get_integer());
|
||||
BOOST_CHECK_NE(t_const_userdef, test_lib::get_integer());
|
||||
BOOST_CHECK_NE(t_int, test_lib::get_user_defined_class());
|
||||
BOOST_CHECK_NE(t_const_int, test_lib::get_const_user_defined_class());
|
||||
BOOST_TEST_NE(t_userdef, test_lib::get_integer());
|
||||
BOOST_TEST_NE(t_const_userdef, test_lib::get_integer());
|
||||
BOOST_TEST_NE(t_int, test_lib::get_user_defined_class());
|
||||
BOOST_TEST_NE(t_const_int, test_lib::get_const_user_defined_class());
|
||||
|
||||
test_lib::accept_typeindex(t_int);
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
int test_main(int , char* []) {
|
||||
int main() {
|
||||
comparing_types_between_modules();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,17 @@
|
||||
//
|
||||
// Copyright 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)
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include "test_lib_anonymous.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define BOOST_CHECK_NE(x, y) BOOST_CHECK(x != y)
|
||||
|
||||
namespace {
|
||||
@ -21,15 +23,26 @@ 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_CHECK_NE(t_userdef, test_lib::get_anonymous_user_defined_class());
|
||||
BOOST_CHECK_NE(t_const_userdef, test_lib::get_const_anonymous_user_defined_class());
|
||||
BOOST_CHECK_NE(t_const_userdef, test_lib::get_anonymous_user_defined_class());
|
||||
BOOST_CHECK_NE(t_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());
|
||||
}
|
||||
|
||||
int test_main(int , char* []) {
|
||||
int main() {
|
||||
comparing_anonymous_types_between_modules();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
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();
|
||||
}
|
||||
|
157
test/type_index_constexpr_test.cpp
Normal file
157
test/type_index_constexpr_test.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
//
|
||||
// Copyright 2015-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 <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
const char* hello1 = "Hello word";
|
||||
const char* hello1_end = hello1 + sizeof("Hello word");
|
||||
const char* hello2 = "Hello word, pal!";
|
||||
const char* hello2_end = hello2 + sizeof("Hello word, pal!");
|
||||
|
||||
void strcmp_same() {
|
||||
using boost::typeindex::detail::constexpr_strcmp;
|
||||
|
||||
BOOST_TEST(
|
||||
constexpr_strcmp(hello1, hello1) == 0
|
||||
);
|
||||
|
||||
BOOST_TEST(
|
||||
constexpr_strcmp(hello2, hello2) == 0
|
||||
);
|
||||
|
||||
BOOST_TEST(
|
||||
constexpr_strcmp(hello1, hello2) != 0
|
||||
);
|
||||
|
||||
BOOST_TEST(
|
||||
constexpr_strcmp(hello2, hello1) != 0
|
||||
);
|
||||
|
||||
BOOST_TEST(
|
||||
(constexpr_strcmp(hello2, hello1) < 0)
|
||||
==
|
||||
(std::strcmp(hello2, hello1) < 0)
|
||||
);
|
||||
|
||||
BOOST_TEST(
|
||||
(constexpr_strcmp(hello1, hello2) < 0)
|
||||
==
|
||||
(std::strcmp(hello1, hello2) < 0)
|
||||
);
|
||||
}
|
||||
|
||||
void search_same() {
|
||||
using boost::typeindex::detail::constexpr_search;
|
||||
BOOST_TEST(
|
||||
constexpr_search(hello1, hello1_end, hello2, hello2_end) == std::search(hello1, hello1_end, hello2, hello2_end)
|
||||
);
|
||||
|
||||
BOOST_TEST(
|
||||
constexpr_search(hello2, hello2_end, hello1, hello1_end) == std::search(hello2, hello2_end, hello1, hello1_end)
|
||||
);
|
||||
|
||||
const char* word = "word";
|
||||
const char* word_end = word + sizeof("word") - 1;
|
||||
BOOST_TEST(
|
||||
constexpr_search(hello1, hello1_end, word, word_end) == std::search(hello1, hello1_end, word, word_end)
|
||||
);
|
||||
|
||||
BOOST_TEST(
|
||||
constexpr_search(hello2, hello2_end, word, word_end) == std::search(hello2, hello2_end, word, word_end)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T, std::size_t N>
|
||||
BOOST_CXX14_CONSTEXPR bool in_namespace(const char (&ns)[N]) BOOST_NOEXCEPT {
|
||||
BOOST_CXX14_CONSTEXPR const char* name = boost::typeindex::ctti_type_index::type_id<T>().raw_name();
|
||||
for (std::size_t i = 0; i < N - 1; ++i)
|
||||
if (name[i] != ns[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
BOOST_CXX14_CONSTEXPR bool is_boost_namespace() BOOST_NOEXCEPT {
|
||||
return in_namespace<T>("boost::") || in_namespace<T>("class boost::") || in_namespace<T>("struct boost::");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool same1 = (t_short1 == t_short0);
|
||||
BOOST_TEST(same1);
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool same2 = (t_int1 == t_int1);
|
||||
BOOST_TEST(same2);
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool same3 = (t_short0 == t_short0);
|
||||
BOOST_TEST(same3);
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool same4 = !(t_short0 < t_short0 || t_short0 > t_short0);
|
||||
BOOST_TEST(same4);
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool same5 = (t_short0 <= t_short0 && t_short0 >= t_short0);
|
||||
BOOST_TEST(same5);
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool not_same0 = (t_int0 != t_short1);
|
||||
BOOST_TEST(not_same0);
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool not_same1 = (t_int1 != t_short0);
|
||||
BOOST_TEST(not_same1);
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool not_same2 = (t_int1 < t_short0 || t_int1 > t_short0);
|
||||
BOOST_TEST(not_same2);
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR const char* int_name = t_int0.name();
|
||||
BOOST_TEST(*int_name != '\0');
|
||||
|
||||
BOOST_CXX14_CONSTEXPR const char* short_name = t_short0.name();
|
||||
BOOST_TEST(*short_name != '\0');
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool in_namespace = is_boost_namespace<ctti_type_index>();
|
||||
BOOST_TEST(in_namespace);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
strcmp_same();
|
||||
search_same();
|
||||
constexpr_test();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
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,22 +1,15 @@
|
||||
//
|
||||
// Copyright 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)
|
||||
|
||||
#include <boost/test/minimal.hpp>
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#define BOOST_CHECK_EQUAL(x, y) BOOST_CHECK(x == y)
|
||||
#define BOOST_CHECK_NE(x, y) BOOST_CHECK(x != y)
|
||||
#define BOOST_CHECK_LE(x, y) BOOST_CHECK(x <= y)
|
||||
#define BOOST_CHECK_GE(x, y) BOOST_CHECK(x >= y)
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
@ -31,24 +24,24 @@ namespace my_namespace2 {
|
||||
void names_matches_type_id()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
BOOST_CHECK_EQUAL(type_id<int>().pretty_name(), "int");
|
||||
BOOST_CHECK_EQUAL(type_id<double>().pretty_name(), "double");
|
||||
BOOST_TEST_EQ(type_id<int>().pretty_name(), "int");
|
||||
BOOST_TEST_EQ(type_id<double>().pretty_name(), "double");
|
||||
|
||||
BOOST_CHECK_EQUAL(type_id<int>().name(), type_id<int>().name());
|
||||
BOOST_CHECK_NE(type_id<int>().name(), type_id<double>().name());
|
||||
BOOST_CHECK_NE(type_id<double>().name(), type_id<int>().name());
|
||||
BOOST_CHECK_EQUAL(type_id<double>().name(), type_id<double>().name());
|
||||
BOOST_TEST_EQ(type_id<int>().name(), type_id<int>().name());
|
||||
BOOST_TEST_NE(type_id<int>().name(), type_id<double>().name());
|
||||
BOOST_TEST_NE(type_id<double>().name(), type_id<int>().name());
|
||||
BOOST_TEST_EQ(type_id<double>().name(), type_id<double>().name());
|
||||
}
|
||||
|
||||
void default_construction()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
type_index ti1, ti2;
|
||||
BOOST_CHECK_EQUAL(ti1, ti2);
|
||||
BOOST_CHECK_EQUAL(type_id<void>(), ti1);
|
||||
BOOST_TEST_EQ(ti1, ti2);
|
||||
BOOST_TEST_EQ(type_id<void>(), ti1);
|
||||
|
||||
BOOST_CHECK_EQUAL(type_id<void>().name(), ti1.name());
|
||||
BOOST_CHECK_NE(type_id<int>(), ti1);
|
||||
BOOST_TEST_EQ(type_id<void>().name(), ti1.name());
|
||||
BOOST_TEST_NE(type_id<int>(), ti1);
|
||||
}
|
||||
|
||||
|
||||
@ -56,12 +49,12 @@ void copy_construction()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
type_index ti1, ti2 = type_id<int>();
|
||||
BOOST_CHECK_NE(ti1, ti2);
|
||||
BOOST_TEST_NE(ti1, ti2);
|
||||
ti1 = ti2;
|
||||
BOOST_CHECK_EQUAL(ti2, ti1);
|
||||
BOOST_TEST_EQ(ti2, ti1);
|
||||
|
||||
const type_index ti3(ti1);
|
||||
BOOST_CHECK_EQUAL(ti3, ti1);
|
||||
BOOST_TEST_EQ(ti3, ti1);
|
||||
}
|
||||
|
||||
void comparators_type_id()
|
||||
@ -70,17 +63,17 @@ void comparators_type_id()
|
||||
type_index t_int = type_id<int>();
|
||||
type_index t_double = type_id<double>();
|
||||
|
||||
BOOST_CHECK_EQUAL(t_int, t_int);
|
||||
BOOST_CHECK_LE(t_int, t_int);
|
||||
BOOST_CHECK_GE(t_int, t_int);
|
||||
BOOST_CHECK_NE(t_int, t_double);
|
||||
BOOST_TEST_EQ(t_int, t_int);
|
||||
BOOST_TEST_LE(t_int, t_int);
|
||||
BOOST_TEST_GE(t_int, t_int);
|
||||
BOOST_TEST_NE(t_int, t_double);
|
||||
|
||||
BOOST_CHECK_LE(t_double, t_double);
|
||||
BOOST_CHECK_GE(t_double, t_double);
|
||||
BOOST_CHECK_NE(t_double, t_int);
|
||||
BOOST_TEST_LE(t_double, t_double);
|
||||
BOOST_TEST_GE(t_double, t_double);
|
||||
BOOST_TEST_NE(t_double, t_int);
|
||||
|
||||
BOOST_CHECK(t_double < t_int || t_int < t_double);
|
||||
BOOST_CHECK(t_double > t_int || t_int > t_double);
|
||||
BOOST_TEST(t_double < t_int || t_int < t_double);
|
||||
BOOST_TEST(t_double > t_int || t_int > t_double);
|
||||
}
|
||||
|
||||
void hash_code_type_id()
|
||||
@ -92,9 +85,9 @@ void hash_code_type_id()
|
||||
std::size_t t_int2 = type_id<int>().hash_code();
|
||||
std::size_t t_double2 = type_id<double>().hash_code();
|
||||
|
||||
BOOST_CHECK_EQUAL(t_int1, t_int2);
|
||||
BOOST_CHECK_NE(t_int1, t_double2);
|
||||
BOOST_CHECK_LE(t_double1, t_double2);
|
||||
BOOST_TEST_EQ(t_int1, t_int2);
|
||||
BOOST_TEST_NE(t_int1, t_double2);
|
||||
BOOST_TEST_LE(t_double1, t_double2);
|
||||
}
|
||||
|
||||
|
||||
@ -106,37 +99,37 @@ static void test_with_modofiers() {
|
||||
type_index t1 = type_id_with_cvr<T1>();
|
||||
type_index t2 = type_id_with_cvr<T2>();
|
||||
|
||||
BOOST_CHECK_NE(t2, t1);
|
||||
BOOST_CHECK(t2 != t1.type_info());
|
||||
BOOST_CHECK(t2.type_info() != t1);
|
||||
BOOST_TEST_NE(t2, t1);
|
||||
BOOST_TEST(t2 != t1.type_info());
|
||||
BOOST_TEST(t2.type_info() != t1);
|
||||
|
||||
BOOST_CHECK(t1 < t2 || t2 < t1);
|
||||
BOOST_CHECK(t1 > t2 || t2 > t1);
|
||||
BOOST_CHECK(t1.type_info() < t2 || t2.type_info() < t1);
|
||||
BOOST_CHECK(t1.type_info() > t2 || t2.type_info() > t1);
|
||||
BOOST_CHECK(t1 < t2.type_info() || t2 < t1.type_info());
|
||||
BOOST_CHECK(t1 > t2.type_info() || t2 > t1.type_info());
|
||||
BOOST_TEST(t1 < t2 || t2 < t1);
|
||||
BOOST_TEST(t1 > t2 || t2 > t1);
|
||||
BOOST_TEST(t1.type_info() < t2 || t2.type_info() < t1);
|
||||
BOOST_TEST(t1.type_info() > t2 || t2.type_info() > t1);
|
||||
BOOST_TEST(t1 < t2.type_info() || t2 < t1.type_info());
|
||||
BOOST_TEST(t1 > t2.type_info() || t2 > t1.type_info());
|
||||
|
||||
// Chaecking that comparisom operators overloads compile
|
||||
BOOST_CHECK(t1 <= t2 || t2 <= t1);
|
||||
BOOST_CHECK(t1 >= t2 || t2 >= t1);
|
||||
BOOST_CHECK(t1.type_info() <= t2 || t2.type_info() <= t1);
|
||||
BOOST_CHECK(t1.type_info() >= t2 || t2.type_info() >= t1);
|
||||
BOOST_CHECK(t1 <= t2.type_info() || t2 <= t1.type_info());
|
||||
BOOST_CHECK(t1 >= t2.type_info() || t2 >= t1.type_info());
|
||||
// Chaecking that comparison operators overloads compile
|
||||
BOOST_TEST(t1 <= t2 || t2 <= t1);
|
||||
BOOST_TEST(t1 >= t2 || t2 >= t1);
|
||||
BOOST_TEST(t1.type_info() <= t2 || t2.type_info() <= t1);
|
||||
BOOST_TEST(t1.type_info() >= t2 || t2.type_info() >= t1);
|
||||
BOOST_TEST(t1 <= t2.type_info() || t2 <= t1.type_info());
|
||||
BOOST_TEST(t1 >= t2.type_info() || t2 >= t1.type_info());
|
||||
|
||||
BOOST_CHECK_EQUAL(t1, type_id_with_cvr<T1>());
|
||||
BOOST_CHECK_EQUAL(t2, type_id_with_cvr<T2>());
|
||||
BOOST_CHECK(t1 == type_id_with_cvr<T1>().type_info());
|
||||
BOOST_CHECK(t2 == type_id_with_cvr<T2>().type_info());
|
||||
BOOST_CHECK(t1.type_info() == type_id_with_cvr<T1>());
|
||||
BOOST_CHECK(t2.type_info() == type_id_with_cvr<T2>());
|
||||
BOOST_TEST_EQ(t1, type_id_with_cvr<T1>());
|
||||
BOOST_TEST_EQ(t2, type_id_with_cvr<T2>());
|
||||
BOOST_TEST(t1 == type_id_with_cvr<T1>().type_info());
|
||||
BOOST_TEST(t2 == type_id_with_cvr<T2>().type_info());
|
||||
BOOST_TEST(t1.type_info() == type_id_with_cvr<T1>());
|
||||
BOOST_TEST(t2.type_info() == type_id_with_cvr<T2>());
|
||||
|
||||
BOOST_CHECK_EQUAL(t1.hash_code(), type_id_with_cvr<T1>().hash_code());
|
||||
BOOST_CHECK_EQUAL(t2.hash_code(), type_id_with_cvr<T2>().hash_code());
|
||||
BOOST_TEST_EQ(t1.hash_code(), type_id_with_cvr<T1>().hash_code());
|
||||
BOOST_TEST_EQ(t2.hash_code(), type_id_with_cvr<T2>().hash_code());
|
||||
|
||||
BOOST_CHECK_NE(t1.hash_code(), type_id_with_cvr<T2>().hash_code());
|
||||
BOOST_CHECK_NE(t2.hash_code(), type_id_with_cvr<T1>().hash_code());
|
||||
BOOST_TEST_NE(t1.hash_code(), type_id_with_cvr<T2>().hash_code());
|
||||
BOOST_TEST_NE(t2.hash_code(), type_id_with_cvr<T1>().hash_code());
|
||||
}
|
||||
|
||||
void type_id_storing_modifiers()
|
||||
@ -194,14 +187,14 @@ static void test_storing_nonstoring_modifiers_templ() {
|
||||
type_index t1 = type_id_with_cvr<T>();
|
||||
type_index t2 = type_id<T>();
|
||||
|
||||
BOOST_CHECK_EQUAL(t2, t1);
|
||||
BOOST_CHECK_EQUAL(t1, t2);
|
||||
BOOST_CHECK(t1 <= t2);
|
||||
BOOST_CHECK(t1 >= t2);
|
||||
BOOST_CHECK(t2 <= t1);
|
||||
BOOST_CHECK(t2 >= t1);
|
||||
BOOST_TEST_EQ(t2, t1);
|
||||
BOOST_TEST_EQ(t1, t2);
|
||||
BOOST_TEST(t1 <= t2);
|
||||
BOOST_TEST(t1 >= t2);
|
||||
BOOST_TEST(t2 <= t1);
|
||||
BOOST_TEST(t2 >= t1);
|
||||
|
||||
BOOST_CHECK_EQUAL(t2.pretty_name(), t1.pretty_name());
|
||||
BOOST_TEST_EQ(t2.pretty_name(), t1.pretty_name());
|
||||
}
|
||||
|
||||
void type_id_storing_modifiers_vs_nonstoring()
|
||||
@ -212,8 +205,8 @@ void type_id_storing_modifiers_vs_nonstoring()
|
||||
|
||||
boost::typeindex::type_index t1 = boost::typeindex::type_id_with_cvr<const int>();
|
||||
boost::typeindex::type_index t2 = boost::typeindex::type_id<int>();
|
||||
BOOST_CHECK_NE(t2, t1);
|
||||
BOOST_CHECK(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
|
||||
BOOST_TEST_NE(t2, t1);
|
||||
BOOST_TEST(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
|
||||
}
|
||||
|
||||
void type_index_stream_operator_via_lexical_cast_testing()
|
||||
@ -221,32 +214,32 @@ void type_index_stream_operator_via_lexical_cast_testing()
|
||||
using namespace boost::typeindex;
|
||||
|
||||
std::string s_int2 = boost::lexical_cast<std::string>(type_id<int>());
|
||||
BOOST_CHECK_EQUAL(s_int2, "int");
|
||||
BOOST_TEST_EQ(s_int2, "int");
|
||||
|
||||
std::string s_double2 = boost::lexical_cast<std::string>(type_id<double>());
|
||||
BOOST_CHECK_EQUAL(s_double2, "double");
|
||||
BOOST_TEST_EQ(s_double2, "double");
|
||||
}
|
||||
|
||||
void type_index_stripping_cvr_test()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
|
||||
BOOST_CHECK_EQUAL(type_id<int>(), type_id<const int>());
|
||||
BOOST_CHECK_EQUAL(type_id<int>(), type_id<const volatile int>());
|
||||
BOOST_CHECK_EQUAL(type_id<int>(), type_id<const volatile int&>());
|
||||
BOOST_TEST_EQ(type_id<int>(), type_id<const int>());
|
||||
BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int>());
|
||||
BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int&>());
|
||||
|
||||
BOOST_CHECK_EQUAL(type_id<int>(), type_id<int&>());
|
||||
BOOST_CHECK_EQUAL(type_id<int>(), type_id<volatile int>());
|
||||
BOOST_CHECK_EQUAL(type_id<int>(), type_id<volatile int&>());
|
||||
BOOST_TEST_EQ(type_id<int>(), type_id<int&>());
|
||||
BOOST_TEST_EQ(type_id<int>(), type_id<volatile int>());
|
||||
BOOST_TEST_EQ(type_id<int>(), type_id<volatile int&>());
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(type_id<double>(), type_id<const double>());
|
||||
BOOST_CHECK_EQUAL(type_id<double>(), type_id<const volatile double>());
|
||||
BOOST_CHECK_EQUAL(type_id<double>(), type_id<const volatile double&>());
|
||||
BOOST_TEST_EQ(type_id<double>(), type_id<const double>());
|
||||
BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double>());
|
||||
BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double&>());
|
||||
|
||||
BOOST_CHECK_EQUAL(type_id<double>(), type_id<double&>());
|
||||
BOOST_CHECK_EQUAL(type_id<double>(), type_id<volatile double>());
|
||||
BOOST_CHECK_EQUAL(type_id<double>(), type_id<volatile double&>());
|
||||
BOOST_TEST_EQ(type_id<double>(), type_id<double&>());
|
||||
BOOST_TEST_EQ(type_id<double>(), type_id<volatile double>());
|
||||
BOOST_TEST_EQ(type_id<double>(), type_id<volatile double&>());
|
||||
}
|
||||
|
||||
|
||||
@ -254,18 +247,18 @@ void type_index_user_defined_class_test()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
|
||||
BOOST_CHECK_EQUAL(type_id<my_namespace1::my_class>(), type_id<my_namespace1::my_class>());
|
||||
BOOST_CHECK_EQUAL(type_id<my_namespace2::my_class>(), type_id<my_namespace2::my_class>());
|
||||
BOOST_TEST_EQ(type_id<my_namespace1::my_class>(), type_id<my_namespace1::my_class>());
|
||||
BOOST_TEST_EQ(type_id<my_namespace2::my_class>(), type_id<my_namespace2::my_class>());
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
BOOST_CHECK(type_id<my_namespace1::my_class>() == typeid(my_namespace1::my_class));
|
||||
BOOST_CHECK(type_id<my_namespace2::my_class>() == typeid(my_namespace2::my_class));
|
||||
BOOST_CHECK(typeid(my_namespace1::my_class) == type_id<my_namespace1::my_class>());
|
||||
BOOST_CHECK(typeid(my_namespace2::my_class) == type_id<my_namespace2::my_class>());
|
||||
BOOST_TEST(type_id<my_namespace1::my_class>() == typeid(my_namespace1::my_class));
|
||||
BOOST_TEST(type_id<my_namespace2::my_class>() == typeid(my_namespace2::my_class));
|
||||
BOOST_TEST(typeid(my_namespace1::my_class) == type_id<my_namespace1::my_class>());
|
||||
BOOST_TEST(typeid(my_namespace2::my_class) == type_id<my_namespace2::my_class>());
|
||||
#endif
|
||||
|
||||
BOOST_CHECK_NE(type_id<my_namespace1::my_class>(), type_id<my_namespace2::my_class>());
|
||||
BOOST_CHECK_NE(
|
||||
BOOST_TEST_NE(type_id<my_namespace1::my_class>(), type_id<my_namespace2::my_class>());
|
||||
BOOST_TEST_NE(
|
||||
type_id<my_namespace1::my_class>().pretty_name().find("my_namespace1::my_class"),
|
||||
std::string::npos);
|
||||
}
|
||||
@ -298,37 +291,37 @@ void comparators_type_id_runtime()
|
||||
A& rb1 = b1;
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
BOOST_CHECK(typeid(rc1) == typeid(*pc1));
|
||||
BOOST_CHECK(typeid(rb1) == typeid(*pb1));
|
||||
BOOST_TEST(typeid(rc1) == typeid(*pc1));
|
||||
BOOST_TEST(typeid(rb1) == typeid(*pb1));
|
||||
|
||||
BOOST_CHECK(typeid(rc1) != typeid(*pb1));
|
||||
BOOST_CHECK(typeid(rb1) != typeid(*pc1));
|
||||
BOOST_TEST(typeid(rc1) != typeid(*pb1));
|
||||
BOOST_TEST(typeid(rb1) != typeid(*pc1));
|
||||
|
||||
BOOST_CHECK(typeid(&rc1) == typeid(pb1));
|
||||
BOOST_CHECK(typeid(&rb1) == typeid(pc1));
|
||||
BOOST_TEST(typeid(&rc1) == typeid(pb1));
|
||||
BOOST_TEST(typeid(&rb1) == typeid(pc1));
|
||||
#else
|
||||
BOOST_CHECK(boost::typeindex::type_index(pc1->boost_type_index_type_id_runtime_()).raw_name());
|
||||
BOOST_TEST(boost::typeindex::type_index(pc1->boost_type_index_type_id_runtime_()).raw_name());
|
||||
#endif
|
||||
|
||||
BOOST_CHECK_EQUAL(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pc1));
|
||||
BOOST_CHECK_EQUAL(boost::typeindex::type_id<C>(), boost::typeindex::type_id_runtime(*pc1));
|
||||
BOOST_CHECK_EQUAL(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pb1));
|
||||
BOOST_CHECK_EQUAL(boost::typeindex::type_id<B>(), boost::typeindex::type_id_runtime(*pb1));
|
||||
BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pc1));
|
||||
BOOST_TEST_EQ(boost::typeindex::type_id<C>(), boost::typeindex::type_id_runtime(*pc1));
|
||||
BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pb1));
|
||||
BOOST_TEST_EQ(boost::typeindex::type_id<B>(), boost::typeindex::type_id_runtime(*pb1));
|
||||
|
||||
BOOST_CHECK_NE(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pb1));
|
||||
BOOST_CHECK_NE(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pc1));
|
||||
BOOST_TEST_NE(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pb1));
|
||||
BOOST_TEST_NE(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pc1));
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
BOOST_CHECK_EQUAL(boost::typeindex::type_id_runtime(&rc1), boost::typeindex::type_id_runtime(pb1));
|
||||
BOOST_CHECK_EQUAL(boost::typeindex::type_id_runtime(&rb1), boost::typeindex::type_id_runtime(pc1));
|
||||
BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rc1), boost::typeindex::type_id_runtime(pb1));
|
||||
BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rb1), boost::typeindex::type_id_runtime(pc1));
|
||||
|
||||
BOOST_CHECK(boost::typeindex::type_id_runtime(rc1) == typeid(*pc1));
|
||||
BOOST_CHECK(boost::typeindex::type_id_runtime(rb1) == typeid(*pb1));
|
||||
BOOST_TEST(boost::typeindex::type_id_runtime(rc1) == typeid(*pc1));
|
||||
BOOST_TEST(boost::typeindex::type_id_runtime(rb1) == typeid(*pb1));
|
||||
|
||||
BOOST_CHECK(boost::typeindex::type_id_runtime(rc1) != typeid(*pb1));
|
||||
BOOST_CHECK(boost::typeindex::type_id_runtime(rb1) != typeid(*pc1));
|
||||
BOOST_CHECK(boost::typeindex::type_id_runtime(&rc1) == typeid(pb1));
|
||||
BOOST_CHECK(boost::typeindex::type_id_runtime(&rb1) == typeid(pc1));
|
||||
BOOST_TEST(boost::typeindex::type_id_runtime(rc1) != typeid(*pb1));
|
||||
BOOST_TEST(boost::typeindex::type_id_runtime(rb1) != typeid(*pc1));
|
||||
BOOST_TEST(boost::typeindex::type_id_runtime(&rc1) == typeid(pb1));
|
||||
BOOST_TEST(boost::typeindex::type_id_runtime(&rb1) == typeid(pc1));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -340,52 +333,51 @@ void comparators_type_id_vs_type_info()
|
||||
using namespace boost::typeindex;
|
||||
type_index t_int = type_id<int>();
|
||||
|
||||
BOOST_CHECK(t_int == typeid(int));
|
||||
BOOST_CHECK(typeid(int) == t_int);
|
||||
BOOST_CHECK(t_int <= typeid(int));
|
||||
BOOST_CHECK(typeid(int) <= t_int);
|
||||
BOOST_CHECK(t_int >= typeid(int));
|
||||
BOOST_CHECK(typeid(int) >= t_int);
|
||||
BOOST_TEST(t_int == typeid(int));
|
||||
BOOST_TEST(typeid(int) == t_int);
|
||||
BOOST_TEST(t_int <= typeid(int));
|
||||
BOOST_TEST(typeid(int) <= t_int);
|
||||
BOOST_TEST(t_int >= typeid(int));
|
||||
BOOST_TEST(typeid(int) >= t_int);
|
||||
|
||||
type_index t_double = type_id<double>();
|
||||
|
||||
BOOST_CHECK(t_double == typeid(double));
|
||||
BOOST_CHECK(typeid(double) == t_double);
|
||||
BOOST_CHECK(t_double <= typeid(double));
|
||||
BOOST_CHECK(typeid(double) <= t_double);
|
||||
BOOST_CHECK(t_double >= typeid(double));
|
||||
BOOST_CHECK(typeid(double) >= t_double);
|
||||
BOOST_TEST(t_double == typeid(double));
|
||||
BOOST_TEST(typeid(double) == t_double);
|
||||
BOOST_TEST(t_double <= typeid(double));
|
||||
BOOST_TEST(typeid(double) <= t_double);
|
||||
BOOST_TEST(t_double >= typeid(double));
|
||||
BOOST_TEST(typeid(double) >= t_double);
|
||||
|
||||
if (t_double < t_int) {
|
||||
BOOST_CHECK(t_double < typeid(int));
|
||||
BOOST_CHECK(typeid(double) < t_int);
|
||||
BOOST_CHECK(typeid(int) > t_double);
|
||||
BOOST_CHECK(t_int > typeid(double));
|
||||
BOOST_TEST(t_double < typeid(int));
|
||||
BOOST_TEST(typeid(double) < t_int);
|
||||
BOOST_TEST(typeid(int) > t_double);
|
||||
BOOST_TEST(t_int > typeid(double));
|
||||
|
||||
|
||||
BOOST_CHECK(t_double <= typeid(int));
|
||||
BOOST_CHECK(typeid(double) <= t_int);
|
||||
BOOST_CHECK(typeid(int) >= t_double);
|
||||
BOOST_CHECK(t_int >= typeid(double));
|
||||
BOOST_TEST(t_double <= typeid(int));
|
||||
BOOST_TEST(typeid(double) <= t_int);
|
||||
BOOST_TEST(typeid(int) >= t_double);
|
||||
BOOST_TEST(t_int >= typeid(double));
|
||||
} else {
|
||||
BOOST_CHECK(t_double > typeid(int));
|
||||
BOOST_CHECK(typeid(double) > t_int);
|
||||
BOOST_CHECK(typeid(int) < t_double);
|
||||
BOOST_CHECK(t_int < typeid(double));
|
||||
BOOST_TEST(t_double > typeid(int));
|
||||
BOOST_TEST(typeid(double) > t_int);
|
||||
BOOST_TEST(typeid(int) < t_double);
|
||||
BOOST_TEST(t_int < typeid(double));
|
||||
|
||||
|
||||
BOOST_CHECK(t_double >= typeid(int));
|
||||
BOOST_CHECK(typeid(double) >= t_int);
|
||||
BOOST_CHECK(typeid(int) <= t_double);
|
||||
BOOST_CHECK(t_int <= typeid(double));
|
||||
BOOST_TEST(t_double >= typeid(int));
|
||||
BOOST_TEST(typeid(double) >= t_int);
|
||||
BOOST_TEST(typeid(int) <= t_double);
|
||||
BOOST_TEST(t_int <= typeid(double));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_RTTI
|
||||
|
||||
|
||||
int test_main(int , char* []) {
|
||||
int main() {
|
||||
names_matches_type_id();
|
||||
default_construction();
|
||||
copy_construction();
|
||||
@ -402,6 +394,7 @@ int test_main(int , char* []) {
|
||||
#ifndef BOOST_NO_RTTI
|
||||
comparators_type_id_vs_type_info();
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
// 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-2013.
|
||||
// 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-2013.
|
||||
// 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