forked from boostorg/type_index
Compare commits
215 Commits
v3.0
...
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 | |||
436ecd0b3e | |||
9fcbfd18ce | |||
1916e2b42f | |||
56bd9b401a | |||
e2c227d4aa | |||
80086cbc4f | |||
0f0902d11c | |||
6857f23e6f | |||
ce103443fd | |||
b34d4d466d | |||
441a71c3d1 | |||
ae946ee496 | |||
76dc3d1053 | |||
28c77f4036 | |||
631e592b7a | |||
fa2fa1805c | |||
0744f86a2c | |||
61594ba1da | |||
e2ceb6cf36 | |||
a397391b0e | |||
8c8d9c6c69 | |||
eac9c8af2f | |||
4cc0272bd2 | |||
ecac9ac83c | |||
8a8a3ec639 | |||
6931c1de4c | |||
7ba3f29da1 | |||
a184f3969f | |||
f7388d59b5 | |||
2602569bc4 | |||
172d4a25ca | |||
6af608a827 | |||
5ed8543025 | |||
a66ffcfa50 |
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. Library is waiting for boost reiew.
|
||||
Documantation available at: http://apolukhin.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)
|
||||
|
||||
While ticket #9228 is not solved, use boost_test_no_rtti.patch to make the tests compile.
|
||||
|
||||
[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,11 +21,12 @@ 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"
|
||||
;
|
||||
|
||||
xml type_index : type_index.qbk ;
|
||||
xml type_index : type_index.qbk : <dependency>autodoc ;
|
||||
boostbook standalone
|
||||
:
|
||||
type_index
|
||||
@ -32,6 +34,14 @@ boostbook standalone
|
||||
<xsl:param>boost.root=http://www.boost.org/doc/libs/1_53_0
|
||||
# <xsl:param>boost.root=../../../..
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
|
||||
<dependency>autodoc
|
||||
;
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc
|
||||
: type_index
|
||||
:
|
||||
: <dependency>autodoc
|
||||
: ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease ;
|
||||
explicit boostrelease ;
|
||||
|
@ -1,7 +1,7 @@
|
||||
[library Boost.TypeIndex
|
||||
[quickbook 1.6]
|
||||
[version 3.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.
|
||||
@ -11,10 +11,10 @@
|
||||
]
|
||||
|
||||
[section Motivation]
|
||||
Sometimes getting and storing information about a type at runtime is required. For such cases a construction like `&typeid(T)` or C++11 class `std::type_index` is usually used. And that is the point, where problems start:
|
||||
Sometimes getting and storing information about a type at runtime is required. For such cases a construction like `&typeid(T)` or C++11 class `std::type_index` is usually used, which is where problems start:
|
||||
|
||||
* `typeid(T)` and `std::type_index` require Run Time Type Info (RTTI)
|
||||
* some implementations of `typeid(T)` strip const, volatile and references from type, while others don't
|
||||
* some implementations of `typeid(T)` erroneously do not strip const, volatile and references from type
|
||||
* some compilers have bugs and do not correctly compare `std::type_info` objects across shared libraries
|
||||
* only a few implementations of Standard Library currently provide `std::type_index`
|
||||
* no easy way to store type info without stripping const, volatile and references
|
||||
@ -25,63 +25,89 @@ Boost.TypeIndex library was designed to work around all those issues.
|
||||
|
||||
[note `T` means type here. Think of it as of `T` in `template <class T>` ]
|
||||
|
||||
[warning Version 3.0 of this library is waitning for Boost mini-review. ]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Getting started]
|
||||
|
||||
`boost::typeind::type_info` is a drop-in replacement for `std::type_info` and `boost::typeind::type_index`
|
||||
is a drop-in replacement for `std::type_index`. Unlike Standard Library versions those classes may work without RTTI.
|
||||
[classref boost::typeindex::type_info boost::typeindex::type_info] is a drop-in replacement for `std::type_info` and
|
||||
[classref boost::typeindex::type_index boost::typeindex::type_index]
|
||||
is a drop-in replacement for `std::type_index`. Unlike Standard Library versions those classes can work without RTTI.
|
||||
|
||||
`type_index` provides the full set of comparison operators, hashing functions and ostream
|
||||
operators, so it can be used with any container class.
|
||||
|
||||
Through all the examples, we'll assume that the following namespace alias is in effect:
|
||||
``namespace bti = boost::typeind;``
|
||||
|
||||
[section How to use]
|
||||
|
||||
To start using Boost.TypeIndex:
|
||||
|
||||
[table:porting
|
||||
[[Replace this:][With the following:]]
|
||||
[[Replace this:][With the following:][More Info]]
|
||||
[[``
|
||||
#include <typeinfo>
|
||||
#include <typeindex>
|
||||
``][``
|
||||
#include <boost/type_index.hpp>
|
||||
``]]
|
||||
``][
|
||||
[headerref boost/type_index.hpp more... ]
|
||||
]]
|
||||
|
||||
[[``
|
||||
std::type_index
|
||||
``][``
|
||||
bti::type_index
|
||||
``]]
|
||||
boost::typeindex::type_index
|
||||
``][
|
||||
[classref boost::typeindex::type_index more... ]
|
||||
]]
|
||||
|
||||
[[``
|
||||
typeid(T)
|
||||
typeid(please_save_modifiers<T>)
|
||||
typeid(T).name() // not human readable
|
||||
typeid(variable)
|
||||
``][``
|
||||
bti::type_id<T>()
|
||||
bti::type_id_with_cvr<T>()
|
||||
bti::type_id<T>().pretty_name() // human readable
|
||||
bti::type_id_runtime(variable)
|
||||
``]]
|
||||
boost::typeindex::type_id<T>()
|
||||
boost::typeindex::type_id<T>().pretty_name() // human readable
|
||||
boost::typeindex::type_id_runtime(variable)
|
||||
``][
|
||||
[funcref boost::typeindex::type_id more... ]
|
||||
|
||||
[classref boost::typeindex::type_index more... ]
|
||||
|
||||
[funcref boost::typeindex::type_id_runtime more... ]
|
||||
]]
|
||||
|
||||
[[``
|
||||
const std::type_info& v1 = typeid(int); // when reference to `std::type_info` is required
|
||||
const std::type_info* v2 = &typeid(int); // other cases
|
||||
// attempt to save const, volatile, reference
|
||||
typeid(please_save_modifiers<T>)
|
||||
``][``
|
||||
const bti::type_info& v1 = bti::type_id<int>().type_info();
|
||||
bti::type_index v2 = bti::type_id<int>();
|
||||
``]]
|
||||
// cvr = const, volatile, reference
|
||||
boost::typeindex::type_id_with_cvr<T>()
|
||||
``][
|
||||
[funcref boost::typeindex::type_id_with_cvr more... ]
|
||||
]]
|
||||
|
||||
[[``
|
||||
// when reference to `std::type_info` is required
|
||||
const std::type_info& v1 = typeid(int);
|
||||
|
||||
// other cases
|
||||
const std::type_info* v2 = &typeid(int);
|
||||
``][``
|
||||
const boost::typeindex::type_info& v1
|
||||
= boost::typeindex::type_id<int>().type_info();
|
||||
|
||||
boost::typeindex::type_index v2
|
||||
= boost::typeindex::type_id<int>();
|
||||
``][
|
||||
[classref boost::typeindex::type_index more... ]
|
||||
|
||||
[funcref boost::typeindex::type_id more... ]
|
||||
]]
|
||||
]
|
||||
|
||||
If you are using `type_id_runtime()` methods and RTTI is disabled, make sure that classes that are
|
||||
passed to `type_id_runtime()` are marked with `BOOST_TYPE_INDEX_REGISTER_CLASS` macro.
|
||||
If you are using [funcref boost::typeindex::type_id_runtime type_id_runtime()] methods
|
||||
and RTTI is disabled, make sure that classes that are passed to
|
||||
`type_id_runtime()` are marked with
|
||||
[macroref BOOST_TYPE_INDEX_REGISTER_CLASS BOOST_TYPE_INDEX_REGISTER_CLASS] macro.
|
||||
|
||||
[endsect]
|
||||
|
||||
@ -98,10 +124,10 @@ Here is how TypeIndex could be used in `boost/any.hpp`:
|
||||
return typeid(ValueType);
|
||||
}
|
||||
``] [``
|
||||
virtual const bti::type_info & type() const BOOST_NOEXCEPT
|
||||
virtual const boost::typeindex::type_info & type() const BOOST_NOEXCEPT
|
||||
{
|
||||
// now works even with RTTI disabled
|
||||
return bti::type_id<ValueType>().type_info();
|
||||
return boost::typeindex::type_id<ValueType>().type_info();
|
||||
}
|
||||
``]]
|
||||
]
|
||||
@ -141,14 +167,14 @@ public: // visitor interfaces
|
||||
#endif // BOOST_NO_TYPEID
|
||||
``][``
|
||||
class reflect
|
||||
: public static_visitor<const bti::type_info&>
|
||||
: public static_visitor<const boost::typeindex::type_info&>
|
||||
{
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename T>
|
||||
const bti::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
const boost::typeindex::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
{
|
||||
return bti::type_id<T>().type_info();
|
||||
return boost::typeindex::type_id<T>().type_info();
|
||||
}
|
||||
|
||||
};
|
||||
@ -162,7 +188,7 @@ public: // visitor interfaces
|
||||
}
|
||||
#endif
|
||||
``] [``
|
||||
const bti::type_info& type() const
|
||||
const boost::typeindex::type_info& type() const
|
||||
{
|
||||
detail::variant::reflect visitor;
|
||||
return this->apply_visitor(visitor);
|
||||
@ -173,16 +199,60 @@ public: // visitor interfaces
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
[section:config Configuring and building the library]
|
||||
|
||||
TypeIndex is a header only library and it does not use Boost libraries that require
|
||||
building. You just need to `#include <boost/type_index.hpp>` to start using it.
|
||||
|
||||
The library supports a number of configuration macros, defining which require full
|
||||
rebuild of all the projects that use TypeIndex:
|
||||
|
||||
[table Configuration macros
|
||||
[[Macro name] [Short description]]
|
||||
[[[macroref BOOST_TYPE_INDEX_USER_TYPEINDEX]] [ Macro that allows you to use your
|
||||
own implementation of TypeIndex instead of the default all around the projects and libraries.]]
|
||||
|
||||
[[[macroref BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY]] [ Macro that must be defined
|
||||
if you are mixing RTTI-on and RTTI-off.]]
|
||||
|
||||
[[[macroref BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING] and
|
||||
[macroref BOOST_TYPE_INDEX_FUNCTION_SIGNATURE]] [ Macros that allow you to specify
|
||||
parsing options and type name generating macro for RTTI-off cases. ]]
|
||||
]
|
||||
|
||||
You can define configuration macros in the `bjam` command line using one of the following
|
||||
approaches:
|
||||
|
||||
[pre
|
||||
b2 variant=release define=BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY stage
|
||||
]
|
||||
|
||||
[pre
|
||||
b2 variant=release "define=BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='(39, 1, true, \\"T = \\")'" stage
|
||||
]
|
||||
|
||||
However, it may be more convenient to define configuration macros in the "boost/config/user.hpp"
|
||||
file in order to automatically define them both for the library and user's projects.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section How it works]
|
||||
`type_index` is just a typedef for `stl_type_index` or `ctti_type_index`.
|
||||
`type_index` is just a typedef for [classref boost::typeindex::stl_type_index]
|
||||
or [classref boost::typeindex::ctti_type_index].
|
||||
|
||||
Depending on the `typeid()` availability TypeIndex library will choose an optimal class for
|
||||
`type_index`. In cases when at least basic support for `typeid()` is available `boost::typeind::stl_type_index`
|
||||
will be used.
|
||||
`type_index`. In cases when at least basic support for `typeid()` is available `stl_type_index` will be used.
|
||||
|
||||
`BOOST_TYPE_INDEX_REGISTER_CLASS` macro is a helper macro that places some virtual helper functions or
|
||||
[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).
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
@ -196,16 +266,28 @@ expands to nothing.
|
||||
[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 match: storing type with const, volatile and reference ] [type_index_exact_type_match_example] [endsect]
|
||||
[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 own type_index]
|
||||
[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]
|
||||
@ -237,17 +319,17 @@ Sometimes there may be a need to create your own type info system. This may be u
|
||||
|
||||
* `ctti_type_index` uses macro for getting full text representation of function name which could lead to code bloat,
|
||||
so prefer using `stl_type_index` type when possible.
|
||||
* `type_index` class hold a single pointer, so it is easy and fast to copy.
|
||||
* All the type_index classes hold a single pointer and are fast to copy.
|
||||
* Calls to `const char* raw_name()` do not require dynamic memory allocation and usually just return a pointer to an array of chars in a read-only section of the binary image.
|
||||
* Comparison operators are optimized as much as possible, and will at worst execute a single `std::strcmp`.
|
||||
* Comparison operators are optimized as much as possible and execute a single `std::strcmp` in worst case.
|
||||
* Calls to `std::string pretty_name()` usually require dynamic memory allocation and some computations, so they are not recommended for usage in performance critical sections.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Code bloat]
|
||||
|
||||
Without RTTI TypeIndex library will switch from using `boost::typeind::stl_type_index` class to
|
||||
`boost::typeind::ctti_type_index`. `boost::typeind::ctti_type_index` uses macro for getting full
|
||||
Without RTTI TypeIndex library will switch from using `boost::typeindex::stl_type_index` class to
|
||||
`boost::typeindex::ctti_type_index`. `boost::typeindex::ctti_type_index` uses macro for getting full
|
||||
text representation of function name for each type that is passed to `type_id()` and
|
||||
`type_id_with_cvr()` functions.
|
||||
|
||||
@ -265,31 +347,96 @@ i
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Compiler support]
|
||||
[section RTTI emulation limitations]
|
||||
|
||||
TypeIndex has been tested and successfully work on MSVC2010, GCC-4.6, Clang-2.9. If your compiler is not
|
||||
in a list of tested compilers, you must correctly define `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`,
|
||||
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` macroses:
|
||||
TypeIndex has been tested and successfully work on many compilers.
|
||||
|
||||
# define `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE` to a compiler specific macro, that outputs the *whole*
|
||||
function signature, including template parameters
|
||||
# define `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `0`
|
||||
# get the output of `boost::template_id<int>().name()`
|
||||
# set `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` equal to characters count before last occurrence of `int` in output
|
||||
# set `BOOST_TYPE_INDEX_CTTI_END_SKIP` equal to characters count after last occurrence of `int` in output
|
||||
# check that `boost::template_id<int>().name_demangled()` returns "int"
|
||||
# (optional, but highly recomended) [@http://www.boost.org/support/bugs.html create ticket] with
|
||||
[warning
|
||||
With RTTI off classes with exactly the same names defined in different modules in anonymous namespaces may collapse:
|
||||
```
|
||||
// In A.cpp
|
||||
namespace { struct user_defined{}; }
|
||||
type_index foo_a() { return type_id<user_defined>(); }
|
||||
|
||||
// In B.cpp
|
||||
namespace { struct user_defined{}; }
|
||||
type_index foo_b() { return type_id<user_defined>(); }
|
||||
|
||||
// In main.cpp
|
||||
assert(foo_a() != foo_b()); // will fail on some compilers
|
||||
```
|
||||
|
||||
*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]
|
||||
|
||||
If you get the following error during compilation
|
||||
``
|
||||
TypeIndex library could not detect your compiler.
|
||||
Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use
|
||||
correct compiler macro for getting the whole function name.
|
||||
Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that.
|
||||
``
|
||||
then you are using a compiler that was not tested with this library.
|
||||
|
||||
[macroref BOOST_TYPE_INDEX_FUNCTION_SIGNATURE] must be defined to a compiler specific macro, that outputs the *whole*
|
||||
function signature including template parameters.
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Fixing pretty_name() output]
|
||||
|
||||
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 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:
|
||||
|
||||
# get the output of `boost::typeindex::ctti_type_index::type_id<int>().name()`
|
||||
# define [macroref BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING] to
|
||||
`(skip_at_begin, skip_at_end, false, "")`, where
|
||||
* `skip_at_begin` is equal to characters count before the first occurrence of `int` in output
|
||||
* `skip_at_end` is equal to characters count after last occurrence of `int` in output
|
||||
# check that `boost::typeindex::ctti_type_index::type_id<int>().name_demangled()` returns "int"
|
||||
# if it does not return `int`, then define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to
|
||||
`(skip_at_begin, skip_at_end, true, "T = ")`, where
|
||||
* `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 recommended) [@http://www.boost.org/support/bugs.html create ticket] with
|
||||
feature request to add your compiler to supported compilers list. Include
|
||||
`BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`, `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and
|
||||
`BOOST_TYPE_INDEX_CTTI_END_SKIP` values.
|
||||
parameters provided to `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` macro.
|
||||
|
||||
|
||||
Consider the following example:
|
||||
|
||||
With `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` set to `0`,
|
||||
`boost::typeind::ctti_type_index::type_id<int>().raw_name()` returns
|
||||
`boost::typeindex::ctti_type_index::type_id<int>().raw_name()` returns
|
||||
"const char *__cdecl boost::detail::ctti<int>::n(void)". Then you shall set
|
||||
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` to `sizeof("const char *__cdecl boost::detail::ctti<") - 1`
|
||||
and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `sizeof(">::n(void)") - 1`.
|
||||
`skip_at_begin` to `sizeof("const char *__cdecl boost::detail::ctti<") - 1`
|
||||
and `skip_at_end` to `sizeof(">::n(void)") - 1`.
|
||||
|
||||
``
|
||||
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (39, 6, false, "")
|
||||
``
|
||||
|
||||
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 macro to "T = ".
|
||||
|
||||
``
|
||||
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (39, 1, true, "T = ")
|
||||
``
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
@ -297,9 +444,9 @@ and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `sizeof(">::n(void)") - 1`.
|
||||
|
||||
Linking a binary from source files that were compiled with different RTTI flags is not a very good
|
||||
idea and may lead to a lot of surprises. However if there is a very strong need, TypeIndex library
|
||||
provides a solution for mixing sources: just define `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY`
|
||||
macro. This would lead to usage of same type_index class (`boost::typeind::ctti_type_index` or
|
||||
`boost::typeind::stl_type_index`) all around the project.
|
||||
provides a solution for mixing sources: just define [macroref BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY]
|
||||
macro. This would lead to usage of same type_index class (`boost::typeindex::ctti_type_index` or
|
||||
`boost::typeindex::stl_type_index`) all around the project.
|
||||
|
||||
[note Do not forget to rebuild *all* the projects with `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` macro defined ]
|
||||
|
||||
@ -311,7 +458,7 @@ RTTI flags:
|
||||
|
||||
[table:diffs
|
||||
[[RTTI on] [RTTI off]]
|
||||
[[`boost::typeind::stl_type_index get_integer();`] [`boost::typeind::ctti_type_index get_integer();`]]
|
||||
[[`boost::typeindex::stl_type_index get_integer();`] [`boost::typeindex::ctti_type_index get_integer();`]]
|
||||
]
|
||||
|
||||
Such differences are usually not detected by linker and lead to errors at runtime.
|
||||
@ -331,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
|
||||
@ -14,38 +14,63 @@
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <iostream>
|
||||
namespace bti = boost::typeind;
|
||||
|
||||
template <class T>
|
||||
void foo(T) {
|
||||
std::cout << "\n Short name: " << bti::type_id<T>().raw_name();
|
||||
std::cout << "\n Readable name: " << bti::type_id<T>().pretty_name();
|
||||
std::cout << "\n Short name: " << boost::typeindex::type_id<T>().raw_name();
|
||||
std::cout << "\n Readable name: " << boost::typeindex::type_id<T>().pretty_name();
|
||||
}
|
||||
|
||||
struct user_defined_type{};
|
||||
|
||||
namespace ns1 { namespace ns2 {
|
||||
struct user_defined_type{};
|
||||
}} // namespace ns1::ns2
|
||||
|
||||
namespace {
|
||||
struct in_anon_type{};
|
||||
} // anonymous namespace
|
||||
|
||||
int main() {
|
||||
// Call to
|
||||
foo(1);
|
||||
// will output something like this:
|
||||
//
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: i Short name: int]
|
||||
// Readable name: int Readable name: int
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: i Short name: int]
|
||||
// Readable name: int Readable name: int
|
||||
|
||||
user_defined_type t;
|
||||
foo(t);
|
||||
// Will output:
|
||||
//
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: 17user_defined_type user_defined_type]
|
||||
// Readable name: user_defined_type user_defined_type
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: 17user_defined_type user_defined_type]
|
||||
// Readable name: user_defined_type user_defined_type
|
||||
|
||||
ns1::ns2::user_defined_type t_in_ns;
|
||||
foo(t_in_ns);
|
||||
// Will output:
|
||||
//
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: N3ns13ns217user_defined_typeE ns1::ns2::user_defined_type]
|
||||
// Readable name: ns1::ns2::user_defined_type ns1::ns2::user_defined_type
|
||||
|
||||
in_anon_type anon_t;
|
||||
foo(anon_t);
|
||||
// Will output:
|
||||
//
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: N12_GLOBAL__N_112in_anon_typeE {anonymous}::in_anon_type]
|
||||
// Readable name: (anonymous namespace)::in_anon_type {anonymous}::in_anon_type
|
||||
}
|
||||
|
||||
/*`
|
||||
Short names are very compiler dependant: some compiler will output `.H`, others `i`.
|
||||
|
||||
Readable names may also differ between compilers: `struct user_defined_type`, `user_defined_type`.
|
||||
|
||||
[warning With RTTI off different classes with same names in anonymous namespace may collapse. See 'RTTI emulation limitations'. ]
|
||||
*/
|
||||
|
||||
//] [/type_index_names_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
|
||||
@ -9,31 +9,47 @@
|
||||
The following example shows that `type_index` (and `type_info`) is able to store the exact type,
|
||||
without stripping const, volatile and references. Example works with and without RTTI.
|
||||
|
||||
In this example we'll create a class, that stores pointer to function and remembers the exact type of a
|
||||
parameter that function accepts. When an attempt to call the stored function will be made, type of input
|
||||
parameter will be checked for exact match with initially erased type of function.
|
||||
In this example we'll create a class that stores a pointer to function and remembers the exact type of the
|
||||
parameter the function accepts. When the call to the bound function is made, he actual input parameter
|
||||
type is checked against the stored parameter type and an exception is thrown in case of mismatch.
|
||||
*/
|
||||
|
||||
#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>
|
||||
namespace bti = boost::typeind;
|
||||
//<-
|
||||
!Closing comment block! */
|
||||
//->
|
||||
|
||||
class type_erased_unary_function {
|
||||
void* function_ptr_;
|
||||
bti::type_index exact_param_t_;
|
||||
void* function_ptr_;
|
||||
boost::typeindex::type_index exact_param_t_;
|
||||
|
||||
public:
|
||||
template <class ParamT>
|
||||
type_erased_unary_function(void(*ptr)(ParamT))
|
||||
: function_ptr_(reinterpret_cast<void*>(ptr)) // ptr - is a pointer to function returning `void` and accepting parameter of type `ParamT`
|
||||
, exact_param_t_(bti::type_id_with_cvr<ParamT>())
|
||||
, exact_param_t_(boost::typeindex::type_id_with_cvr<ParamT>())
|
||||
{}
|
||||
|
||||
template <class ParamT>
|
||||
void call(ParamT v) {
|
||||
if (exact_param_t_ != bti::type_id_with_cvr<ParamT>()) {
|
||||
if (exact_param_t_ != boost::typeindex::type_id_with_cvr<ParamT>()) {
|
||||
throw std::runtime_error("Incorrect `ParamT`");
|
||||
}
|
||||
|
||||
@ -51,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,8 +13,8 @@
|
||||
*/
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/type_index/runtime_cast/register_runtime_class.hpp>
|
||||
#include <iostream>
|
||||
namespace bti = boost::typeind;
|
||||
|
||||
struct A {
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
@ -22,9 +22,10 @@ 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 << bti::type_id_runtime(a).pretty_name() << '\n';
|
||||
std::cout << boost::typeindex::type_id_runtime(a).pretty_name() << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
@ -32,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,28 +11,45 @@
|
||||
*/
|
||||
|
||||
#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>
|
||||
namespace bti = boost::typeind;
|
||||
//<-
|
||||
!Closing comment block! */
|
||||
//->
|
||||
|
||||
int main() {
|
||||
boost::unordered_set<bti::type_index> types;
|
||||
boost::unordered_set<boost::typeindex::type_index> types;
|
||||
|
||||
// Storing some `boost::type_info`s
|
||||
types.insert(bti::type_id<int>());
|
||||
types.insert(bti::type_id<float>());
|
||||
types.insert(boost::typeindex::type_id<int>());
|
||||
types.insert(boost::typeindex::type_id<float>());
|
||||
|
||||
// `types` variable contains two `boost::type_index`es:
|
||||
assert(types.size() == 2);
|
||||
|
||||
// Const, volatile and reference will be striped from the type:
|
||||
bool is_inserted = types.insert(bti::type_id<const int>()).second;
|
||||
bool is_inserted = types.insert(boost::typeindex::type_id<const int>()).second;
|
||||
assert(!is_inserted);
|
||||
assert(types.erase(bti::type_id<float&>()) == 1);
|
||||
assert(types.erase(boost::typeindex::type_id<float&>()) == 1);
|
||||
|
||||
// We have erased the `float` type, only `int` remains
|
||||
assert(*types.begin() == bti::type_id<int>());
|
||||
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]
|
90
examples/table_of_names.cpp
Normal file
90
examples/table_of_names.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
// 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>.)
|
||||
|
||||
|
||||
//[type_index_names_table
|
||||
/*`
|
||||
The following example shows how different type names look when we explicitly use classes for RTTI and RTT off.
|
||||
|
||||
This example requires RTTI. For a more portable example see 'Getting human readable and mangled type names':
|
||||
*/
|
||||
|
||||
|
||||
#include <boost/type_index/stl_type_index.hpp>
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
void print(const char* name) {
|
||||
boost::typeindex::stl_type_index sti = boost::typeindex::stl_type_index::type_id<T>();
|
||||
boost::typeindex::ctti_type_index cti = boost::typeindex::ctti_type_index::type_id<T>();
|
||||
std::cout << "\t[" /* start of the row */
|
||||
<< "[" << name << "]"
|
||||
<< "[`" << sti.raw_name() << "`] "
|
||||
<< "[`" << sti.pretty_name() << "`] "
|
||||
<< "[`" << cti.raw_name() << "`] "
|
||||
<< "]\n" /* end of the row */ ;
|
||||
}
|
||||
|
||||
struct user_defined_type{};
|
||||
|
||||
namespace ns1 { namespace ns2 {
|
||||
struct user_defined_type{};
|
||||
}} // namespace ns1::ns2
|
||||
|
||||
namespace {
|
||||
struct in_anon_type{};
|
||||
} // anonymous namespace
|
||||
|
||||
namespace ns3 { namespace { namespace ns4 {
|
||||
struct in_anon_type{};
|
||||
}}} // namespace ns3::{anonymous}::ns4
|
||||
|
||||
|
||||
template <class T0, class T1>
|
||||
class templ {};
|
||||
|
||||
template <>
|
||||
class templ<int, int> {};
|
||||
|
||||
int main() {
|
||||
std::cout << "[table:id Table of names\n";
|
||||
std::cout << "\t[[Type] [RTTI & raw_name] [RTTI & pretty_name] [noRTTI & raw_name]]\n";
|
||||
|
||||
print<user_defined_type>("User defined type");
|
||||
print<in_anon_type>("In anonymous namespace");
|
||||
print<ns3::ns4::in_anon_type>("In ns3::{anonymous}::ns4 namespace");
|
||||
print<templ<short, int> >("Template class");
|
||||
print<templ<int, int> >("Template class (full specialization)");
|
||||
print<templ<
|
||||
templ<char, signed char>,
|
||||
templ<int, user_defined_type>
|
||||
> >("Template class with templae classes");
|
||||
|
||||
|
||||
std::cout << "]\n";
|
||||
}
|
||||
|
||||
/*`
|
||||
Code from the example will produce the following table:
|
||||
|
||||
[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 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 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'. ]
|
||||
*/
|
||||
|
||||
//] [/type_index_names_table]
|
@ -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
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
//[type_index_my_type_index_worldwide_macro
|
||||
/*`
|
||||
There is an easy way to force `boost::typeind::type_id` to use your own type_index class.
|
||||
There is an easy way to force `boost::typeindex::type_id` to use your own type_index class.
|
||||
|
||||
All we need to do is just define `BOOST_TYPE_INDEX_USER_TYPEINDEX` to the full path to header file
|
||||
of your type index class:
|
||||
@ -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
|
||||
@ -56,10 +61,13 @@ int main() {
|
||||
/*`
|
||||
That's it! Now all TypeIndex global methods and typedefs will be using your class:
|
||||
*/
|
||||
boost::typeind::type_index worldwide = boost::typeind::type_id<my_classes>();
|
||||
boost::typeindex::type_index worldwide = boost::typeindex::type_id<my_classes>();
|
||||
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,12 +79,20 @@ 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 {
|
||||
|
||||
class my_type_index: public boost::typeind::type_index_facade<my_type_index, detail::my_typeinfo> {
|
||||
class my_type_index: public boost::typeindex::type_index_facade<my_type_index, detail::my_typeinfo> {
|
||||
const detail::my_typeinfo* data_;
|
||||
|
||||
public:
|
||||
@ -118,7 +135,7 @@ public:
|
||||
} // namespace my_namespace
|
||||
|
||||
/*`
|
||||
Note that we have used the boost::typeind::type_index_facade class as base.
|
||||
Note that we have used the boost::typeindex::type_index_facade class as base.
|
||||
That class took care about all the helper function and operators (comparison, hashing, ostreaming and others).
|
||||
*/
|
||||
|
||||
@ -186,7 +203,7 @@ struct my_struct: public my_class {
|
||||
You'll also need to add some typedefs and macro to your "user_defined_typeinfo.hpp" header file:
|
||||
*/
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CLASS MY_TYPEINDEX_REGISTER_CLASS
|
||||
namespace boost { namespace typeind {
|
||||
namespace boost { namespace typeindex {
|
||||
typedef my_namespace::my_type_index type_index;
|
||||
}}
|
||||
//] [/type_index_my_type_index_worldwide_typedefs]
|
||||
|
@ -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)
|
||||
@ -12,54 +12,132 @@
|
||||
/// \brief Includes minimal set of headers required to use the Boost.TypeIndex library.
|
||||
///
|
||||
/// By inclusion of this file most optimal type index classes will be included and used
|
||||
/// as a boost::typeind::type_index and boost::typeind::type_info.
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
/// as a boost::typeindex::type_index and boost::typeindex::type_info.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#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
|
||||
# include <boost/type_index/stl_register_class.hpp>
|
||||
# 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/ctti_register_class.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
|
||||
|
||||
namespace boost { namespace typeind {
|
||||
#ifndef BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE
|
||||
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::typeindex::ctti_type_index class to
|
||||
/// deduce the name of a type. If your compiler is not recognized
|
||||
/// by the TypeIndex library and you wish to work with boost::typeindex::ctti_type_index, you may
|
||||
/// define this macro by yourself.
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro
|
||||
/// that outputs the \b whole function signature \b including \b template \b parameters.
|
||||
///
|
||||
/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined,
|
||||
/// then a compile-time error will arise at any attempt to use boost::typeindex::ctti_type_index classes.
|
||||
///
|
||||
/// See BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS and BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
|
||||
/// for an information of how to tune the implementation to make a nice pretty_name() output.
|
||||
#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
|
||||
/// This is a helper macro for making correct pretty_names() with RTTI off.
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING macro may be defined to
|
||||
/// '(begin_skip, end_skip, runtime_skip, runtime_skip_until)' with parameters for adding a
|
||||
/// support for compilers, that by default are not recognized by TypeIndex library.
|
||||
///
|
||||
/// \b Example:
|
||||
///
|
||||
/// Imagine the situation when
|
||||
/// \code boost::typeindex::ctti_type_index::type_id<int>().pretty_name() \endcode
|
||||
/// returns the following string:
|
||||
/// \code "static const char *boost::detail::ctti<int>::n() [T = int]" \endcode
|
||||
/// and \code boost::typeindex::ctti_type_index::type_id<short>().pretty_name() \endcode returns the following:
|
||||
/// \code "static const char *boost::detail::ctti<short>::n() [T = short]" \endcode
|
||||
///
|
||||
/// As we may see first 39 characters are "static const char *boost::detail::ctti<" and they do not depend on
|
||||
/// the type T. After first 39 characters we have a human readable type name which is duplicated at the end
|
||||
/// of a string. String always ends on ']', which consumes 1 character.
|
||||
///
|
||||
/// Now if we define `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` to
|
||||
/// `(39, 1, false, "")` we'll be getting \code "int>::n() [T = int" \endcode
|
||||
/// for `boost::typeindex::ctti_type_index::type_id<int>().pretty_name()` and \code "short>::n() [T = short" \endcode
|
||||
/// for `boost::typeindex::ctti_type_index::type_id<short>().pretty_name()`.
|
||||
///
|
||||
/// Now we need to take additional care of the characters that go before the last mention of our type. We'll
|
||||
/// do that by telling the macro that we need to cut off everything that goes before the "T = " including the "T = "
|
||||
/// itself:
|
||||
///
|
||||
/// \code (39, 1, true, "T = ") \endcode
|
||||
///
|
||||
/// In case of GCC or Clang command line we need to add the following line while compiling all the sources:
|
||||
///
|
||||
/// \code
|
||||
/// -DBOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='(39, 1, true, "T = ")'
|
||||
/// \endcode
|
||||
/// \param begin_skip How many characters must be skipped at the beginning of the type holding string.
|
||||
/// Must be a compile time constant.
|
||||
/// \param end_skip How many characters must be skipped at the end of the type holding string.
|
||||
/// Must be a compile time constant.
|
||||
/// \param runtime_skip Do we need additional checks at runtime to cut off the more characters.
|
||||
/// Must be `true` or `false`.
|
||||
/// \param runtime_skip_until Skip all the characters before the following string (including the string itself).
|
||||
/// Must be a compile time array of characters.
|
||||
///
|
||||
/// See [RTTI emulation limitations](boost_typeindex/rtti_emulation_limitations.html) for more info.
|
||||
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (0, 0, false, "")
|
||||
|
||||
|
||||
/// Depending on a compiler flags, optimal implementation of type_index will be used
|
||||
/// as a default boost::typeind::type_index.
|
||||
/// as a default boost::typeindex::type_index.
|
||||
///
|
||||
/// Could be a boost::typeind::stl_type_index, boost::typeind::ctti_type_index or
|
||||
/// Could be a boost::typeindex::stl_type_index, boost::typeindex::ctti_type_index or
|
||||
/// user defined type_index class.
|
||||
typedef platform-specific type_index;
|
||||
///
|
||||
/// \b See boost::typeindex::type_index_facade for a full description of type_index functions.
|
||||
typedef platform_specific type_index;
|
||||
#elif defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
|
||||
// Nothing to do
|
||||
#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
|
||||
typedef boost::typeind::stl_type_index type_index;
|
||||
# ifdef BOOST_NO_RTTI
|
||||
# define BOOST_TYPE_INDEX_REGISTER_CLASS BOOST_TYPE_INDEX_REGISTER_STL_CLASS
|
||||
# else
|
||||
# define BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
# endif
|
||||
typedef boost::typeindex::stl_type_index type_index;
|
||||
#else
|
||||
typedef boost::typeind::ctti_type_index type_index;
|
||||
# define BOOST_TYPE_INDEX_REGISTER_CLASS BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS
|
||||
typedef boost::typeindex::ctti_type_index type_index;
|
||||
#endif
|
||||
|
||||
/// Depending on a compiler flags, optimal implementation of type_info will be used
|
||||
/// as a default boost::typeind::type_info.
|
||||
/// as a default boost::typeindex::type_info.
|
||||
///
|
||||
/// Could be a std::type_info, boost::typeind::detail::ctti_data or
|
||||
/// Could be a std::type_info, boost::typeindex::detail::ctti_data or
|
||||
/// some user defined class.
|
||||
///
|
||||
/// type_info \b is \b not copyable or default constructible. It is \b not assignable too!
|
||||
@ -71,16 +149,17 @@ typedef type_index::type_info_t type_info;
|
||||
/// BOOST_TYPE_INDEX_USER_TYPEINDEX can be defined to the path to header file
|
||||
/// with user provided implementation of type_index.
|
||||
///
|
||||
/// See "Making own type_index" section of documentation for usage example.
|
||||
/// See [Making a custom type_index](boost_typeindex/making_a_custom_type_index.html) section
|
||||
/// of documentation for usage example.
|
||||
#define BOOST_TYPE_INDEX_USER_TYPEINDEX <full/absolute/path/to/header/with/type_index.hpp>
|
||||
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
/// \def BOOST_TYPE_INDEX_REGISTER_CLASSis used to help to emulate RTTI.
|
||||
/// BOOST_TYPE_INDEX_REGISTER_CLASS is used to help to emulate RTTI.
|
||||
/// Put this macro into the public section of polymorphic class to allow runtime type detection.
|
||||
///
|
||||
/// Depending on the typeid() availability this macro will expand to nothing or to virtual helper function
|
||||
/// `virtual const type_info& type_id_runtime() const`.
|
||||
/// `virtual const type_info& boost_type_info_type_id_runtime_() const noexcept`.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
@ -102,20 +181,21 @@ typedef type_index::type_info_t type_info;
|
||||
///
|
||||
/// C c1;
|
||||
/// A* pc1 = &c1;
|
||||
/// assert(boost::typeind::type_id<C>() == boost::typeind::type_id_runtime(*pc1));
|
||||
/// assert(boost::typeindex::type_id<C>() == boost::typeindex::type_id_runtime(*pc1));
|
||||
/// \endcode
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CLASS nothing-or-some-virtual-functions
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
|
||||
/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY is a helper macro that must be defined if mixing
|
||||
/// RTTI on/off modules. See "Mixing sources with RTTI on and RTTI off" section of documentation
|
||||
/// for more info.
|
||||
/// RTTI on/off modules. See
|
||||
/// [Mixing sources with RTTI on and RTTI off](boost_typeindex/mixing_sources_with_rtti_on_and_.html)
|
||||
/// section of documentation for more info.
|
||||
#define BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
|
||||
|
||||
#endif // defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
||||
|
||||
/// Function to get boost::type_index for a type T.
|
||||
/// Function to get boost::typeindex::type_index for a type T.
|
||||
/// Removes const, volatile && and & modifiers from T.
|
||||
///
|
||||
/// \b Example:
|
||||
@ -126,13 +206,13 @@ typedef type_index::type_info_t type_info;
|
||||
///
|
||||
/// \tparam T Type for which type_index must be created.
|
||||
/// \throw Nothing.
|
||||
/// \return boost::typeind::type_index with information about the specified type T.
|
||||
/// \return boost::typeindex::type_index with information about the specified type T.
|
||||
template <class T>
|
||||
inline type_index type_id() BOOST_NOEXCEPT {
|
||||
return type_index::type_id<T>();
|
||||
}
|
||||
|
||||
/// Function for constructing boost::type_index instance for type T.
|
||||
/// Function for constructing boost::typeindex::type_index instance for type T.
|
||||
/// Does not remove const, volatile, & and && modifiers from T.
|
||||
///
|
||||
/// If T has no const, volatile, & and && modifiers, then returns exactly
|
||||
@ -146,7 +226,7 @@ inline type_index type_id() BOOST_NOEXCEPT {
|
||||
///
|
||||
/// \tparam T Type for which type_index must be created.
|
||||
/// \throw Nothing.
|
||||
/// \return boost::typeind::type_index with information about the specified type T.
|
||||
/// \return boost::typeindex::type_index with information about the specified type T.
|
||||
template <class T>
|
||||
inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
return type_index::type_id_with_cvr<T>();
|
||||
@ -154,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.
|
||||
///
|
||||
@ -169,15 +249,15 @@ 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::typeind::type_index with information about the specified variable.
|
||||
/// \return boost::typeindex::type_index with information about the specified variable.
|
||||
template <class T>
|
||||
inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT {
|
||||
return type_index::type_id_runtime(runtime_val);
|
||||
}
|
||||
|
||||
}} // namespace boost::typeind
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
|
||||
|
||||
|
@ -1,44 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2013-2014.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
|
||||
#define BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/// \file ctti_register_class.hpp
|
||||
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS macro.
|
||||
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
|
||||
namespace boost { namespace typeind { namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline const ctti_data& ctti_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
|
||||
return ctti_construct<T>();
|
||||
}
|
||||
|
||||
}}} // namespace boost::typeind::detail
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS
|
||||
/// BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS is used by BOOST_TYPE_INDEX_REGISTER_CLASS when RTTI is off
|
||||
/// and `typeid()` does not work.
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS macro expands to declaration and implementation of
|
||||
/// `virtual const detail::ctti_data& type_id_runtime() const` method.
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS \
|
||||
virtual const boost::typeind::detail::ctti_data& type_id_runtime() const BOOST_NOEXCEPT { \
|
||||
return boost::typeind::detail::ctti_construct_typeid_ref(this); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_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
|
||||
@ -9,15 +9,10 @@
|
||||
#ifndef BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
|
||||
#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/// \file ctti_type_index.hpp
|
||||
/// \brief Contains boost::typeind::ctti_type_index class.
|
||||
/// \brief Contains boost::typeindex::ctti_type_index class that is constexpr if C++14 constexpr is supported by compiler.
|
||||
///
|
||||
/// boost::typeind::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
|
||||
@ -27,40 +22,66 @@
|
||||
#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>
|
||||
|
||||
namespace boost { namespace typeind {
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
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 a standard-layout class with private constructors and assignment operators.
|
||||
// Solution would be the following:
|
||||
|
||||
/// \class ctti_data
|
||||
/// Standard-layout class with private constructors and assignment operators.
|
||||
///
|
||||
/// You can not work with this class directly. The purpose of this class is to hold type info
|
||||
/// \b when \b RTTI \b is \b off and allow ctti_type_index construction from itself.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
/// const detail::ctti_data& foo();
|
||||
/// ...
|
||||
/// type_index ti = type_index(foo());
|
||||
/// std::cout << ti.pretty_name();
|
||||
/// \endcode
|
||||
class ctti_data {
|
||||
#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
|
||||
public:
|
||||
ctti_data() = delete;
|
||||
ctti_data(const ctti_data&) = delete;
|
||||
ctti_data& operator=(const ctti_data&) = delete;
|
||||
#else
|
||||
private:
|
||||
ctti_data();
|
||||
ctti_data(const ctti_data&);
|
||||
ctti_data& operator=(const ctti_data&);
|
||||
#endif
|
||||
};
|
||||
|
||||
} // 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.
|
||||
//
|
||||
@ -69,35 +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
|
||||
/// not require RTTI support. For description of functions see type_index_facade.
|
||||
/// 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;
|
||||
@ -105,49 +143,71 @@ 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());
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
inline ctti_type_index ctti_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
|
||||
return variable.type_id_runtime();
|
||||
return variable.boost_type_index_type_id_runtime_();
|
||||
}
|
||||
|
||||
|
||||
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 {
|
||||
return std::strlen(raw_name() + detail::ctti_skip_size_at_end);
|
||||
}
|
||||
|
||||
|
||||
inline std::string ctti_type_index::pretty_name() const {
|
||||
std::size_t len = std::strlen(raw_name() + detail::ctti_skip_size_at_end);
|
||||
std::size_t len = get_raw_name_length();
|
||||
while (raw_name()[len - 1] == ' ') --len; // MSVC sometimes adds whitespaces
|
||||
return std::string(raw_name(), len);
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t ctti_type_index::hash_code() const BOOST_NOEXCEPT {
|
||||
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name() + detail::ctti_skip_size_at_end));
|
||||
return boost::hash_range(raw_name(), raw_name() + get_raw_name_length());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::typeind
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_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
|
||||
@ -9,131 +9,331 @@
|
||||
#ifndef BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
|
||||
#define BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
/// \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.
|
||||
|
||||
#include <cstring>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
/// \file compile_time_type_info.hpp
|
||||
/// \brief Contains implementation of boost::ctti class.
|
||||
///
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost { namespace typeind { namespace detail {
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE
|
||||
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::template_info class to
|
||||
/// deduce the name of a template parameter. If your compiler is not recognized
|
||||
/// by the TypeIndex library and you wish to work with boost::template_info, you may
|
||||
/// define this macro by yourself.
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro,
|
||||
/// that outputs the WHOLE function signature, including template parameters.
|
||||
///
|
||||
/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined,
|
||||
/// then a compile-time error will arise at any attempt to use boost::template_info or
|
||||
/// boost::template_index classes.
|
||||
#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE, BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
|
||||
/// and BOOST_TYPE_INDEX_CTTI_END_SKIP macroses are used for adding a
|
||||
/// support for compilers, that by default are not recognized by TypeIndex library.
|
||||
///
|
||||
/// See Compiler support for more info
|
||||
#define BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP 0
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_CTTI_END_SKIP
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE, BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
|
||||
/// and BOOST_TYPE_INDEX_CTTI_END_SKIP macroses are used for adding a
|
||||
/// support for compilers, that by default are not recognized by TypeIndex library.
|
||||
///
|
||||
/// See Compiler support for more info
|
||||
#define BOOST_TYPE_INDEX_CTTI_END_SKIP 0
|
||||
|
||||
#elif defined(BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP) && defined(BOOST_TYPE_INDEX_CTTI_END_SKIP)
|
||||
// skip user specified bytes count
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP);
|
||||
// skip user specified bytes count
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = BOOST_TYPE_INDEX_CTTI_END_SKIP);
|
||||
#elif defined _MSC_VER
|
||||
// sizeof("const char *__cdecl boost::detail::ctti<") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 40);
|
||||
|
||||
// sizeof(">::n(void)") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 10);
|
||||
|
||||
#elif defined __clang__
|
||||
// sizeof("static const char *boost::detail::ctti<") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 39);
|
||||
|
||||
// == sizeof(">::n()") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 6);
|
||||
#elif defined __GNUC__
|
||||
// sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 57);
|
||||
|
||||
// == sizeof("]") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 1);
|
||||
|
||||
#else
|
||||
// TODO: Code for other platforms
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 0); // skip nothing
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 0); // skip nothing
|
||||
/// @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
|
||||
|
||||
}}} // namespace boost::typeind::detail
|
||||
#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; \
|
||||
BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_end = end_skip; \
|
||||
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) && !defined(__clang__) && defined (BOOST_NO_CXX11_NOEXCEPT)
|
||||
// sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "")
|
||||
#elif defined(_MSC_VER) && !defined(__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 = ")
|
||||
#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__ >= 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(__EDG__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static cha boost::detail::ctti<T>::s() [with I = 40U, T = ") - 1, sizeof("]") - 1
|
||||
// note: checked on 4.14
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(58, 1, false, "")
|
||||
#elif defined(__EDG__) && defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static const char *boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
|
||||
// note: checked on 4.14
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
|
||||
#elif defined(__GNUC__) && (__GNUC__ < 7) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static constexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0u; T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(81, 1, false, "")
|
||||
#elif defined(__GNUC__) && (__GNUC__ >= 7) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static constexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0; T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(80, 1, false, "")
|
||||
#elif defined(__GNUC__) && defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
// sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
|
||||
#elif defined(__ghs__)
|
||||
// sizeof("static const char *boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
|
||||
#else
|
||||
// Deafult code for other platforms... Just skip nothing!
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "")
|
||||
#endif
|
||||
|
||||
#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
template <bool Condition>
|
||||
BOOST_CXX14_CONSTEXPR inline void assert_compile_time_legths() BOOST_NOEXCEPT {
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
Condition,
|
||||
"TypeIndex library is misconfigured for your compiler. "
|
||||
"Please define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct values. See section "
|
||||
"'RTTI emulation limitations' of the documentation for more information."
|
||||
);
|
||||
}
|
||||
|
||||
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. "
|
||||
"Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use "
|
||||
"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 posible, to avoid code bloat
|
||||
/// This name must be as short as possible, to avoid code bloat
|
||||
template <class T>
|
||||
struct ctti {
|
||||
typedef T template_type;
|
||||
typedef ctti this_type;
|
||||
|
||||
/// 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_TYPE_INDEX_FUNCTION_SIGNATURE + boost::typeind::detail::ctti_skip_size_at_begin;
|
||||
#elif defined(__FUNCSIG__)
|
||||
return __FUNCSIG__ + boost::typeind::detail::ctti_skip_size_at_begin;
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
#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
|
||||
|
||||
return __PRETTY_FUNCTION__ + boost::typeind::detail::ctti_skip_size_at_begin;
|
||||
#else
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
sizeof(T) && false,
|
||||
"TypeIndex library could not detect your compiler. "
|
||||
"Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use "
|
||||
"correct compiler macro for getting the whole function name. "
|
||||
"Do not forget to also define BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP and "
|
||||
"BOOST_TYPE_INDEX_CTTI_END_SKIP."
|
||||
);
|
||||
#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");
|
||||
|
||||
/// Returns raw name
|
||||
static const char* name() BOOST_NOEXCEPT {
|
||||
return this_type::n();
|
||||
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
|
||||
|
||||
|
40
include/boost/type_index/detail/ctti_register_class.hpp
Normal file
40
include/boost/type_index/detail/ctti_register_class.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright 2013-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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
|
||||
#define BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
|
||||
|
||||
/// \file ctti_register_class.hpp
|
||||
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CLASS macro implementation that uses boost::typeindex::ctti_type_index.
|
||||
/// Not intended for inclusion from user's code.
|
||||
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline const ctti_data& ctti_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
|
||||
return ctti_construct<T>();
|
||||
}
|
||||
|
||||
}}} // namespace boost::typeindex::detail
|
||||
|
||||
/// @cond
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CLASS \
|
||||
virtual const boost::typeindex::detail::ctti_data& boost_type_index_type_id_runtime_() const BOOST_NOEXCEPT { \
|
||||
return boost::typeindex::detail::ctti_construct_typeid_ref(this); \
|
||||
} \
|
||||
/**/
|
||||
/// @endcond
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
|
||||
|
40
include/boost/type_index/detail/stl_register_class.hpp
Normal file
40
include/boost/type_index/detail/stl_register_class.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright 2013-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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
|
||||
#define BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
|
||||
|
||||
/// \file stl_register_class.hpp
|
||||
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CLASS macro implementation that uses boost::typeindex::stl_type_index.
|
||||
/// Not intended for inclusion from user's code.
|
||||
|
||||
#include <boost/type_index/stl_type_index.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline const stl_type_index::type_info_t& stl_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
|
||||
return typeid(T);
|
||||
}
|
||||
|
||||
}}} // namespace boost::typeindex::detail
|
||||
|
||||
/// @cond
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CLASS \
|
||||
virtual const boost::typeindex::stl_type_index::type_info_t& boost_type_index_type_id_runtime_() const BOOST_NOEXCEPT { \
|
||||
return boost::typeindex::detail::stl_construct_typeid_ref(this); \
|
||||
} \
|
||||
/**/
|
||||
/// @endcond
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
|
||||
|
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,45 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2013-2014.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
|
||||
#define BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/// \file stl_register_class.hpp
|
||||
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_STL_CLASS macro.
|
||||
|
||||
#include <boost/type_index/stl_type_index.hpp>
|
||||
|
||||
namespace boost { namespace typeind { namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline const stl_type_index::type_info_t& stl_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
|
||||
return typeid(T);
|
||||
}
|
||||
|
||||
}}} // namespace boost::typeind::detail
|
||||
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_REGISTER_STL_CLASS
|
||||
/// BOOST_TYPE_INDEX_REGISTER_STL_CLASS is used by BOOST_TYPE_INDEX_REGISTER_CLASS when RTTI is off
|
||||
/// and `typeid()` does work.
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_REGISTER_STL_CLASS macro expands to declaration and implementation of
|
||||
/// `virtual const std::type_info& type_id_runtime() const` method.
|
||||
#define BOOST_TYPE_INDEX_REGISTER_STL_CLASS \
|
||||
virtual const boost::typeind::stl_type_index::type_info_t& type_id_runtime() const BOOST_NOEXCEPT { \
|
||||
return boost::typeind::detail::stl_construct_typeid_ref(this); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_STL_REGISTER_CLASS_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
|
||||
@ -9,60 +9,60 @@
|
||||
#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
|
||||
#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/// \file stl_type_index.hpp
|
||||
/// \brief Contains boost::typeind::stl_type_index class.
|
||||
/// \brief Contains boost::typeindex::stl_type_index class.
|
||||
///
|
||||
/// boost::typeind::stl_type_index class can be used as a drop-in replacement
|
||||
/// boost::typeindex::stl_type_index class can be used as a drop-in replacement
|
||||
/// for std::type_index.
|
||||
///
|
||||
/// It is used in situations when RTTI is enabled or typeid() method is available.
|
||||
/// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro
|
||||
/// is defined boost::typeind::ctti is usually used instead of boost::typeind::stl_type_index.
|
||||
/// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index.
|
||||
|
||||
#include <boost/type_index/type_index_facade.hpp>
|
||||
|
||||
|
||||
// MSVC is capable of calling typeid(T) even when RTTI is off
|
||||
#if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC)
|
||||
#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available."
|
||||
#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/functional/hash_fwd.hpp>
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
# include <cxxabi.h> // abi::__cxa_demangle
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MSVC)
|
||||
# include <boost/assert.hpp>
|
||||
# include <boost/detail/no_exceptions_support.hpp>
|
||||
#if (defined(_MSC_VER) && _MSC_VER > 1600) \
|
||||
|| (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) \
|
||||
|| (defined(__GNUC__) && __GNUC__ > 4 && __cplusplus >= 201103)
|
||||
# define BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
|
||||
#else
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
# include <boost/type_traits/is_arithmetic.hpp>
|
||||
# include <boost/type_traits/is_signed.hpp>
|
||||
# include <boost/type_traits/make_signed.hpp>
|
||||
# include <boost/type_traits/type_identity.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeind {
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \class stl_type_index
|
||||
/// This class is a wrapper around std::type_info, that workarounds issues and provides
|
||||
/// much more rich interface. For description of functions see type_index_facade.
|
||||
/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
|
||||
///
|
||||
/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index.
|
||||
class stl_type_index
|
||||
@ -132,49 +132,60 @@ inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
|
||||
}
|
||||
|
||||
inline std::string stl_type_index::pretty_name() const {
|
||||
#if defined(_MSC_VER)
|
||||
std::string ret = data_->name();
|
||||
#else
|
||||
std::string ret;
|
||||
int status = 0;
|
||||
char* demang = abi::__cxa_demangle(raw_name(), NULL, 0, &status);
|
||||
BOOST_ASSERT(!status);
|
||||
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;
|
||||
|
||||
BOOST_TRY {
|
||||
ret = demang; // may throw out of memory exception
|
||||
} BOOST_CATCH (...) {
|
||||
free(demang);
|
||||
BOOST_RETHROW;
|
||||
} BOOST_CATCH_END
|
||||
// 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());
|
||||
|
||||
free(demang);
|
||||
#endif
|
||||
|
||||
std::string::size_type pos = ret.find("boost::typeind::detail::cvr_saver<");
|
||||
if (pos == std::string::npos) {
|
||||
return ret;
|
||||
const char* begin = demangled_name.get();
|
||||
if (!begin) {
|
||||
boost::throw_exception(std::runtime_error("Type name demangling failed"));
|
||||
}
|
||||
|
||||
pos += sizeof("boost::typeind::detail::cvr_saver<") - 1;
|
||||
while (ret[pos] == ' ') {
|
||||
++ pos;
|
||||
const std::string::size_type len = std::strlen(begin);
|
||||
const char* end = begin + len;
|
||||
|
||||
if (len > cvr_saver_name_len) {
|
||||
const char* b = std::strstr(begin, cvr_saver_name);
|
||||
if (b) {
|
||||
b += cvr_saver_name_len;
|
||||
|
||||
// Trim leading spaces
|
||||
while (*b == ' ') { // the string is zero terminated, we won't exceed the buffer size
|
||||
++ b;
|
||||
}
|
||||
|
||||
// Skip the closing angle bracket
|
||||
const char* e = end - 1;
|
||||
while (e > b && *e != '>') {
|
||||
-- e;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string::size_type end = ret.rfind(">");
|
||||
while (ret[end - 1] == ' ') {
|
||||
-- end;
|
||||
}
|
||||
|
||||
return ret.substr(pos, end - pos);
|
||||
return std::string(begin, end);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -187,42 +198,49 @@ 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>
|
||||
inline stl_type_index stl_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;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_prefinal_t;
|
||||
|
||||
# if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
BOOST_STATIC_ASSERT_MSG( !boost::is_arithmetic<no_cvr_t>::type::value
|
||||
, "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions.");
|
||||
|
||||
// Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
|
||||
// in typeid() expressions. Full template specialization for 'integral' fixes that issue:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
|
||||
boost::is_signed<no_cvr_prefinal_t>::value,
|
||||
boost::make_signed<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;
|
||||
#else
|
||||
typedef no_cvr_prefinal_t no_cvr_t;
|
||||
#endif
|
||||
|
||||
return typeid(no_cvr_t);
|
||||
@ -234,10 +252,8 @@ namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
typedef typename boost::mpl::if_c<
|
||||
boost::is_reference<T>::value
|
||||
|| boost::is_const<T>::value
|
||||
|| boost::is_volatile<T>::value,
|
||||
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;
|
||||
@ -248,15 +264,15 @@ 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
|
||||
return value.type_id_runtime();
|
||||
#ifdef BOOST_NO_RTTI
|
||||
return value.boost_type_index_type_id_runtime_();
|
||||
#else
|
||||
return typeid(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
}} // namespace boost::typeind
|
||||
}} // 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
|
||||
@ -9,13 +9,8 @@
|
||||
#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
@ -27,7 +22,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeind {
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \class type_index_facade
|
||||
///
|
||||
@ -54,63 +53,71 @@ namespace boost { namespace typeind {
|
||||
///
|
||||
/// \tparam Derived Class derived from type_index_facade.
|
||||
/// \tparam TypeInfo Class that will be used as a base type_info class.
|
||||
/// \note Take a look at the protected methods. They are \b not \b defined in type_index_facade.
|
||||
/// Protected member functions raw_name() \b must be defined in Derived class. All the other
|
||||
/// methods are mandatory.
|
||||
/// \see 'Making a custom type_index' section for more information about
|
||||
/// creating your own type_index using type_index_facade.
|
||||
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
|
||||
public:
|
||||
typedef TypeInfo type_info_t;
|
||||
|
||||
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Const reference to underlying low level type_info_t.
|
||||
inline const type_info_t& type_info() const BOOST_NOEXCEPT {
|
||||
return derived().type_info();
|
||||
}
|
||||
|
||||
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Pointer to unredable/raw type name.
|
||||
inline const char* raw_name() const BOOST_NOEXCEPT {
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \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 must be redefined in Derived class. Overrides may throw.
|
||||
/// \return Human redable type name.
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides may throw.
|
||||
/// \return Human readable type name. By default returns Derived::name().
|
||||
inline std::string pretty_name() const {
|
||||
return derived().pretty_name();
|
||||
}
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Name of a type. By default retuns raw_name().
|
||||
inline const char* name() const BOOST_NOEXCEPT {
|
||||
return raw_name();
|
||||
return derived().name();
|
||||
}
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return True if two types are equal. By default compares types by raw_name().
|
||||
inline bool equal(const Derived& rhs) const BOOST_NOEXCEPT {
|
||||
return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
|
||||
const char* const left = derived().raw_name();
|
||||
const char* const right = rhs.raw_name();
|
||||
return left == right || !std::strcmp(left, right);
|
||||
}
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return True if rhs is greater than this. By default compares types by raw_name().
|
||||
inline bool before(const Derived& rhs) const BOOST_NOEXCEPT {
|
||||
return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
|
||||
const char* const left = derived().raw_name();
|
||||
const char* const right = rhs.raw_name();
|
||||
return left != right && std::strcmp(left, right) < 0;
|
||||
}
|
||||
|
||||
/// \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 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 {
|
||||
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_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)
|
||||
protected:
|
||||
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Pointer to unredable/raw type name.
|
||||
inline const char* raw_name() const BOOST_NOEXCEPT;
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Const reference to underlying low level type_info_t.
|
||||
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
|
||||
|
||||
/// This is a factory method that is used to create instances of Derived classes.
|
||||
/// boost::typeind::type_id() will call this method, if Derived has same type as boost::typeind::type_index.
|
||||
/// boost::typeindex::type_id() will call this method, if Derived has same type as boost::typeindex::type_index.
|
||||
///
|
||||
/// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
|
||||
/// Overrides \b must remove const, volatile && and & modifiers from T.
|
||||
@ -120,7 +127,7 @@ protected:
|
||||
static Derived type_id() BOOST_NOEXCEPT;
|
||||
|
||||
/// This is a factory method that is used to create instances of Derived classes.
|
||||
/// boost::typeind::type_id_with_cvr() will call this method, if Derived has same type as boost::typeind::type_index.
|
||||
/// boost::typeindex::type_id_with_cvr() will call this method, if Derived has same type as boost::typeindex::type_index.
|
||||
///
|
||||
/// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
|
||||
/// Overrides \b must \b not remove const, volatile && and & modifiers from T.
|
||||
@ -130,7 +137,7 @@ protected:
|
||||
static Derived type_id_with_cvr() BOOST_NOEXCEPT;
|
||||
|
||||
/// This is a factory method that is used to create instances of Derived classes.
|
||||
/// boost::typeind::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeind::type_index.
|
||||
/// boost::typeindex::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeindex::type_index.
|
||||
///
|
||||
/// \b Override: This function \b may be redefined and made public in Derived class.
|
||||
/// \param variable Variable which runtime type will be stored in type_index.
|
||||
@ -144,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);
|
||||
}
|
||||
|
||||
@ -244,13 +251,13 @@ inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
||||
/// noexcept comparison operators for type_index_facade classes.
|
||||
bool operator ? (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;
|
||||
bool operator ==, !=, <, ... (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;
|
||||
|
||||
/// noexcept comparison operators for type_index_facade and it's TypeInfo classes.
|
||||
bool operator ? (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;
|
||||
bool operator ==, !=, <, ... (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;
|
||||
|
||||
/// noexcept comparison operators for type_index_facade's TypeInfo and type_index_facade classes.
|
||||
bool operator ? (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
|
||||
bool operator ==, !=, <, ... (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
|
||||
|
||||
#endif
|
||||
|
||||
@ -260,7 +267,7 @@ bool operator ? (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
|
||||
/// Ostream operator that will output demangled name
|
||||
template <class Derived, class TypeInfo>
|
||||
inline std::ostream& operator<<(std::ostream& ostr, const type_index_facade<Derived, TypeInfo>& ind) {
|
||||
ostr << ind.pretty_name();
|
||||
ostr << static_cast<Derived const&>(ind).pretty_name();
|
||||
return ostr;
|
||||
}
|
||||
/// @endcond
|
||||
@ -271,19 +278,20 @@ inline std::basic_ostream<CharT, TriatT>& operator<<(
|
||||
std::basic_ostream<CharT, TriatT>& ostr,
|
||||
const type_index_facade<Derived, TypeInfo>& ind)
|
||||
{
|
||||
ostr << ind.pretty_name();
|
||||
ostr << static_cast<Derived const&>(ind).pretty_name();
|
||||
return ostr;
|
||||
}
|
||||
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
|
||||
#endif // BOOST_NO_IOSTREAM
|
||||
|
||||
/// This free function is used by Boost's unordered containers.
|
||||
/// \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();
|
||||
}
|
||||
|
||||
}} // namespace boost::typeind
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
|
||||
|
35
index.html
Normal file
35
index.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2014-2022 Antony Polukhin
|
||||
antoshkka at gmail dot com
|
||||
|
||||
Distributed under the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<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 {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
a {
|
||||
color: #00f;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Automatic redirection failed, please go to
|
||||
<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-2022 Antony Polukhin
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
15
meta/libraries.json
Normal file
15
meta/libraries.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"key": "type_index",
|
||||
"name": "Type Index",
|
||||
"authors": [
|
||||
"Antony Polukhin"
|
||||
],
|
||||
"maintainers": [
|
||||
"Antony Polukhin <antoshkka -at- gmail.com>"
|
||||
],
|
||||
"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,58 +0,0 @@
|
||||
From fcd4da81d14847272fa888f4e9a54930b48ee95b Mon Sep 17 00:00:00 2001
|
||||
From: Antony Polukhin <antoshkka@gmail.com>
|
||||
Date: Sat, 11 Jan 2014 19:19:20 +0400
|
||||
Subject: [PATCH] Make Boost.Test work with RTTI disabled (fixes #9228)
|
||||
|
||||
---
|
||||
include/boost/test/execution_monitor.hpp | 2 +-
|
||||
include/boost/test/tree/test_case_template.hpp | 13 +++++++++++--
|
||||
2 files changed, 12 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/boost/test/execution_monitor.hpp b/include/boost/test/execution_monitor.hpp
|
||||
index f6b7681..259f97c 100644
|
||||
--- a/include/boost/test/execution_monitor.hpp
|
||||
+++ b/include/boost/test/execution_monitor.hpp
|
||||
@@ -261,7 +261,7 @@ public:
|
||||
template<typename ExceptionType>
|
||||
void erase_exception_translator( boost::type<ExceptionType>* = 0 )
|
||||
{
|
||||
- m_custom_translators = m_custom_translators->erase<ExceptionType>( m_custom_translators );
|
||||
+ m_custom_translators = m_custom_translators->template erase<ExceptionType>( m_custom_translators );
|
||||
}
|
||||
|
||||
private:
|
||||
diff --git a/include/boost/test/tree/test_case_template.hpp b/include/boost/test/tree/test_case_template.hpp
|
||||
index 9f7466a..b0fa634 100644
|
||||
--- a/include/boost/test/tree/test_case_template.hpp
|
||||
+++ b/include/boost/test/tree/test_case_template.hpp
|
||||
@@ -34,8 +34,13 @@
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/function/function0.hpp>
|
||||
|
||||
-// STL
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
#include <typeinfo> // for typeid
|
||||
+#else
|
||||
+#include <boost/current_function.hpp>
|
||||
+#endif
|
||||
+
|
||||
+// STL
|
||||
#include <string> // for std::string
|
||||
#include <list> // for std::list
|
||||
|
||||
@@ -77,7 +82,11 @@ struct generate_test_case_4_type {
|
||||
std::string full_name;
|
||||
assign_op( full_name, m_test_case_name, 0 );
|
||||
full_name += '<';
|
||||
- full_name += typeid(TestType).name();
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
+ full_name += typeid(TestType).name();
|
||||
+#else
|
||||
+ full_name += BOOST_CURRENT_FUNCTION;
|
||||
+#endif
|
||||
if( boost::is_const<TestType>::value )
|
||||
full_name += " const";
|
||||
full_name += '>';
|
||||
--
|
||||
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)
|
||||
@ -8,22 +8,26 @@ import testing ;
|
||||
import feature ;
|
||||
import os ;
|
||||
|
||||
# Variable that contains all the stuff required for linking against -lboost_unit_test
|
||||
tlib = /boost/test//boost_unit_test_framework/<link>static ;
|
||||
|
||||
# Variable that contains all the stuff required for linking together <rtti>on and <rtti>off
|
||||
compat = <define>BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY ;
|
||||
|
||||
# Making own `nortti` that is link compatible
|
||||
nortti = <toolset>gcc:<cxxflags>-fno-rtti <toolset>clang:<cxxflags>-fno-rtti <toolset>msvc:<cxxflags>/GR- ;
|
||||
# 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-" ;
|
||||
|
||||
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
|
||||
obj test_lib_nortti-obj : test_lib.cpp : <link>shared <rtti>off ;
|
||||
lib test_lib_nortti : test_lib_nortti-obj : <link>shared <rtti>off ;
|
||||
obj test_lib_nortti-obj : test_lib.cpp : <link>shared <rtti>off $(norttidefines) ;
|
||||
obj test_lib_anonymous_nortti-obj : test_lib_anonymous.cpp : <link>shared <rtti>off $(norttidefines) ;
|
||||
lib test_lib_nortti : test_lib_nortti-obj : <link>shared <rtti>off $(norttidefines) ;
|
||||
lib test_lib_anonymous_nortti : test_lib_anonymous_nortti-obj : <link>shared <rtti>off $(norttidefines) ;
|
||||
|
||||
obj test_lib_rtti-obj : test_lib.cpp : <link>shared ;
|
||||
obj test_lib_anonymous_rtti-obj : test_lib_anonymous.cpp : <link>shared ;
|
||||
lib test_lib_rtti : test_lib_rtti-obj : <link>shared ;
|
||||
lib test_lib_anonymous_rtti : test_lib_anonymous_rtti-obj : <link>shared ;
|
||||
|
||||
# Making libraries that can work between rtti-on/rtti-off modules
|
||||
obj test_lib_nortti_compat-obj : test_lib.cpp : <link>shared $(nortti) $(compat) ;
|
||||
@ -31,23 +35,34 @@ 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 $(tlib) ]
|
||||
[ run type_index_test.cpp $(tlib) : : : <rtti>off : type_index_test_no_rtti ]
|
||||
[ run testing_crossmodule.cpp test_lib_rtti $(tlib) ]
|
||||
[ run testing_crossmodule.cpp test_lib_nortti $(tlib) : : : <rtti>off : testing_crossmodule_no_rtti ]
|
||||
[ 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 : : : <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 $(tlib) 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 $(tlib) test_lib_nortti : : link_fail_rtti_nortti ]
|
||||
[ run testing_crossmodule.cpp $(tlib) test_lib_rtti_compat : : : $(nortti) $(compat) : testing_crossmodule_nortti_rtti_compat ]
|
||||
[ run testing_crossmodule.cpp $(tlib) test_lib_nortti_compat : : : $(compat) : testing_crossmodule_rtti_nortti_compat ]
|
||||
|
||||
# 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 ]
|
||||
;
|
||||
|
||||
# Assuring that examples compile and run. Adding sources from `examples` directory to the `type_index` test suite.
|
||||
@ -58,6 +73,9 @@ for local p in [ glob ../examples/*.cpp ]
|
||||
|
||||
# RTTI off
|
||||
local target_name = $(p[1]:B)_no_rtti ;
|
||||
type_index += [ run $(p) : : : <rtti>off : $(target_name) ] ;
|
||||
if $(target_name) != "table_of_names_no_rtti"
|
||||
{
|
||||
type_index += [ run $(p) : : : <rtti>off $(norttidefines) : $(target_name) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
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
|
||||
|
44
test/ctti_print_name.cpp
Normal file
44
test/ctti_print_name.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// 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 <iostream>
|
||||
|
||||
// This cpp file:
|
||||
// * tests BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING macro
|
||||
// * outputs full ctti name so that TypeIndex library could be adjust to new compiler without requesting regression tester's help
|
||||
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (0,0,false,"")
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
|
||||
namespace user_defined_namespace {
|
||||
class user_defined_class {};
|
||||
}
|
||||
|
||||
class empty
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
|
||||
std::cout << "int: "
|
||||
<< ctti_type_index::type_id<int>() << '\n';
|
||||
|
||||
std::cout << "double: "
|
||||
<< ctti_type_index::type_id<double>() << '\n';
|
||||
|
||||
std::cout << "user_defined_namespace::user_defined_class: "
|
||||
<< 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"
|
||||
|
||||
@ -7,25 +15,26 @@ namespace user_defined_namespace {
|
||||
|
||||
namespace test_lib {
|
||||
|
||||
boost::typeind::type_index get_integer() {
|
||||
return boost::typeind::type_id<int>();
|
||||
boost::typeindex::type_index get_integer() {
|
||||
return boost::typeindex::type_id<int>();
|
||||
}
|
||||
|
||||
boost::typeind::type_index get_user_defined_class() {
|
||||
return boost::typeind::type_id<user_defined_namespace::user_defined>();
|
||||
boost::typeindex::type_index get_user_defined_class() {
|
||||
return boost::typeindex::type_id<user_defined_namespace::user_defined>();
|
||||
}
|
||||
|
||||
boost::typeind::type_index get_const_integer() {
|
||||
return boost::typeind::type_id_with_cvr<const int>();
|
||||
boost::typeindex::type_index get_const_integer() {
|
||||
return boost::typeindex::type_id_with_cvr<const int>();
|
||||
}
|
||||
|
||||
boost::typeind::type_index get_const_user_defined_class() {
|
||||
return boost::typeind::type_id_with_cvr<const user_defined_namespace::user_defined>();
|
||||
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::typeind::type_index&) {}
|
||||
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
|
||||
@ -25,14 +25,16 @@
|
||||
|
||||
namespace test_lib {
|
||||
|
||||
TEST_LIB_DECL boost::typeind::type_index get_integer();
|
||||
TEST_LIB_DECL boost::typeind::type_index get_user_defined_class();
|
||||
TEST_LIB_DECL boost::typeindex::type_index get_integer();
|
||||
TEST_LIB_DECL boost::typeindex::type_index get_user_defined_class();
|
||||
|
||||
TEST_LIB_DECL boost::typeind::type_index get_const_integer();
|
||||
TEST_LIB_DECL boost::typeind::type_index get_const_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::typeind::type_index&);
|
||||
TEST_LIB_DECL void accept_typeindex(const boost::typeindex::type_index&);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
27
test/test_lib_anonymous.cpp
Normal file
27
test/test_lib_anonymous.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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"
|
||||
|
||||
namespace {
|
||||
class user_defined{};
|
||||
} // anonymous namespace
|
||||
|
||||
namespace test_lib {
|
||||
|
||||
boost::typeindex::type_index get_anonymous_user_defined_class() {
|
||||
return boost::typeindex::type_id<user_defined>();
|
||||
}
|
||||
|
||||
boost::typeindex::type_index get_const_anonymous_user_defined_class() {
|
||||
return boost::typeindex::type_id_with_cvr<const user_defined>();
|
||||
}
|
||||
|
||||
}
|
||||
|
34
test/test_lib_anonymous.hpp
Normal file
34
test/test_lib_anonymous.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_TESTS_TEST_LIB_ANONYMOUS_HPP
|
||||
#define BOOST_TYPE_INDEX_TESTS_TEST_LIB_ANONYMOUS_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
// This is ALWAYS a dynamic library
|
||||
#if defined(TEST_LIB_SOURCE)
|
||||
# define TEST_LIB_DECL BOOST_SYMBOL_EXPORT
|
||||
# else
|
||||
# define TEST_LIB_DECL BOOST_SYMBOL_IMPORT
|
||||
# endif
|
||||
|
||||
namespace test_lib {
|
||||
|
||||
TEST_LIB_DECL boost::typeindex::type_index get_anonymous_user_defined_class();
|
||||
TEST_LIB_DECL boost::typeindex::type_index get_const_anonymous_user_defined_class();
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_TESTS_TEST_LIB_ANONYMOUS_HPP
|
||||
|
@ -1,47 +1,57 @@
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_TEST_MODULE testing_crossmodule_module
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include "test_lib.hpp"
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
namespace user_defined_namespace {
|
||||
class user_defined{};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparing_types_between_modules)
|
||||
void comparing_types_between_modules()
|
||||
{
|
||||
boost::typeind::type_index t_const_int = boost::typeind::type_id_with_cvr<const int>();
|
||||
boost::typeind::type_index t_int = boost::typeind::type_id<int>();
|
||||
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::typeind::type_index t_const_userdef
|
||||
= boost::typeind::type_id_with_cvr<const user_defined_namespace::user_defined>();
|
||||
boost::typeind::type_index t_userdef
|
||||
= boost::typeind::type_id<user_defined_namespace::user_defined>();
|
||||
boost::typeindex::type_index t_const_userdef
|
||||
= boost::typeindex::type_id_with_cvr<const user_defined_namespace::user_defined>();
|
||||
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 main() {
|
||||
comparing_types_between_modules();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
48
test/testing_crossmodule_anonymous.cpp
Normal file
48
test/testing_crossmodule_anonymous.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// 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/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 {
|
||||
class user_defined{};
|
||||
}
|
||||
|
||||
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>();
|
||||
|
||||
// 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 main() {
|
||||
comparing_anonymous_types_between_modules();
|
||||
|
||||
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,18 +1,16 @@
|
||||
//
|
||||
// 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)
|
||||
|
||||
#define BOOST_TEST_MODULE type_index_test_module
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
}
|
||||
@ -23,116 +21,118 @@ namespace my_namespace2 {
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(names_matches_type_id)
|
||||
void names_matches_type_id()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
BOOST_CHECK_EQUAL(type_id<int>().pretty_name(), "int");
|
||||
BOOST_CHECK_EQUAL(type_id<double>().pretty_name(), "double");
|
||||
using namespace boost::typeindex;
|
||||
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());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(default_construction)
|
||||
void default_construction()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(copy_construction)
|
||||
void copy_construction()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
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);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparators_type_id)
|
||||
void comparators_type_id()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
using namespace boost::typeindex;
|
||||
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);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(hash_code_type_id)
|
||||
void hash_code_type_id()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
using namespace boost::typeindex;
|
||||
std::size_t t_int1 = type_id<int>().hash_code();
|
||||
std::size_t t_double1 = type_id<double>().hash_code();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1, class T2>
|
||||
static void test_with_modofiers() {
|
||||
using namespace boost::typeind;
|
||||
using namespace boost::typeindex;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_id_storing_modifiers)
|
||||
void type_id_storing_modifiers()
|
||||
{
|
||||
test_with_modofiers<int, const int>();
|
||||
test_with_modofiers<int, const int&>();
|
||||
@ -182,88 +182,91 @@ BOOST_AUTO_TEST_CASE(type_id_storing_modifiers)
|
||||
|
||||
template <class T>
|
||||
static void test_storing_nonstoring_modifiers_templ() {
|
||||
using namespace boost::typeind;
|
||||
using namespace boost::typeindex;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_id_storing_modifiers_vs_nonstoring)
|
||||
void type_id_storing_modifiers_vs_nonstoring()
|
||||
{
|
||||
test_storing_nonstoring_modifiers_templ<int>();
|
||||
test_storing_nonstoring_modifiers_templ<my_namespace1::my_class>();
|
||||
test_storing_nonstoring_modifiers_templ<my_namespace2::my_class>();
|
||||
|
||||
boost::typeind::type_index t1 = boost::typeind::type_id_with_cvr<const int>();
|
||||
boost::typeind::type_index t2 = boost::typeind::type_id<int>();
|
||||
BOOST_CHECK_NE(t2, t1);
|
||||
BOOST_CHECK(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
|
||||
boost::typeindex::type_index t1 = boost::typeindex::type_id_with_cvr<const int>();
|
||||
boost::typeindex::type_index t2 = boost::typeindex::type_id<int>();
|
||||
BOOST_TEST_NE(t2, t1);
|
||||
BOOST_TEST(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_index_stream_operator_via_lexical_cast_testing)
|
||||
void type_index_stream_operator_via_lexical_cast_testing()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
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");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_index_stripping_cvr_test)
|
||||
void type_index_stripping_cvr_test()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
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&>());
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_index_user_defined_class_test)
|
||||
void type_index_user_defined_class_test()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct A {
|
||||
public:
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
@ -278,7 +281,7 @@ struct C: public B {
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparators_type_id_runtime)
|
||||
void comparators_type_id_runtime()
|
||||
{
|
||||
C c1;
|
||||
B b1;
|
||||
@ -288,90 +291,110 @@ BOOST_AUTO_TEST_CASE(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::typeind::type_index(pc1->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::typeind::type_id_runtime(rc1), boost::typeind::type_id_runtime(*pc1));
|
||||
BOOST_CHECK_EQUAL(boost::typeind::type_id<C>(), boost::typeind::type_id_runtime(*pc1));
|
||||
BOOST_CHECK_EQUAL(boost::typeind::type_id_runtime(rb1), boost::typeind::type_id_runtime(*pb1));
|
||||
BOOST_CHECK_EQUAL(boost::typeind::type_id<B>(), boost::typeind::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::typeind::type_id_runtime(rc1), boost::typeind::type_id_runtime(*pb1));
|
||||
BOOST_CHECK_NE(boost::typeind::type_id_runtime(rb1), boost::typeind::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::typeind::type_id_runtime(&rc1), boost::typeind::type_id_runtime(pb1));
|
||||
BOOST_CHECK_EQUAL(boost::typeind::type_id_runtime(&rb1), boost::typeind::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::typeind::type_id_runtime(rc1) == typeid(*pc1));
|
||||
BOOST_CHECK(boost::typeind::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::typeind::type_id_runtime(rc1) != typeid(*pb1));
|
||||
BOOST_CHECK(boost::typeind::type_id_runtime(rb1) != typeid(*pc1));
|
||||
BOOST_CHECK(boost::typeind::type_id_runtime(&rc1) == typeid(pb1));
|
||||
BOOST_CHECK(boost::typeind::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
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparators_type_id_vs_type_info)
|
||||
void comparators_type_id_vs_type_info()
|
||||
{
|
||||
using namespace boost::typeind;
|
||||
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 main() {
|
||||
names_matches_type_id();
|
||||
default_construction();
|
||||
copy_construction();
|
||||
comparators_type_id();
|
||||
hash_code_type_id();
|
||||
|
||||
type_id_storing_modifiers();
|
||||
type_id_storing_modifiers_vs_nonstoring();
|
||||
type_index_stream_operator_via_lexical_cast_testing();
|
||||
type_index_stripping_cvr_test();
|
||||
type_index_user_defined_class_test();
|
||||
|
||||
comparators_type_id_runtime();
|
||||
#ifndef BOOST_NO_RTTI
|
||||
comparators_type_id_vs_type_info();
|
||||
#endif
|
||||
|
||||
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
|
||||
@ -10,8 +10,8 @@
|
||||
|
||||
int main() {
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
boost::alignment_of<boost::typeind::detail::ctti_data>::value == boost::alignment_of<char>::value,
|
||||
"Alignments of boost::typeind::detail::ctti_data and char differ. "
|
||||
boost::alignment_of<boost::typeindex::detail::ctti_data>::value == boost::alignment_of<char>::value,
|
||||
"Alignments of boost::typeindex::detail::ctti_data and char differ. "
|
||||
"It is unsafe to reinterpret_cast between them."
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
@ -8,7 +8,7 @@
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
|
||||
int main() {
|
||||
using namespace boost::typeind;
|
||||
using namespace boost::typeindex;
|
||||
ctti_type_index::type_info_t t;
|
||||
(void)t;
|
||||
}
|
||||
|
@ -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
|
||||
@ -8,7 +8,7 @@
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
|
||||
int main() {
|
||||
using namespace boost::typeind;
|
||||
using namespace boost::typeindex;
|
||||
ctti_type_index::type_info_t t = ctti_type_index::type_id<int>().type_info();
|
||||
(void)t;
|
||||
}
|
||||
|
Reference in New Issue
Block a user