forked from boostorg/type_index
Compare commits
245 Commits
v2.1
...
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 | |||
2e11dc75d4 | |||
a2a934dde8 | |||
3f51425f3c | |||
501a0a992e | |||
b8265cdb4f | |||
89398ac07c | |||
40f6ae1ede | |||
2ebd172f4e | |||
70fdaa633e | |||
7ddb306c65 | |||
7488e75a9c | |||
b44845b46d | |||
0d8c6f36ad | |||
98e5bbe6ac | |||
276101f1b3 | |||
ea2e5beabb | |||
c99b7b26da | |||
78824176ea | |||
de0d90eca1 | |||
2ef8924510 | |||
beaa53f460 | |||
0137b9b43f | |||
683dab93a2 | |||
496ab93589 | |||
c0871ef714 | |||
2f9c4b7834 | |||
c43f8c1cfa | |||
50d496288f | |||
3daeab38fa | |||
5f97225a18 |
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
|
379
.gitignore
vendored
379
.gitignore
vendored
@ -1,377 +1,2 @@
|
||||
# Ignore docs/html directory, that is actually a `gh-pages` branch
|
||||
/libs/type_index/doc/autodoc.xml
|
||||
/libs/type_index/doc/html/
|
||||
|
||||
|
||||
# While testing I use this project inside the SVN's /boost/trunk folders
|
||||
# Follwoing rules ignore all the /boost's files, without ignorng the TypeIndex library
|
||||
|
||||
*~
|
||||
*.svn
|
||||
/boost/.svn/
|
||||
/boost/accumulators
|
||||
/boost/algorithm
|
||||
/boost/aligned_storage.hpp
|
||||
/boost/any.hpp
|
||||
/boost/any.hpp~
|
||||
/boost/archive
|
||||
/boost/array.hpp
|
||||
/boost/asio
|
||||
/boost/asio.hpp
|
||||
/boost/assert.hpp
|
||||
/boost/assign
|
||||
/boost/assign.hpp
|
||||
/boost/atomic
|
||||
/boost/atomic.hpp
|
||||
/boost/bimap
|
||||
/boost/bimap.hpp
|
||||
/boost/bind
|
||||
/boost/bind.hpp
|
||||
/boost/blank_fwd.hpp
|
||||
/boost/blank.hpp
|
||||
/boost/call_traits.hpp
|
||||
/boost/cast.hpp
|
||||
/boost/cerrno.hpp
|
||||
/boost/checked_delete.hpp
|
||||
/boost/chrono
|
||||
/boost/chrono.hpp
|
||||
/boost/circular_buffer
|
||||
/boost/circular_buffer_fwd.hpp
|
||||
/boost/circular_buffer.hpp
|
||||
/boost/compatibility
|
||||
/boost/compressed_pair.hpp
|
||||
/boost/concept
|
||||
/boost/concept_archetype.hpp
|
||||
/boost/concept_check
|
||||
/boost/concept_check.hpp
|
||||
/boost/config
|
||||
/boost/config.hpp
|
||||
/boost/container
|
||||
/boost/context
|
||||
/boost/coroutine
|
||||
/boost/crc.hpp
|
||||
/boost/cregex.hpp
|
||||
/boost/cstdint.hpp
|
||||
/boost/cstdlib.hpp
|
||||
/boost/current_function.hpp
|
||||
/boost/date_time
|
||||
/boost/date_time.hpp
|
||||
/boost/detail
|
||||
/boost/dynamic_bitset
|
||||
/boost/dynamic_bitset_fwd.hpp
|
||||
/boost/dynamic_bitset.hpp
|
||||
/boost/enable_shared_from_this.hpp
|
||||
/boost/exception
|
||||
/boost/exception_ptr.hpp
|
||||
/boost/filesystem
|
||||
/boost/filesystem.hpp
|
||||
/boost/flyweight
|
||||
/boost/flyweight.hpp
|
||||
/boost/foreach_fwd.hpp
|
||||
/boost/foreach.hpp
|
||||
/boost/format
|
||||
/boost/format.hpp
|
||||
/boost/function
|
||||
/boost/functional
|
||||
/boost/functional.hpp
|
||||
/boost/function_equal.hpp
|
||||
/boost/function.hpp
|
||||
/boost/function_output_iterator.hpp
|
||||
/boost/function_types
|
||||
/boost/fusion
|
||||
/boost/generator_iterator.hpp
|
||||
/boost/geometry
|
||||
/boost/geometry.hpp
|
||||
/boost/get_pointer.hpp
|
||||
/boost/gil
|
||||
/boost/graph
|
||||
/boost/heap
|
||||
/boost/icl
|
||||
/boost/implicit_cast.hpp
|
||||
/boost/indirect_reference.hpp
|
||||
/boost/integer
|
||||
/boost/integer_fwd.hpp
|
||||
/boost/integer.hpp
|
||||
/boost/integer_traits.hpp
|
||||
/boost/interprocess
|
||||
/boost/intrusive
|
||||
/boost/intrusive_ptr.hpp
|
||||
/boost/io
|
||||
/boost/io_fwd.hpp
|
||||
/boost/iostreams
|
||||
/boost/is_placeholder.hpp
|
||||
/boost/iterator
|
||||
/boost/iterator_adaptors.hpp
|
||||
/boost/iterator.hpp
|
||||
/boost/lambda
|
||||
/boost/last_value.hpp
|
||||
/boost/lexical_cast.hpp
|
||||
/boost/lexical_cast.hpp~
|
||||
/boost/limits.hpp
|
||||
/boost/locale
|
||||
/boost/locale.hpp
|
||||
/boost/local_function
|
||||
/boost/local_function.hpp
|
||||
/boost/lockfree
|
||||
/boost/log
|
||||
/boost/logic
|
||||
/boost/make_shared.hpp
|
||||
/boost/math
|
||||
/boost/math_fwd.hpp
|
||||
/boost/mem_fn.hpp
|
||||
/boost/memory_order.hpp
|
||||
/boost/move
|
||||
/boost/mpi
|
||||
/boost/mpi.hpp
|
||||
/boost/mpl
|
||||
/boost/msm
|
||||
/boost/multi_array
|
||||
/boost/multi_array.hpp
|
||||
/boost/multi_index
|
||||
/boost/multi_index_container_fwd.hpp
|
||||
/boost/multi_index_container.hpp
|
||||
/boost/multiprecision
|
||||
/boost/next_prior.hpp
|
||||
/boost/noncopyable.hpp
|
||||
/boost/nondet_random.hpp
|
||||
/boost/none.hpp
|
||||
/boost/none_t.hpp
|
||||
/boost/non_type.hpp
|
||||
/boost/numeric
|
||||
/boost/operators.hpp
|
||||
/boost/optional
|
||||
/boost/optional.hpp
|
||||
/boost/parameter
|
||||
/boost/parameter.hpp
|
||||
/boost/pending
|
||||
/boost/phoenix
|
||||
/boost/phoenix.hpp
|
||||
/boost/pointee.hpp
|
||||
/boost/pointer_cast.hpp
|
||||
/boost/pointer_to_other.hpp
|
||||
/boost/polygon
|
||||
/boost/pool
|
||||
/boost/predef
|
||||
/boost/predef.h
|
||||
/boost/preprocessor
|
||||
/boost/preprocessor.hpp
|
||||
/boost/program_options
|
||||
/boost/program_options.hpp
|
||||
/boost/progress.hpp
|
||||
/boost/progress.hpp~
|
||||
/boost/property_map
|
||||
/boost/property_tree
|
||||
/boost/proto
|
||||
/boost/ptr_container
|
||||
/boost/python
|
||||
/boost/python.hpp
|
||||
/boost/random
|
||||
/boost/random.hpp
|
||||
/boost/range
|
||||
/boost/range.hpp
|
||||
/boost/ratio
|
||||
/boost/ratio.hpp
|
||||
/boost/rational.hpp
|
||||
/boost/rational.hpp.htm
|
||||
/boost/ref.hpp
|
||||
/boost/regex
|
||||
/boost/regex_fwd.hpp
|
||||
/boost/regex.h
|
||||
/boost/regex.hpp
|
||||
/boost/scoped_array.hpp
|
||||
/boost/scoped_ptr.hpp
|
||||
/boost/scope_exit.hpp
|
||||
/boost/serialization
|
||||
/boost/shared_array.hpp
|
||||
/boost/shared_container_iterator.hpp
|
||||
/boost/shared_ptr.hpp
|
||||
/boost/signal.hpp
|
||||
/boost/signals
|
||||
/boost/signals2
|
||||
/boost/signals2.hpp
|
||||
/boost/signals.hpp
|
||||
/boost/smart_ptr
|
||||
/boost/smart_ptr.hpp
|
||||
/boost/spirit
|
||||
/boost/spirit.hpp
|
||||
/boost/statechart
|
||||
/boost/static_assert.hpp
|
||||
/boost/strong_typedef.hpp
|
||||
/boost/swap.hpp
|
||||
/boost/sync
|
||||
/boost/system
|
||||
/boost/test
|
||||
/boost/thread
|
||||
/boost/thread.hpp
|
||||
/boost/throw_exception.hpp
|
||||
/boost/timer
|
||||
/boost/timer.hpp
|
||||
/boost/token_functions.hpp
|
||||
/boost/token_iterator.hpp
|
||||
/boost/tokenizer.hpp
|
||||
/boost/tr1
|
||||
/boost/tti
|
||||
/boost/tuple
|
||||
/boost/type_erasure
|
||||
/boost/type.hpp
|
||||
/boost/typeof
|
||||
/boost/type_traits
|
||||
/boost/type_traits.hpp
|
||||
/boost/type_traits.hpp~
|
||||
/boost/units
|
||||
/boost/unordered
|
||||
/boost/unordered_map.hpp
|
||||
/boost/unordered_set.hpp
|
||||
/boost/utility
|
||||
/boost/utility.hpp
|
||||
/boost/uuid
|
||||
/boost/variant
|
||||
/boost/variant.hpp
|
||||
/boost/version.hpp
|
||||
/boost/visit_each.hpp
|
||||
/boost/wave
|
||||
/boost/wave.hpp
|
||||
/boost/weak_ptr.hpp
|
||||
/boost/xpressive
|
||||
|
||||
|
||||
/libs/accumulators
|
||||
/libs/algorithm
|
||||
/libs/any
|
||||
/libs/array
|
||||
/libs/asio
|
||||
/libs/assign
|
||||
/libs/atomic
|
||||
/libs/bimap
|
||||
/libs/bind
|
||||
/libs/chrono
|
||||
/libs/circular_buffer
|
||||
/libs/compatibility
|
||||
/libs/compose
|
||||
/libs/concept_check
|
||||
/libs/config
|
||||
/libs/container
|
||||
/libs/context
|
||||
/libs/conversion
|
||||
/libs/coroutine
|
||||
/libs/crc
|
||||
/libs/date_time
|
||||
/libs/detail
|
||||
/libs/disjoint_sets
|
||||
/libs/dynamic_bitset
|
||||
/libs/exception
|
||||
/libs/filesystem
|
||||
/libs/flyweight
|
||||
/libs/foreach
|
||||
/libs/format
|
||||
/libs/function
|
||||
/libs/functional
|
||||
/libs/function_types
|
||||
/libs/fusion
|
||||
/libs/geometry
|
||||
/libs/gil
|
||||
/libs/graph
|
||||
/libs/graph_parallel
|
||||
/libs/heap
|
||||
/libs/icl
|
||||
/libs/index.html
|
||||
/libs/integer
|
||||
/libs/interprocess
|
||||
/libs/intrusive
|
||||
/libs/io
|
||||
/libs/iostreams
|
||||
/libs/iterator
|
||||
/libs/lambda
|
||||
/libs/libraries.htm
|
||||
/libs/locale
|
||||
/libs/local_function
|
||||
/libs/lockfree
|
||||
/libs/log
|
||||
/libs/logic
|
||||
/libs/maintainers.txt
|
||||
/libs/math
|
||||
/libs/mem_fn
|
||||
/libs/move
|
||||
/libs/mpi
|
||||
/libs/mpl
|
||||
/libs/msm
|
||||
/libs/multi_array
|
||||
/libs/multi_index
|
||||
/libs/multiprecision
|
||||
/libs/numeric
|
||||
/libs/optional
|
||||
/libs/parameter
|
||||
/libs/phoenix
|
||||
/libs/platform_maintainers.txt
|
||||
/libs/polygon
|
||||
/libs/pool
|
||||
/libs/predef
|
||||
/libs/preprocessor
|
||||
/libs/program_options
|
||||
/libs/property_map
|
||||
/libs/property_tree
|
||||
/libs/proto
|
||||
/libs/ptr_container
|
||||
/libs/python
|
||||
/libs/random
|
||||
/libs/range
|
||||
/libs/ratio
|
||||
/libs/rational
|
||||
/libs/regex
|
||||
/libs/scope_exit
|
||||
/libs/serialization
|
||||
/libs/signals
|
||||
/libs/signals2
|
||||
/libs/smart_ptr
|
||||
/libs/spirit
|
||||
/libs/statechart
|
||||
/libs/static_assert
|
||||
/libs/sync
|
||||
/libs/system
|
||||
/libs/test
|
||||
/libs/thread
|
||||
/libs/timer
|
||||
/libs/tokenizer
|
||||
/libs/tr1
|
||||
/libs/tti
|
||||
/libs/tuple
|
||||
/libs/type_erasure
|
||||
/libs/typeof
|
||||
/libs/type_traits
|
||||
/libs/units
|
||||
/libs/unordered
|
||||
/libs/utility
|
||||
/libs/uuid
|
||||
/libs/variant
|
||||
/libs/wave
|
||||
/libs/xpressive
|
||||
/libs/Jamfile.v2
|
||||
|
||||
|
||||
/boost.css
|
||||
/b2
|
||||
/boost-build.jam
|
||||
/rst.css
|
||||
/boost.png
|
||||
/bootstrap.sh
|
||||
/project-config.jam
|
||||
/Jamroot
|
||||
/.gitignore~
|
||||
/index.htm
|
||||
/README.md
|
||||
/boostcpp.jam
|
||||
/INSTALL
|
||||
/LICENSE_1_0.txt
|
||||
/index.html
|
||||
/bjam
|
||||
/bootstrap.bat
|
||||
/bootstrap.log
|
||||
/boostcpp.py
|
||||
|
||||
|
||||
/bin.v2/
|
||||
/doc/
|
||||
/more/
|
||||
/status/
|
||||
/tools/
|
||||
/stage/
|
||||
doc/autodoc.xml
|
||||
doc/html
|
||||
|
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,34 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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_HPP
|
||||
#define BOOST_TYPE_INDEX_HPP
|
||||
|
||||
/// \file boost/type_index.hpp
|
||||
/// \brief Includes all the headers of the Boost.TypeIndex library.
|
||||
///
|
||||
/// By inclusion of this file all classes (boost::type_info + boost::type_index if RTTI is on
|
||||
/// and boost::template_info + boost::template_index) will be available.
|
||||
///
|
||||
/// Consider including <boost/type_index/type_index.hpp> if you do not want to include
|
||||
/// boost::template_info and boost::template_index class while RTTI is available.
|
||||
///
|
||||
/// Consider including <boost/type_index/type_info.hpp> if you need only boost::type_info class
|
||||
/// and boost::type_id* functions.
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/type_index/type_info.hpp>
|
||||
#include <boost/type_index/type_index.hpp>
|
||||
#include <boost/type_index/template_info.hpp>
|
||||
#include <boost/type_index/template_index.hpp>
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_HPP
|
||||
|
@ -1,35 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2013.
|
||||
//
|
||||
//
|
||||
// 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_TEMPLATE_INDEX_HPP
|
||||
#define BOOST_TYPE_INDEX_TEMPLATE_INDEX_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
/// \file template_index.hpp
|
||||
/// \brief Contains implementation of boost::template_index class.
|
||||
///
|
||||
/// boost::template_index is just a typedef of boost::template_info, that combines functionality
|
||||
/// of boost::type_info and boost::type_index but can work with RTTI disabled.
|
||||
|
||||
#include <boost/type_index/template_info.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
/// boost::template_index is just a typedef of boost::template_info, that combines functionality
|
||||
/// of boost::type_info and boost::type_index but can work with RTTI disabled.
|
||||
typedef template_info template_index;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_TEMPLATE_INDEX_HPP
|
||||
|
@ -1,317 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2013.
|
||||
//
|
||||
//
|
||||
// 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_TEMPLATE_INFO_HPP
|
||||
#define BOOST_TYPE_INDEX_TEMPLATE_INFO_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
/// \file template_info.hpp
|
||||
/// \brief Contains implementation of boost::template_info class.
|
||||
///
|
||||
/// boost::template_info class is used instead of boost::type_info and boost::type_index classes
|
||||
/// in situations when RTTI is disabled.
|
||||
///
|
||||
/// It combines functionality of std::type_info and std::type_index.
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_IOSTREAM)
|
||||
#if !defined(BOOST_NO_IOSFWD)
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
#else
|
||||
#include <ostream>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
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
|
||||
|
||||
#elif defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
|
||||
template <class T>
|
||||
inline void lazy_function_signature_assert(){}
|
||||
|
||||
#elif defined(__FUNCSIG__)
|
||||
|
||||
template <class T>
|
||||
inline void lazy_function_signature_assert(){}
|
||||
#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE __FUNCSIG__
|
||||
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
|| defined(__GNUC__) \
|
||||
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__)
|
||||
|
||||
template <class T>
|
||||
inline void lazy_function_signature_assert(){}
|
||||
#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE __PRETTY_FUNCTION__
|
||||
|
||||
#else
|
||||
|
||||
template <class T>
|
||||
inline void lazy_function_signature_assert() {
|
||||
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
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
||||
/// \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
|
||||
#endif
|
||||
|
||||
/// Noncopyable type_info that does not require RTTI
|
||||
/// CTTI == Compile Time Type Info
|
||||
/// This name must be as short as posible, to avoid code bloat
|
||||
template <class T>
|
||||
struct ctti {
|
||||
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 {
|
||||
lazy_function_signature_assert<T>();
|
||||
return BOOST_TYPE_INDEX_FUNCTION_SIGNATURE + detail::ctti_skip_size_at_begin;
|
||||
}
|
||||
|
||||
/// Returns raw name
|
||||
static const char* name() BOOST_NOEXCEPT {
|
||||
return this_type::n();
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// Copyable type_info class that does not require RTTI.
|
||||
/// When RTTI is disabled this class will be used instead of boost::type_info and boost::type_index.
|
||||
class template_info {
|
||||
private:
|
||||
const char* name_;
|
||||
|
||||
/// @cond
|
||||
explicit template_info(const char* name) BOOST_NOEXCEPT
|
||||
: name_(name)
|
||||
{}
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
/// Default constructor.
|
||||
template_info() BOOST_NOEXCEPT
|
||||
: name_(detail::ctti<void>::name())
|
||||
{}
|
||||
|
||||
/// Factory method for constructing boost::template_info instance for type T.
|
||||
/// Strips const, volatile and & modifiers from T.
|
||||
///
|
||||
/// Works exactly like boost::template_id().
|
||||
template <class T>
|
||||
static const template_info& construct(){
|
||||
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;
|
||||
|
||||
# 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.");
|
||||
#endif
|
||||
|
||||
static const template_info ret(detail::ctti<no_cvr_t>::name());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Factory method for constructing template_info instance for type T.
|
||||
/// Does not strip const, volatile and & modifiers from T.
|
||||
///
|
||||
/// Works exactly like boost::template_id_with_cvr().
|
||||
template <class T>
|
||||
static const template_info& construct_with_cvr() {
|
||||
# if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
BOOST_STATIC_ASSERT_MSG( !boost::is_arithmetic<T>::type::value
|
||||
, "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions.");
|
||||
#endif
|
||||
|
||||
static const template_info ret(detail::ctti<T>::name());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if the type precedes the type of rhs in the collation order.
|
||||
/// The collation order is just an internal order.
|
||||
bool before(const template_info& rhs) const BOOST_NOEXCEPT {
|
||||
return std::strcmp(name(), rhs.name()) < 0;
|
||||
}
|
||||
|
||||
/// Returns raw name
|
||||
const char* name() const BOOST_NOEXCEPT {
|
||||
return name_;
|
||||
}
|
||||
|
||||
/// Returns user-friendly name
|
||||
std::string name_demangled() const {
|
||||
std::size_t len = std::strlen(name_ + detail::ctti_skip_size_at_end);
|
||||
while (name_[len - 1] == ' ') --len; // MSVC sometimes adds whitespaces
|
||||
return std::string(name_, len);
|
||||
}
|
||||
|
||||
bool operator == (const template_info& rhs) const BOOST_NOEXCEPT {
|
||||
return name_ == rhs.name() || !std::strcmp(name_, rhs.name());
|
||||
}
|
||||
|
||||
bool operator != (const template_info& rhs) const BOOST_NOEXCEPT {
|
||||
return name_ != rhs.name() && !!std::strcmp(name_, rhs.name());
|
||||
}
|
||||
|
||||
bool operator < (const template_info& rhs) const BOOST_NOEXCEPT {
|
||||
return name_ != rhs.name() && std::strcmp(name_, rhs.name()) < 0;
|
||||
}
|
||||
|
||||
bool operator > (const template_info& rhs) const BOOST_NOEXCEPT {
|
||||
return name_ != rhs.name() && std::strcmp(name_, rhs.name()) > 0;
|
||||
}
|
||||
|
||||
bool operator <= (const template_info& rhs) const BOOST_NOEXCEPT {
|
||||
return name_ == rhs.name() || std::strcmp(name_, rhs.name()) <= 0;
|
||||
}
|
||||
|
||||
bool operator >= (const template_info& rhs) const BOOST_NOEXCEPT {
|
||||
return name_ == rhs.name() || std::strcmp(name_, rhs.name()) >= 0;
|
||||
}
|
||||
|
||||
/// Function for getting hash value
|
||||
std::size_t hash_code() const BOOST_NOEXCEPT {
|
||||
return boost::hash_range(name_, name_ + std::strlen(name_ + detail::ctti_skip_size_at_end));
|
||||
}
|
||||
};
|
||||
|
||||
/// Method for constructing template_info instance for type T.
|
||||
/// Strips const, volatile and & modifiers from T.
|
||||
template <class T>
|
||||
inline const template_info& template_id() BOOST_NOEXCEPT {
|
||||
return template_info::construct<T>();
|
||||
}
|
||||
|
||||
/// Method for constructing template_info instance for type T.
|
||||
/// Does not strip const, volatile and & modifiers from T.
|
||||
/// If T has no const, volatile, & and && modifiers, then returns exactly
|
||||
/// the same result as in case of calling `template_id<T>()`.
|
||||
template <class T>
|
||||
inline const template_info& template_id_with_cvr() BOOST_NOEXCEPT {
|
||||
return template_info::construct_with_cvr<T>();
|
||||
}
|
||||
|
||||
/* *************** template_info free functions ******************* */
|
||||
|
||||
#ifndef BOOST_NO_IOSTREAM
|
||||
#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
|
||||
/// Ostream operator that will output demangled name
|
||||
inline std::ostream& operator<<(std::ostream& ostr, template_info const& ind) {
|
||||
ostr << ind.name_demangled();
|
||||
return ostr;
|
||||
}
|
||||
#else
|
||||
/// Ostream operator that will output demangled name
|
||||
template <class CharT, class TriatT>
|
||||
inline std::basic_ostream<CharT, TriatT>& operator<<(std::basic_ostream<CharT, TriatT>& ostr, template_info const& ind) {
|
||||
ostr << ind.name_demangled();
|
||||
return ostr;
|
||||
}
|
||||
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
|
||||
#endif // BOOST_NO_IOSTREAM
|
||||
|
||||
/// hash_value function overload for template_info
|
||||
inline std::size_t hash_value(template_info const& v) BOOST_NOEXCEPT {
|
||||
return v.hash_code();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_TEMPLATE_INFO_HPP
|
||||
|
@ -1,221 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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_TYPE_INDEX_HPP
|
||||
#define BOOST_TYPE_INDEX_TYPE_INDEX_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/// \file boost/type_index/type_index.hpp
|
||||
/// \brief Contains implementation of boost::type_index class.
|
||||
///
|
||||
/// boost::type_index class is used in situations when RTTI is enabled, it is designed to be a drop-in
|
||||
/// replacement for C++11 std::type_index class.
|
||||
///
|
||||
/// When RTTI is disabled boost::template_index will be usually (some compilers allow calling typeid(T)
|
||||
/// even if RTTI is disabled) used instead of this class.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_index/type_info.hpp>
|
||||
|
||||
// MSVC is capable of calling typeid(T) even when RTTI is off
|
||||
#if (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
|
||||
|
||||
#if !defined(BOOST_NO_IOSTREAM)
|
||||
#if !defined(BOOST_NO_IOSFWD)
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
#else
|
||||
#include <ostream>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
/// This class is designed to be a drop-in replacement for C++11 std::type_index class.
|
||||
///
|
||||
/// Copyable std::type_index class that requires RTTI.
|
||||
/// When RTTI is disabled boost::template_index will be used instead of
|
||||
/// this class.
|
||||
class type_index {
|
||||
private:
|
||||
const type_info* pinfo_;
|
||||
|
||||
public:
|
||||
typedef detail::stl_type_info stl_type_info;
|
||||
|
||||
/// Default constructor.
|
||||
type_index() BOOST_NOEXCEPT
|
||||
: pinfo_(static_cast<const type_info*>(&typeid(void)))
|
||||
{}
|
||||
|
||||
/// Constructs type_index from an instance of boost::type_info.
|
||||
type_index(const type_info& inf) BOOST_NOEXCEPT
|
||||
: pinfo_(&inf)
|
||||
{}
|
||||
|
||||
/// Constructs type_index from an instance of std::type_info.
|
||||
type_index(const stl_type_info& inf) BOOST_NOEXCEPT
|
||||
: pinfo_(static_cast<const type_info*>(&inf))
|
||||
{}
|
||||
|
||||
/// Returns true if the type precedes the type of rhs in the collation order.
|
||||
/// The collation order is just an internal order.
|
||||
bool before(type_index const& rhs) const BOOST_NOEXCEPT {
|
||||
return pinfo_->before(*rhs.pinfo_);
|
||||
}
|
||||
|
||||
/// Returns raw name
|
||||
const char* name() const BOOST_NOEXCEPT {
|
||||
return pinfo_->name();
|
||||
}
|
||||
|
||||
/// Returns user-friendly name
|
||||
std::string name_demangled() const {
|
||||
return pinfo_->name_demangled();
|
||||
}
|
||||
|
||||
bool operator == (type_index const& rhs) const BOOST_NOEXCEPT {
|
||||
return *pinfo_ == *rhs.pinfo_;
|
||||
}
|
||||
|
||||
bool operator != (type_index const& rhs) const BOOST_NOEXCEPT {
|
||||
return !(*pinfo_ == *rhs.pinfo_);
|
||||
}
|
||||
|
||||
bool operator < (type_index const& rhs) const BOOST_NOEXCEPT {
|
||||
return before(rhs);
|
||||
}
|
||||
|
||||
bool operator > (type_index const& rhs) const BOOST_NOEXCEPT {
|
||||
return (rhs < *this);
|
||||
}
|
||||
|
||||
bool operator <= (type_index const& rhs) const BOOST_NOEXCEPT {
|
||||
return !(*this > rhs);
|
||||
}
|
||||
|
||||
bool operator >= (type_index const& rhs) const BOOST_NOEXCEPT {
|
||||
return !(*this < rhs);
|
||||
}
|
||||
|
||||
|
||||
bool operator == (stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return *this == type_index(rhs);
|
||||
}
|
||||
|
||||
bool operator != (stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return *this != type_index(rhs);
|
||||
}
|
||||
|
||||
bool operator < (stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return *this < type_index(rhs);
|
||||
}
|
||||
|
||||
bool operator > (stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return *this > type_index(rhs);
|
||||
}
|
||||
|
||||
bool operator <= (stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return *this <= type_index(rhs);
|
||||
}
|
||||
|
||||
bool operator >= (stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return *this >= type_index(rhs);
|
||||
}
|
||||
|
||||
|
||||
/// Function for getting hash value
|
||||
std::size_t hash_code() const BOOST_NOEXCEPT {
|
||||
return pinfo_->hash_code();
|
||||
}
|
||||
};
|
||||
|
||||
/* *************** type_index free functions ******************* */
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_DOXYGEN_INVOKED
|
||||
|
||||
inline bool operator == (detail::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT {
|
||||
return rhs == lhs; // Operation is commutative
|
||||
}
|
||||
|
||||
inline bool operator != (detail::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT {
|
||||
return rhs != lhs; // Operation is commutative
|
||||
}
|
||||
|
||||
inline bool operator < (detail::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT {
|
||||
return rhs > lhs;
|
||||
}
|
||||
|
||||
inline bool operator > (detail::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT {
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
inline bool operator <= (detail::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT {
|
||||
return rhs >= lhs;
|
||||
}
|
||||
|
||||
inline bool operator >= (detail::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT {
|
||||
return rhs <= lhs;
|
||||
}
|
||||
|
||||
#else // BOOST_TYPE_INDEX_DOXYGEN_INVOKED
|
||||
|
||||
inline bool operator == (std::type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT;
|
||||
inline bool operator != (std::type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT;
|
||||
inline bool operator < (std::type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT;
|
||||
inline bool operator > (std::type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT;
|
||||
inline bool operator <= (std::type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT;
|
||||
inline bool operator >= (std::type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT;
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_DOXYGEN_INVOKED
|
||||
|
||||
/* *************** type_index free functions ******************* */
|
||||
|
||||
#ifndef BOOST_NO_IOSTREAM
|
||||
#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
|
||||
|
||||
/// Ostream operator that will output demangled name.
|
||||
inline std::ostream& operator<<(std::ostream& ostr, type_index const& ind) {
|
||||
ostr << ind.name_demangled();
|
||||
return ostr;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/// Ostream operator that will output demangled name.
|
||||
template <class CharT, class TriatT>
|
||||
inline std::basic_ostream<CharT, TriatT>& operator<<(std::basic_ostream<CharT, TriatT>& ostr, type_index const& ind) {
|
||||
ostr << ind.name_demangled();
|
||||
return ostr;
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
|
||||
#endif // BOOST_NO_IOSTREAM
|
||||
|
||||
/// hash_value function overload for type_index.
|
||||
inline std::size_t hash_value(type_index const& v) BOOST_NOEXCEPT {
|
||||
return v.hash_code();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else // (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
|
||||
|
||||
#include <boost/type_index/template_index.hpp>
|
||||
namespace boost {
|
||||
|
||||
typedef template_index type_index;
|
||||
|
||||
}
|
||||
|
||||
#endif // (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_TYPE_INDEX_HPP
|
||||
|
@ -1,373 +0,0 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2013.
|
||||
//
|
||||
//
|
||||
// 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_TYPE_INFO_HPP
|
||||
#define BOOST_TYPE_INDEX_TYPE_INFO_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/// \file type_info.hpp
|
||||
/// \brief Contains implementation of boost::type_info class.
|
||||
///
|
||||
/// boost::type_info class can be used as a drop-in replacement for std::type_info, but unlike std::type_info
|
||||
/// this class has a name_demangled() function for getting human-readable type names.
|
||||
///
|
||||
/// boost::type_info class is used in situations when RTTI is enabled.
|
||||
/// When RTTI is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro is defined boost::template_info
|
||||
/// is usually used instead of it (some compilers allow calling typeid(T)
|
||||
/// even if RTTI is disabled, those copilers will continue to use boost::type_info class).
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
|
||||
// MSVC is capable of calling typeid(T) even when RTTI is off
|
||||
#if (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_arithmetic.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/detail/no_exceptions_support.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
/// @cond
|
||||
|
||||
// for this compiler at least, cross-shared-library type_info
|
||||
// comparisons don't work, so we are using typeid(x).name() instead.
|
||||
# if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))) \
|
||||
|| defined(_AIX) \
|
||||
|| (defined(__sgi) && defined(__host_mips)) \
|
||||
|| (defined(__hpux) && defined(__HP_aCC)) \
|
||||
|| (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
|
||||
# define BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
# endif
|
||||
|
||||
/// @endcond
|
||||
|
||||
namespace detail {
|
||||
#ifdef BOOST_NO_STD_TYPEINFO
|
||||
typedef type_info stl_type_info;
|
||||
#else
|
||||
typedef std::type_info stl_type_info;
|
||||
#endif
|
||||
|
||||
template <class T> class cvr_saver{};
|
||||
}
|
||||
|
||||
/// boost::type_info is a class that can be used as a drop-in replacement for std::type_info.
|
||||
///
|
||||
/// boost::type_info class is used in situations when RTTI is enabled.
|
||||
/// When RTTI is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro is defined boost::template_info
|
||||
/// is used instead of it.
|
||||
///
|
||||
/// Unlike std::type_info this class:
|
||||
/// * has a name_demangled() function for getting human-readable type names
|
||||
/// * name() function always noexcept and returns simple mangled name as character a character array
|
||||
/// * contains workarounds for some compiler issues
|
||||
///
|
||||
/// boost::type_info is not copyable and is not default constructible. Use boost::type_id* functions
|
||||
/// to get const references to instances of boost::type_info objects.
|
||||
class type_info: public detail::stl_type_info {
|
||||
#ifndef BOOST_NO_DELETED_FUNCTIONS
|
||||
type_info() = delete;
|
||||
type_info(const type_info&) = delete;
|
||||
#else
|
||||
type_info();
|
||||
type_info(const type_info&);
|
||||
#endif
|
||||
public:
|
||||
typedef detail::stl_type_info stl_type_info;
|
||||
|
||||
/// Factory method for constructing boost::type_info instance for type T.
|
||||
/// Strips const, volatile and & modifiers from T.
|
||||
///
|
||||
/// Works exactly like boost::type_id().
|
||||
template <class T>
|
||||
static const boost::type_info& construct() 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;
|
||||
|
||||
# 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.");
|
||||
#endif
|
||||
|
||||
return static_cast<const boost::type_info&>(typeid(no_cvr_t));
|
||||
}
|
||||
|
||||
/// Factory method for constructing boost::type_info instance for type T.
|
||||
/// Does not strip const, volatile, & and && modifiers from T.
|
||||
/// If T has no const, volatile, & and && modifiers, then returns exactly
|
||||
/// the same result as in case of calling `construct<T>()`.
|
||||
///
|
||||
/// Works exactly like boost::type_id_with_cvr().
|
||||
template <class T>
|
||||
static const boost::type_info& construct_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,
|
||||
detail::cvr_saver<T>,
|
||||
T
|
||||
>::type type;
|
||||
|
||||
return static_cast<const boost::type_info&>(typeid(type));
|
||||
}
|
||||
|
||||
/// Factory function, that works exactly like C++ typeid(rtti_val) call, but returns boost::type_info.
|
||||
/// This method available only with RTTI enabled.
|
||||
///
|
||||
/// Same as boost::type_id_rtti_only().
|
||||
template <class T>
|
||||
static const type_info& construct_rtti_only(T& rtti_val) BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_NO_RTTI
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false,
|
||||
"boost::type_id_rtti_only(T&) and boost::type_info::construct_rtti_only(T&) require RTTI");
|
||||
#endif
|
||||
return static_cast<const boost::type_info&>(typeid(rtti_val));
|
||||
}
|
||||
|
||||
/// Factory function, that works exactly like C++ typeid(rtti_val) call, but returns boost::type_info.
|
||||
/// This method available only with RTTI enabled.
|
||||
///
|
||||
/// Same as boost::type_id_rtti_only().
|
||||
template <class T>
|
||||
static const type_info& construct_rtti_only(T* rtti_val) {
|
||||
#ifdef BOOST_NO_RTTI
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false,
|
||||
"boost::type_id_rtti_only(T*) and boost::type_info::construct_rtti_only(T*) require RTTI");
|
||||
#endif
|
||||
return static_cast<const boost::type_info&>(typeid(rtti_val));
|
||||
}
|
||||
|
||||
/// Returns mangled type name.
|
||||
const char* name() const BOOST_NOEXCEPT {
|
||||
#ifdef _MSC_VER
|
||||
return stl_type_info::raw_name();
|
||||
#else
|
||||
return stl_type_info::name();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Returns user-friendly name
|
||||
std::string name_demangled() const {
|
||||
#if defined(_MSC_VER)
|
||||
std::string ret = stl_type_info::name();
|
||||
#else
|
||||
std::string ret;
|
||||
int status = 0;
|
||||
char* demang = abi::__cxa_demangle(name(), NULL, 0, &status);
|
||||
BOOST_ASSERT(!status);
|
||||
|
||||
BOOST_TRY {
|
||||
ret = demang; // may throw out of memory exception
|
||||
} BOOST_CATCH (...) {
|
||||
free(demang);
|
||||
BOOST_RETHROW;
|
||||
} BOOST_CATCH_END
|
||||
|
||||
free(demang);
|
||||
#endif
|
||||
std::string::size_type pos = ret.find("boost::detail::cvr_saver<");
|
||||
if (pos == std::string::npos) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pos += sizeof("boost::detail::cvr_saver<") - 1;
|
||||
while (ret[pos] == ' ') {
|
||||
++ pos;
|
||||
}
|
||||
std::string::size_type end = ret.rfind(">");
|
||||
BOOST_ASSERT(end != std::string::npos);
|
||||
while (ret[end - 1] == ' ') {
|
||||
-- end;
|
||||
}
|
||||
|
||||
return ret.substr(pos, end - pos);
|
||||
}
|
||||
|
||||
bool operator == (type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
return name() == rhs.name() || !std::strcmp(name(), rhs.name());
|
||||
#else
|
||||
return static_cast<const stl_type_info&>(*this) == static_cast<const stl_type_info&>(rhs);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool operator != (type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
bool operator == (stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return *this == static_cast<const boost::type_info&>(rhs);
|
||||
}
|
||||
|
||||
bool operator != (stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
/// Returns true if the type precedes the type of rhs in the collation order.
|
||||
/// The collation order is just an internal order.
|
||||
/// Works exactly like operator <
|
||||
bool before(type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
return name() != rhs.name() && std::strcmp(name(), rhs.name()) < 0;
|
||||
#else
|
||||
return !!stl_type_info::before(rhs);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Returns true if the type precedes the type of rhs in the collation order.
|
||||
/// The collation order is just an internal order.
|
||||
/// Works exactly like operator <
|
||||
bool before(stl_type_info const& rhs) const BOOST_NOEXCEPT {
|
||||
return before(static_cast<const boost::type_info&>(rhs));
|
||||
}
|
||||
|
||||
/// Function for getting hash value
|
||||
std::size_t hash_code() const BOOST_NOEXCEPT {
|
||||
#if _MSC_VER > 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||
return stl_type_info::hash_code();
|
||||
#else
|
||||
return boost::hash_range(name(), name() + std::strlen(name()));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
#undef BOOST_CLASSINFO_COMPARE_BY_NAMES
|
||||
#endif
|
||||
|
||||
/// Function to get boost::type_info for a type T.
|
||||
/// Strips const, volatile and & modifiers from T.
|
||||
template <class T>
|
||||
inline const type_info& type_id() BOOST_NOEXCEPT {
|
||||
return type_info::construct<T>();
|
||||
}
|
||||
|
||||
/// Function for constructing boost::type_info instance for type T.
|
||||
/// Does not strip const, volatile, & and && modifiers from T.
|
||||
/// If T has no const, volatile, & and && modifiers, then returns exactly
|
||||
/// the same result as in case of calling `type_id<T>()`.
|
||||
template <class T>
|
||||
inline const type_info& type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
return type_info::construct_with_cvr<T>();
|
||||
}
|
||||
|
||||
/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_info.
|
||||
/// This method available only with RTTI enabled. Without RTTI support it won't compile,
|
||||
/// producing a compile-time error with message: "boost::type_id_rtti_only(T&) requires RTTI"
|
||||
template <class T>
|
||||
inline const type_info& type_id_rtti_only(T& rtti_val) BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_NO_RTTI
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false, "boost::type_id_rtti_only(T&) requires RTTI");
|
||||
#endif
|
||||
return static_cast<const type_info&>(typeid(rtti_val));
|
||||
}
|
||||
|
||||
/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_info.
|
||||
/// This method available only with RTTI enabled. Without RTTI support it won't compile,
|
||||
/// producing a compile-time error with message: "boost::type_id_rtti_only(T*) requires RTTI"
|
||||
template <class T>
|
||||
inline const type_info& type_id_rtti_only(T* rtti_val) {
|
||||
#ifdef BOOST_NO_RTTI
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false, "boost::type_id_rtti_only(T*) requires RTTI");
|
||||
#endif
|
||||
return static_cast<const type_info&>(typeid(rtti_val));
|
||||
}
|
||||
|
||||
/* *************** type_info free functions ******************* */
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_DOXYGEN_INVOKED
|
||||
|
||||
inline bool operator == (detail::stl_type_info const& lhs, type_info const& rhs) BOOST_NOEXCEPT {
|
||||
return rhs == static_cast<const boost::type_info&>(lhs);
|
||||
}
|
||||
|
||||
inline bool operator != (detail::stl_type_info const& lhs, type_info const& rhs) BOOST_NOEXCEPT {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
#else // BOOST_TYPE_INDEX_DOXYGEN_INVOKED
|
||||
|
||||
inline bool operator == (std::type_info const& lhs, type_info const& rhs) BOOST_NOEXCEPT;
|
||||
inline bool operator != (std::type_info const& lhs, type_info const& rhs) BOOST_NOEXCEPT;
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_DOXYGEN_INVOKED
|
||||
|
||||
/// hash_value function overload for boost::type_info.
|
||||
inline std::size_t hash_value(type_info const& v) BOOST_NOEXCEPT {
|
||||
return v.hash_code();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else // !defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)
|
||||
# include <boost/type_index/template_info.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
typedef template_info type_info;
|
||||
|
||||
template <class T>
|
||||
inline const type_info& type_id() BOOST_NOEXCEPT {
|
||||
return template_info::construct<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline const type_info& type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
return template_info::construct_with_cvr<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline const type_info& type_id_rtti_only(T& rtti_val) BOOST_NOEXCEPT {
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false, "boost::type_id_rtti_only(T&) requires RTTI");
|
||||
return template_info::construct_with_cvr<void>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline const type_info& type_id_rtti_only(T* rtti_val) {
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false, "boost::type_id_rtti_only(T*) requires RTTI");
|
||||
return template_info::construct_with_cvr<void>();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined (BOOST_MSVC)
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
/// \def BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
|
||||
/// Define the BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro if you are mixing objects
|
||||
/// compiled with different RTTI flags. This will force the usage of boost::template_index
|
||||
/// class instead of boost::type_index.
|
||||
#define BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
|
||||
#endif // BOOST_TYPE_INDEX_DOXYGEN_INVOKED
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_TYPE_INFO_HPP
|
||||
|
@ -1,44 +0,0 @@
|
||||
Index: trunk/boost/test/execution_monitor.hpp
|
||||
===================================================================
|
||||
--- trunk/boost/test/execution_monitor.hpp (revision 86235)
|
||||
+++ trunk/boost/test/execution_monitor.hpp (working copy)
|
||||
@@ -261,7 +261,7 @@
|
||||
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:
|
||||
Index: trunk/boost/test/tree/test_case_template.hpp
|
||||
===================================================================
|
||||
--- trunk/boost/test/tree/test_case_template.hpp (revision 86235)
|
||||
+++ trunk/boost/test/tree/test_case_template.hpp (working copy)
|
||||
@@ -34,8 +34,13 @@
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/function/function0.hpp>
|
||||
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
+#include <typeinfo> // for typeid
|
||||
+#else
|
||||
+#include <boost/current_function.hpp>
|
||||
+#endif
|
||||
+
|
||||
// STL
|
||||
-#include <typeinfo> // for typeid
|
||||
#include <string> // for std::string
|
||||
#include <list> // for std::list
|
||||
|
||||
@@ -77,7 +82,11 @@
|
||||
std::string full_name;
|
||||
assign_op( full_name, m_test_case_name, 0 );
|
||||
full_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,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 ;
|
483
doc/type_index.qbk
Normal file
483
doc/type_index.qbk
Normal file
@ -0,0 +1,483 @@
|
||||
[library Boost.TypeIndex
|
||||
[quickbook 1.6]
|
||||
[version 4.1]
|
||||
[copyright 2012-2022 Antony Polukhin]
|
||||
[category Language Features Emulation]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
[@http://www.boost.org/LICENSE_1_0.txt])
|
||||
]
|
||||
]
|
||||
|
||||
[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, which is where problems start:
|
||||
|
||||
* `typeid(T)` and `std::type_index` require Run Time Type Info (RTTI)
|
||||
* 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
|
||||
* no nice and portable way to get human readable type names
|
||||
* no way to easily make your own type info class
|
||||
|
||||
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>` ]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Getting started]
|
||||
|
||||
[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.
|
||||
|
||||
[section How to use]
|
||||
|
||||
To start using Boost.TypeIndex:
|
||||
|
||||
[table:porting
|
||||
[[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
|
||||
``][``
|
||||
boost::typeindex::type_index
|
||||
``][
|
||||
[classref boost::typeindex::type_index more... ]
|
||||
]]
|
||||
|
||||
[[``
|
||||
typeid(T)
|
||||
typeid(T).name() // not human readable
|
||||
typeid(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... ]
|
||||
]]
|
||||
|
||||
[[``
|
||||
// attempt to save const, volatile, reference
|
||||
typeid(please_save_modifiers<T>)
|
||||
``][``
|
||||
// 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 [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]
|
||||
|
||||
[section Example with Boost.Any]
|
||||
|
||||
Here is how TypeIndex could be used in `boost/any.hpp`:
|
||||
[table:any
|
||||
[[Before] [With TypeIndex]]
|
||||
[[``#include <typeinfo>``][``#include <boost/type_index.hpp>``]]
|
||||
[[``
|
||||
virtual const std::type_info & type() const BOOST_NOEXCEPT
|
||||
{
|
||||
// requires RTTI
|
||||
return typeid(ValueType);
|
||||
}
|
||||
``] [``
|
||||
virtual const boost::typeindex::type_info & type() const BOOST_NOEXCEPT
|
||||
{
|
||||
// now works even with RTTI disabled
|
||||
return boost::typeindex::type_id<ValueType>().type_info();
|
||||
}
|
||||
``]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Example with Boost.Variant]
|
||||
|
||||
Here is how TypeIndex could be used in `boost/variant/variant.hpp`:
|
||||
[table:variant
|
||||
[[Before] [With TypeIndex]]
|
||||
|
||||
[[``
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
#include <typeinfo> // for typeid, std::type_info
|
||||
#endif // BOOST_NO_TYPEID
|
||||
``][``
|
||||
#include <boost/type_index.hpp>
|
||||
``]]
|
||||
[[``
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
|
||||
class reflect
|
||||
: public static_visitor<const std::type_info&>
|
||||
{
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename T>
|
||||
const std::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
{
|
||||
return typeid(T);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_TYPEID
|
||||
``][``
|
||||
class reflect
|
||||
: public static_visitor<const boost::typeindex::type_info&>
|
||||
{
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename T>
|
||||
const boost::typeindex::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::typeindex::type_id<T>().type_info();
|
||||
}
|
||||
|
||||
};
|
||||
``]]
|
||||
[[``
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
const std::type_info& type() const
|
||||
{
|
||||
detail::variant::reflect visitor;
|
||||
return this->apply_visitor(visitor);
|
||||
}
|
||||
#endif
|
||||
``] [``
|
||||
const boost::typeindex::type_info& type() const
|
||||
{
|
||||
detail::variant::reflect visitor;
|
||||
return this->apply_visitor(visitor);
|
||||
}
|
||||
``]]
|
||||
]
|
||||
|
||||
[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 [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 `stl_type_index` will be used.
|
||||
|
||||
[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]
|
||||
|
||||
[import ../examples/demangled_names.cpp]
|
||||
[section Getting human readable and mangled type names] [type_index_names_example] [endsect]
|
||||
|
||||
[import ../examples/registry.cpp]
|
||||
[section Storing information about a type in container ] [type_index_registry_example] [endsect]
|
||||
|
||||
[import ../examples/inheritance.cpp]
|
||||
[section Getting through the inheritance to receive a real type name ] [type_index_derived_example] [endsect]
|
||||
|
||||
[import ../examples/runtime_cast.cpp]
|
||||
[section Using runtime_cast where RTTI is unavailable or undesirable ] [type_index_runtime_cast_example] [endsect]
|
||||
|
||||
[import ../examples/exact_types_match.cpp]
|
||||
[section Exact type matching: storing type with const, volatile and reference qualifiers] [type_index_exact_type_match_example] [endsect]
|
||||
|
||||
[import ../examples/table_of_names.cpp]
|
||||
[section Table of raw_name() and pretty_name() outputs with and without RTTI ] [type_index_names_table] [endsect]
|
||||
|
||||
[import ../examples/constexpr14_namespace_check.cpp]
|
||||
[section C++14: Checking namespace at compile time ] [type_index_constexpr14_namespace_example] [endsect]
|
||||
|
||||
[import ../examples/constexpr14_sort_check.cpp]
|
||||
[section C++14: Checking lexigraphical order of provided types ] [type_index_constexpr14_sort_check_example] [endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[xinclude autodoc.xml]
|
||||
|
||||
[section Making a custom type_index]
|
||||
|
||||
Sometimes there may be a need to create your own type info system. This may be 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]
|
||||
|
||||
[section Basics]
|
||||
[type_index_userdefined_usertypes]
|
||||
[type_index_userdefined_enum]
|
||||
[type_index_my_type_index]
|
||||
[type_index_my_type_index_usage]
|
||||
[endsect]
|
||||
|
||||
[section Getting type infos at runtime]
|
||||
[type_index_my_type_index_register_class]
|
||||
[type_index_my_type_index_type_id_runtime_implmentation]
|
||||
[type_index_my_type_index_type_id_runtime_classes]
|
||||
[type_index_my_type_index_type_id_runtime_test]
|
||||
[endsect]
|
||||
|
||||
[section Using new type infos all around the code]
|
||||
[type_index_my_type_index_worldwide_macro]
|
||||
[type_index_my_type_index_worldwide_typedefs]
|
||||
[type_index_my_type_index_worldwide_usage]
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Space and Performance]
|
||||
|
||||
* `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.
|
||||
* 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 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::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.
|
||||
|
||||
This leads to big strings in binary file:
|
||||
```
|
||||
static const char* boost::detail::ctti<T>::n() [with T = int]
|
||||
static const char* boost::detail::ctti<T>::n() [with T = user_defined_type]
|
||||
```
|
||||
While using RTTI, you'll get the following (more compact) string in binary file:
|
||||
|
||||
```
|
||||
i
|
||||
17user_defined_type
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section RTTI emulation limitations]
|
||||
|
||||
TypeIndex has been tested and successfully work on many compilers.
|
||||
|
||||
[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
|
||||
parameters provided to `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` macro.
|
||||
|
||||
|
||||
Consider the following example:
|
||||
|
||||
`boost::typeindex::ctti_type_index::type_id<int>().raw_name()` returns
|
||||
"const char *__cdecl boost::detail::ctti<int>::n(void)". Then you shall set
|
||||
`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]
|
||||
|
||||
[section Mixing sources with RTTI on and RTTI off]
|
||||
|
||||
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 [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 ]
|
||||
|
||||
You must know that linking RTTI on and RTTI off binaries may succeed even without defining the
|
||||
`BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` macro, but that does not mean that you'll get a
|
||||
working binary. Such actions may break the One Definition Rule. Take a look at the table below,
|
||||
that shows how the `boost::type_index get_integer();` function will look like with different
|
||||
RTTI flags:
|
||||
|
||||
[table:diffs
|
||||
[[RTTI on] [RTTI off]]
|
||||
[[`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.
|
||||
|
||||
[warning
|
||||
Even with `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` defined there is no guarantee
|
||||
that everything will be OK. Libraries that use their own workarounds for disabled RTTI
|
||||
may fail to link or to work correctly.
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Acknowledgements]
|
||||
|
||||
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
|
||||
|
76
examples/demangled_names.cpp
Normal file
76
examples/demangled_names.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>.)
|
||||
|
||||
|
||||
//[type_index_names_example
|
||||
/*`
|
||||
The following example shows how short (mangled) and human readable type names could be obtained from a type.
|
||||
Works with and without RTTI.
|
||||
*/
|
||||
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
void foo(T) {
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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 Antony Polukhin
|
||||
// Copyright 2013-2022 Antony Polukhin
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See the accompanying file LICENSE_1_0.txt
|
||||
@ -6,33 +6,50 @@
|
||||
|
||||
//[type_index_exact_type_match_example
|
||||
/*`
|
||||
The following example shows that `boost::type_index` (and `boost::type_info`) is able to store the exact type,
|
||||
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 initaily 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/type_index.hpp>
|
||||
#include <boost/type_index.hpp>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
|
||||
//<-
|
||||
// Making `#include <cassert>` visible in docs, while actually using hand-made check
|
||||
// instead of `assert`. This is required to verify correct behavior even if NDEBUG
|
||||
// is defined and to avoid `unused local variable` warnings with defined NDEBUG.
|
||||
//
|
||||
// boost-no-inspect
|
||||
#ifdef assert
|
||||
# undef assert
|
||||
#endif
|
||||
#define assert(X) if (!(X)) std::exit(__LINE__)
|
||||
/* !Comment block is not closed intentionaly!
|
||||
//->
|
||||
#include <cassert>
|
||||
//<-
|
||||
!Closing comment block! */
|
||||
//->
|
||||
|
||||
class type_erased_unary_function {
|
||||
void* function_ptr_;
|
||||
boost::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_(boost::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_ != boost::type_id_with_cvr<ParamT>()) {
|
||||
if (exact_param_t_ != boost::typeindex::type_id_with_cvr<ParamT>()) {
|
||||
throw std::runtime_error("Incorrect `ParamT`");
|
||||
}
|
||||
|
||||
@ -50,7 +67,7 @@ int main() {
|
||||
int i = 100;
|
||||
|
||||
// An attempt to convert stored function to a function accepting reference
|
||||
func.call<int&>(i); // Will throw, because types `int&` and `int` missmatch
|
||||
func.call<int&>(i); // Will throw, because types `int&` and `int` mismatch
|
||||
|
||||
assert(false);
|
||||
} catch (const std::runtime_error& /*e*/) {}
|
47
examples/inheritance.cpp
Normal file
47
examples/inheritance.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
// 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_derived_example
|
||||
/*`
|
||||
The following example shows that `type_info` is able to store the real type, successfully getting through
|
||||
all the inheritances.
|
||||
|
||||
Example works with and without RTTI."
|
||||
*/
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/type_index/runtime_cast/register_runtime_class.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct A {
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
virtual ~A(){}
|
||||
};
|
||||
struct B: public A { BOOST_TYPE_INDEX_REGISTER_CLASS };
|
||||
struct C: public B { BOOST_TYPE_INDEX_REGISTER_CLASS };
|
||||
struct D: public C { BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS) };
|
||||
|
||||
void print_real_type(const A& a) {
|
||||
std::cout << boost::typeindex::type_id_runtime(a).pretty_name() << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
C c;
|
||||
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]
|
55
examples/registry.cpp
Normal file
55
examples/registry.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
// 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_registry_example
|
||||
/*`
|
||||
The following example shows how an information about a type could be stored.
|
||||
Example works with and without RTTI.
|
||||
*/
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/unordered/unordered_set.hpp>
|
||||
//<-
|
||||
// Making `#include <cassert>` visible in docs, while actually using `BOOST_TEST`
|
||||
// instead of `assert`. This is required to verify correct behavior even if NDEBUG
|
||||
// is defined and to avoid `unused local variable` warnings with defined NDEBUG.
|
||||
//
|
||||
// boost-no-inspect
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#ifdef assert
|
||||
# undef assert
|
||||
#endif
|
||||
#define assert(X) BOOST_TEST(X)
|
||||
/* !Comment block is not closed intentionaly!
|
||||
//->
|
||||
#include <cassert>
|
||||
//<-
|
||||
!Closing comment block! */
|
||||
//->
|
||||
|
||||
int main() {
|
||||
boost::unordered_set<boost::typeindex::type_index> types;
|
||||
|
||||
// Storing some `boost::type_info`s
|
||||
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(boost::typeindex::type_id<const int>()).second;
|
||||
assert(!is_inserted);
|
||||
assert(types.erase(boost::typeindex::type_id<float&>()) == 1);
|
||||
|
||||
// We have erased the `float` type, only `int` remains
|
||||
assert(*types.begin() == boost::typeindex::type_id<int>());
|
||||
//<-
|
||||
return boost::report_errors();
|
||||
//->
|
||||
}
|
||||
|
||||
//] [/type_index_registry_example]
|
90
examples/runtime_cast.cpp
Normal file
90
examples/runtime_cast.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright (c) Chris Glover, 2016.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
//[type_index_runtime_cast_example
|
||||
/*`
|
||||
The following example shows that `runtime_cast` is able to find a valid pointer
|
||||
in various class hierarchies regardless of inheritance or type relation.
|
||||
|
||||
Example works with and without RTTI."
|
||||
*/
|
||||
|
||||
#include <boost/type_index/runtime_cast.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct A {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
virtual ~A()
|
||||
{}
|
||||
};
|
||||
|
||||
struct B {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
|
||||
virtual ~B()
|
||||
{}
|
||||
};
|
||||
|
||||
struct C : A {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((A))
|
||||
};
|
||||
|
||||
struct D : B {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((B))
|
||||
};
|
||||
|
||||
struct E : C, D {
|
||||
BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((C)(D))
|
||||
};
|
||||
|
||||
int main() {
|
||||
C c;
|
||||
A* a = &c;
|
||||
|
||||
if(C* cp = boost::typeindex::runtime_cast<C*>(a)) {
|
||||
std::cout << "Yes, a points to a C: "
|
||||
<< a << "->" << cp << '\n';
|
||||
}
|
||||
else {
|
||||
std::cout << "Error: Expected a to point to a C" << '\n';
|
||||
}
|
||||
|
||||
if(E* ce = boost::typeindex::runtime_cast<E*>(a)) {
|
||||
std::cout << "Error: Expected a to not points to an E: "
|
||||
<< a << "->" << ce << '\n';
|
||||
}
|
||||
else {
|
||||
std::cout << "But, a does not point to an E" << '\n';
|
||||
}
|
||||
|
||||
E e;
|
||||
C* cp2 = &e;
|
||||
if(D* dp = boost::typeindex::runtime_cast<D*>(cp2)) {
|
||||
std::cout << "Yes, we can cross-cast from a C* to a D* when we actually have an E: "
|
||||
<< cp2 << "->" << dp << '\n';
|
||||
}
|
||||
else {
|
||||
std::cout << "Error: Expected cp to point to a D" << '\n';
|
||||
}
|
||||
|
||||
/*`
|
||||
Alternatively, we can use runtime_pointer_cast so we don't need to specity the target as a pointer.
|
||||
This works for smart_ptr types too.
|
||||
*/
|
||||
A* ap = &e;
|
||||
if(B* bp = boost::typeindex::runtime_pointer_cast<B>(ap)) {
|
||||
std::cout << "Yes, we can cross-cast and up-cast at the same time."
|
||||
<< ap << "->" << bp << '\n';
|
||||
}
|
||||
else {
|
||||
std::cout << "Error: Expected ap to point to a B" << '\n';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//] [/type_index_runtime_cast_example]
|
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]
|
73
examples/user_defined_typeinfo.cpp
Normal file
73
examples/user_defined_typeinfo.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
// 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_my_type_index_worldwide_macro
|
||||
/*`
|
||||
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:
|
||||
*/
|
||||
|
||||
// BOOST_TYPE_INDEX_USER_TYPEINDEX must be defined *BEFORE* first inclusion of <boost/type_index.hpp>
|
||||
#define BOOST_TYPE_INDEX_USER_TYPEINDEX <boost/../libs/type_index/examples/user_defined_typeinfo.hpp>
|
||||
#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;
|
||||
|
||||
int main() {
|
||||
//[type_index_my_type_index_usage
|
||||
/*`
|
||||
Finally we can use the my_type_index class for getting type indexes:
|
||||
*/
|
||||
|
||||
my_type_index
|
||||
cl1 = my_type_index::type_id<my_class>(),
|
||||
st1 = my_type_index::type_id<my_struct>(),
|
||||
st2 = my_type_index::type_id<my_struct>(),
|
||||
vec = my_type_index::type_id<my_classes>()
|
||||
;
|
||||
|
||||
assert(cl1 != st1);
|
||||
assert(st2 == st1);
|
||||
assert(vec.pretty_name() == "my_classes");
|
||||
assert(cl1.pretty_name() == "my_class");
|
||||
|
||||
//] [/type_index_my_type_index_usage]
|
||||
|
||||
//[type_index_my_type_index_type_id_runtime_test
|
||||
/*`
|
||||
Now the following example will compile and work.
|
||||
*/
|
||||
my_struct str;
|
||||
my_class& reference = str;
|
||||
assert(my_type_index::type_id<my_struct>() == my_type_index::type_id_runtime(reference));
|
||||
//][/type_index_my_type_index_type_id_runtime_test]
|
||||
|
||||
//[type_index_my_type_index_worldwide_usage
|
||||
/*`
|
||||
That's it! Now all TypeIndex global methods and typedefs will be using your class:
|
||||
*/
|
||||
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();
|
||||
//->
|
||||
}
|
||||
|
||||
|
213
examples/user_defined_typeinfo.hpp
Normal file
213
examples/user_defined_typeinfo.hpp
Normal file
@ -0,0 +1,213 @@
|
||||
// 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>.)
|
||||
|
||||
#ifndef USER_DEFINED_TYPEINFO_HPP
|
||||
#define USER_DEFINED_TYPEINFO_HPP
|
||||
|
||||
//[type_index_userdefined_usertypes
|
||||
/*`
|
||||
The following example shows how a user defined type_info can be created and used.
|
||||
Example works with and without RTTI.
|
||||
|
||||
Consider situation when user uses only those types in `typeid()`:
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace my_namespace {
|
||||
|
||||
class my_class;
|
||||
struct my_struct;
|
||||
|
||||
typedef std::vector<my_class> my_classes;
|
||||
typedef std::string my_string;
|
||||
|
||||
} // namespace my_namespace
|
||||
|
||||
//] [/type_index_userdefined_usertypes]
|
||||
|
||||
|
||||
//[type_index_userdefined_enum
|
||||
/*`
|
||||
In that case user may wish to save space in binary and create it's own type system.
|
||||
For that case `detail::typenum<>` meta function is added. Depending on the input type T
|
||||
this function will return different numeric values.
|
||||
*/
|
||||
#include <boost/type_index/type_index_facade.hpp>
|
||||
|
||||
namespace my_namespace { namespace detail {
|
||||
template <class T> struct typenum;
|
||||
template <> struct typenum<void>{ enum {value = 0}; };
|
||||
template <> struct typenum<my_class>{ enum {value = 1}; };
|
||||
template <> struct typenum<my_struct>{ enum {value = 2}; };
|
||||
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"}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline const my_typeinfo& my_typeinfo_construct() {
|
||||
return infos[typenum<T>::value];
|
||||
}
|
||||
}} // my_namespace::detail
|
||||
|
||||
//] [/type_index_userdefined_usertypes]
|
||||
|
||||
|
||||
//[type_index_my_type_index
|
||||
/*`
|
||||
`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::typeindex::type_index_facade<my_type_index, detail::my_typeinfo> {
|
||||
const detail::my_typeinfo* data_;
|
||||
|
||||
public:
|
||||
typedef detail::my_typeinfo type_info_t;
|
||||
|
||||
inline my_type_index() BOOST_NOEXCEPT
|
||||
: data_(&detail::my_typeinfo_construct<void>())
|
||||
{}
|
||||
|
||||
inline my_type_index(const type_info_t& data) BOOST_NOEXCEPT
|
||||
: data_(&data)
|
||||
{}
|
||||
|
||||
inline const type_info_t& type_info() const BOOST_NOEXCEPT {
|
||||
return *data_;
|
||||
}
|
||||
|
||||
inline const char* raw_name() const BOOST_NOEXCEPT {
|
||||
return data_->type_;
|
||||
}
|
||||
|
||||
inline std::string pretty_name() const {
|
||||
return data_->type_;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline static my_type_index type_id() BOOST_NOEXCEPT {
|
||||
return detail::my_typeinfo_construct<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline static my_type_index type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
return detail::my_typeinfo_construct<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline static my_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
} // namespace my_namespace
|
||||
|
||||
/*`
|
||||
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).
|
||||
*/
|
||||
|
||||
//] [/type_index_my_type_index]
|
||||
|
||||
//[type_index_my_type_index_register_class
|
||||
/*`
|
||||
Usually to allow runtime type info we need to register class with some macro.
|
||||
Let's see how a `MY_TYPEINDEX_REGISTER_CLASS` macro could be implemented for our `my_type_index` class:
|
||||
*/
|
||||
namespace my_namespace { namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline const my_typeinfo& my_typeinfo_construct_ref(const T*) {
|
||||
return my_typeinfo_construct<T>();
|
||||
}
|
||||
|
||||
#define MY_TYPEINDEX_REGISTER_CLASS \
|
||||
virtual const my_namespace::detail::my_typeinfo& type_id_runtime() const { \
|
||||
return my_namespace::detail::my_typeinfo_construct_ref(this); \
|
||||
}
|
||||
|
||||
}} // namespace my_namespace::detail
|
||||
|
||||
//] [/type_index_my_type_index_register_class]
|
||||
|
||||
//[type_index_my_type_index_type_id_runtime_implmentation
|
||||
/*`
|
||||
Now when we have a MY_TYPEINDEX_REGISTER_CLASS, let's implement a `my_type_index::type_id_runtime` method:
|
||||
*/
|
||||
namespace my_namespace {
|
||||
template <class T>
|
||||
my_type_index my_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
|
||||
// Classes that were marked with `MY_TYPEINDEX_REGISTER_CLASS` will have a
|
||||
// `type_id_runtime()` method.
|
||||
return variable.type_id_runtime();
|
||||
}
|
||||
}
|
||||
//] [/type_index_my_type_index_type_id_runtime_implmentation]
|
||||
|
||||
//[type_index_my_type_index_type_id_runtime_classes
|
||||
/*`
|
||||
Consider the situation, when `my_class` and `my_struct` are polymorphic classes:
|
||||
*/
|
||||
|
||||
namespace my_namespace {
|
||||
|
||||
class my_class {
|
||||
public:
|
||||
MY_TYPEINDEX_REGISTER_CLASS
|
||||
virtual ~my_class() {}
|
||||
};
|
||||
|
||||
struct my_struct: public my_class {
|
||||
MY_TYPEINDEX_REGISTER_CLASS
|
||||
};
|
||||
|
||||
} // namespace my_namespace
|
||||
|
||||
//] [/type_index_my_type_index_type_id_runtime_classes]
|
||||
|
||||
|
||||
//[type_index_my_type_index_worldwide_typedefs
|
||||
/*`
|
||||
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 typeindex {
|
||||
typedef my_namespace::my_type_index type_index;
|
||||
}}
|
||||
//] [/type_index_my_type_index_worldwide_typedefs]
|
||||
|
||||
|
||||
#endif // USER_DEFINED_TYPEINFO_HPP
|
||||
|
265
include/boost/type_index.hpp
Normal file
265
include/boost/type_index.hpp
Normal file
@ -0,0 +1,265 @@
|
||||
//
|
||||
// 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_HPP
|
||||
#define BOOST_TYPE_INDEX_HPP
|
||||
|
||||
/// \file boost/type_index.hpp
|
||||
/// \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::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>
|
||||
# if defined(BOOST_NO_RTTI) || defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)
|
||||
# include <boost/type_index/detail/stl_register_class.hpp>
|
||||
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - typeid() is used only for templates")
|
||||
# endif
|
||||
# else
|
||||
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is used")
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# include <boost/type_index/ctti_type_index.hpp>
|
||||
# include <boost/type_index/detail/ctti_register_class.hpp>
|
||||
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
|
||||
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - using CTTI")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
#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::typeindex::type_index.
|
||||
///
|
||||
/// Could be a boost::typeindex::stl_type_index, boost::typeindex::ctti_type_index or
|
||||
/// user defined type_index class.
|
||||
///
|
||||
/// \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::typeindex::stl_type_index type_index;
|
||||
#else
|
||||
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::typeindex::type_info.
|
||||
///
|
||||
/// 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!
|
||||
typedef type_index::type_info_t type_info;
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_USER_TYPEINDEX
|
||||
/// BOOST_TYPE_INDEX_USER_TYPEINDEX can be defined to the path to header file
|
||||
/// with user provided implementation of type_index.
|
||||
///
|
||||
/// 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
|
||||
/// 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& boost_type_info_type_id_runtime_() const noexcept`.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
/// class A {
|
||||
/// public:
|
||||
/// BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
/// virtual ~A(){}
|
||||
/// };
|
||||
///
|
||||
/// struct B: public A {
|
||||
/// BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
/// };
|
||||
///
|
||||
/// struct C: public B {
|
||||
/// BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
/// };
|
||||
///
|
||||
/// ...
|
||||
///
|
||||
/// C c1;
|
||||
/// A* pc1 = &c1;
|
||||
/// 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](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::typeindex::type_index for a type T.
|
||||
/// Removes const, volatile && and & modifiers from T.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
/// type_index ti = type_id<int&>();
|
||||
/// std::cout << ti.pretty_name(); // Outputs 'int'
|
||||
/// \endcode
|
||||
///
|
||||
/// \tparam T Type for which type_index must be created.
|
||||
/// \throw Nothing.
|
||||
/// \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::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
|
||||
/// the same result as in case of calling `type_id<T>()`.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
/// type_index ti = type_id_with_cvr<int&>();
|
||||
/// std::cout << ti.pretty_name(); // Outputs 'int&'
|
||||
/// \endcode
|
||||
///
|
||||
/// \tparam T Type for which type_index must be created.
|
||||
/// \throw Nothing.
|
||||
/// \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>();
|
||||
}
|
||||
|
||||
/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index.
|
||||
///
|
||||
/// Returns runtime information about specified type.
|
||||
///
|
||||
/// \b Requirements: RTTI available or Base and Derived classes must be marked with BOOST_TYPE_INDEX_REGISTER_CLASS.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
/// struct Base { virtual ~Base(){} };
|
||||
/// struct Derived: public Base {};
|
||||
/// ...
|
||||
/// Derived d;
|
||||
/// Base& b = d;
|
||||
/// type_index ti = type_id_runtime(b);
|
||||
/// std::cout << ti.pretty_name(); // Outputs 'Derived'
|
||||
/// \endcode
|
||||
///
|
||||
/// \param runtime_val Variable which runtime type must be returned.
|
||||
/// \throw Nothing.
|
||||
/// \return boost::typeindex::type_index with information about the specified variable.
|
||||
template <class T>
|
||||
inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT {
|
||||
return type_index::type_id_runtime(runtime_val);
|
||||
}
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_HPP
|
||||
|
213
include/boost/type_index/ctti_type_index.hpp
Normal file
213
include/boost/type_index/ctti_type_index.hpp
Normal file
@ -0,0 +1,213 @@
|
||||
//
|
||||
// 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_TYPE_INDEX_HPP
|
||||
#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
|
||||
|
||||
/// \file ctti_type_index.hpp
|
||||
/// \brief Contains boost::typeindex::ctti_type_index class that is constexpr if C++14 constexpr is supported by compiler.
|
||||
///
|
||||
/// boost::typeindex::ctti_type_index class can be used as a drop-in replacement
|
||||
/// for std::type_index.
|
||||
///
|
||||
/// It is used in situations when typeid() method is not available or
|
||||
/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro is defined.
|
||||
|
||||
#include <boost/type_index/type_index_facade.hpp>
|
||||
#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>
|
||||
|
||||
#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 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 sure that user does not copy or
|
||||
// default construct `struct-that-represents-type`
|
||||
//
|
||||
// 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 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
|
||||
// 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
|
||||
// requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer
|
||||
// value.
|
||||
//
|
||||
// Alignments are checked in `type_index_test_ctti_alignment.cpp` test.
|
||||
return *reinterpret_cast<const detail::ctti_data*>(boost::detail::ctti<T>::n());
|
||||
}
|
||||
|
||||
/// \class ctti_type_index
|
||||
/// 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 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 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;
|
||||
|
||||
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_(reinterpret_cast<const char*>(&data))
|
||||
{}
|
||||
|
||||
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;
|
||||
|
||||
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>
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
inline const ctti_type_index::type_info_t& ctti_type_index::type_info() const BOOST_NOEXCEPT {
|
||||
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>
|
||||
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_type_index(boost::detail::ctti<no_cvr_t>::n());
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class 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.boost_type_index_type_id_runtime_();
|
||||
}
|
||||
|
||||
|
||||
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 = 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() + get_raw_name_length());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
|
||||
|
339
include/boost/type_index/detail/compile_time_type_info.hpp
Normal file
339
include/boost/type_index/detail/compile_time_type_info.hpp
Normal file
@ -0,0 +1,339 @@
|
||||
//
|
||||
// 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_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
|
||||
#define BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
|
||||
|
||||
/// \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
|
||||
|
||||
/// @cond
|
||||
#if defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_constant_p)
|
||||
#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
|
||||
#endif
|
||||
#if __has_builtin(__builtin_strcmp)
|
||||
#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2)
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
|
||||
#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2)
|
||||
#endif
|
||||
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(begin_skip, end_skip, runtime_skip, runtime_skip_until) \
|
||||
namespace boost { namespace typeindex { namespace detail { \
|
||||
BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_begin = begin_skip; \
|
||||
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 possible, to avoid code bloat
|
||||
template <class T>
|
||||
struct ctti {
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||
//helper functions
|
||||
template <unsigned int I>
|
||||
constexpr static char s() BOOST_NOEXCEPT { // step
|
||||
constexpr unsigned int offset =
|
||||
(I >= 10u ? 1u : 0u)
|
||||
+ (I >= 100u ? 1u : 0u)
|
||||
+ (I >= 1000u ? 1u : 0u)
|
||||
+ (I >= 10000u ? 1u : 0u)
|
||||
+ (I >= 100000u ? 1u : 0u)
|
||||
+ (I >= 1000000u ? 1u : 0u)
|
||||
;
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
return BOOST_TYPE_INDEX_FUNCTION_SIGNATURE[I + offset];
|
||||
#elif defined(__FUNCSIG__)
|
||||
return __FUNCSIG__[I + offset];
|
||||
#else
|
||||
return __PRETTY_FUNCTION__[I + offset];
|
||||
#endif
|
||||
}
|
||||
|
||||
template <unsigned int ...Indexes>
|
||||
constexpr static const char* impl(::boost::typeindex::detail::index_seq<Indexes...> ) BOOST_NOEXCEPT {
|
||||
return ::boost::typeindex::detail::cstring<s<Indexes>()...>::data_;
|
||||
}
|
||||
|
||||
template <unsigned int D = 0> // `D` means `Dummy`
|
||||
constexpr static const char* n() BOOST_NOEXCEPT {
|
||||
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
constexpr unsigned int size = sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
|
||||
#elif defined(__FUNCSIG__)
|
||||
constexpr unsigned int size = sizeof(__FUNCSIG__);
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
|| defined(__GNUC__) \
|
||||
|| (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
|
||||
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__)
|
||||
constexpr unsigned int size = sizeof(__PRETTY_FUNCTION__);
|
||||
#else
|
||||
boost::typeindex::detail::failed_to_get_function_name<T>();
|
||||
#endif
|
||||
|
||||
boost::typeindex::detail::assert_compile_time_legths<
|
||||
(size > boost::typeindex::detail::ctti_skip_size_at_begin + boost::typeindex::detail::ctti_skip_size_at_end + sizeof("const *") - 1)
|
||||
>();
|
||||
static_assert(!boost::typeindex::detail::ctti_skip_more_at_runtime, "Skipping for GCC in C++14 mode is unsupported");
|
||||
|
||||
typedef typename boost::typeindex::detail::make_index_seq_impl<
|
||||
boost::typeindex::detail::ctti_skip_size_at_begin,
|
||||
size - sizeof("const *") + 1 - boost::typeindex::detail::ctti_skip_size_at_begin
|
||||
>::type idx_seq;
|
||||
return impl(idx_seq());
|
||||
}
|
||||
#else
|
||||
/// Returns raw name. Must be as short, as possible, to avoid code bloat
|
||||
BOOST_CXX14_CONSTEXPR static const char* n() BOOST_NOEXCEPT {
|
||||
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
|
||||
#elif defined(__FUNCSIG__)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__);
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
|| defined(__GNUC__) \
|
||||
|| (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
|
||||
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__) \
|
||||
|| defined(__clang__)
|
||||
return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
|
||||
#else
|
||||
boost::typeindex::detail::failed_to_get_function_name<T>();
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
|
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
|
278
include/boost/type_index/stl_type_index.hpp
Normal file
278
include/boost/type_index/stl_type_index.hpp
Normal file
@ -0,0 +1,278 @@
|
||||
//
|
||||
// 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_TYPE_INDEX_HPP
|
||||
#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
|
||||
|
||||
/// \file stl_type_index.hpp
|
||||
/// \brief Contains boost::typeindex::stl_type_index class.
|
||||
///
|
||||
/// 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::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, 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>
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER > 1600) \
|
||||
|| (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) \
|
||||
|| (defined(__GNUC__) && __GNUC__ > 4 && __cplusplus >= 201103)
|
||||
# define BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
|
||||
#else
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
# include <boost/type_traits/is_signed.hpp>
|
||||
# include <boost/type_traits/make_signed.hpp>
|
||||
# include <boost/type_traits/type_identity.hpp>
|
||||
#endif
|
||||
|
||||
#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. \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
|
||||
: public type_index_facade<
|
||||
stl_type_index,
|
||||
#ifdef BOOST_NO_STD_TYPEINFO
|
||||
type_info
|
||||
#else
|
||||
std::type_info
|
||||
#endif
|
||||
>
|
||||
{
|
||||
public:
|
||||
#ifdef BOOST_NO_STD_TYPEINFO
|
||||
typedef type_info type_info_t;
|
||||
#else
|
||||
typedef std::type_info type_info_t;
|
||||
#endif
|
||||
|
||||
private:
|
||||
const type_info_t* data_;
|
||||
|
||||
public:
|
||||
inline stl_type_index() BOOST_NOEXCEPT
|
||||
: data_(&typeid(void))
|
||||
{}
|
||||
|
||||
inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT
|
||||
: data_(&data)
|
||||
{}
|
||||
|
||||
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
|
||||
|
||||
inline const char* raw_name() const BOOST_NOEXCEPT;
|
||||
inline const char* name() const BOOST_NOEXCEPT;
|
||||
inline std::string pretty_name() const;
|
||||
|
||||
inline std::size_t hash_code() const BOOST_NOEXCEPT;
|
||||
inline bool equal(const stl_type_index& rhs) const BOOST_NOEXCEPT;
|
||||
inline bool before(const stl_type_index& rhs) const BOOST_NOEXCEPT;
|
||||
|
||||
template <class T>
|
||||
inline static stl_type_index type_id() BOOST_NOEXCEPT;
|
||||
|
||||
template <class T>
|
||||
inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT;
|
||||
|
||||
template <class T>
|
||||
inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT {
|
||||
return *data_;
|
||||
}
|
||||
|
||||
|
||||
inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT {
|
||||
#ifdef _MSC_VER
|
||||
return data_->raw_name();
|
||||
#else
|
||||
return data_->name();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
|
||||
return data_->name();
|
||||
}
|
||||
|
||||
inline std::string stl_type_index::pretty_name() const {
|
||||
static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
|
||||
static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;
|
||||
|
||||
// In case of MSVC demangle() is a no-op, and name() already returns demangled name.
|
||||
// In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it.
|
||||
const boost::core::scoped_demangled_name demangled_name(data_->name());
|
||||
|
||||
const char* begin = demangled_name.get();
|
||||
if (!begin) {
|
||||
boost::throw_exception(std::runtime_error("Type name demangling failed"));
|
||||
}
|
||||
|
||||
const 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::string(begin, end);
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
|
||||
return data_->hash_code();
|
||||
#else
|
||||
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// @cond
|
||||
|
||||
// for this compiler at least, cross-shared-library type_info
|
||||
// comparisons don't work, so we are using typeid(x).name() instead.
|
||||
# if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))) \
|
||||
|| defined(_AIX) \
|
||||
|| (defined(__sgi) && defined(__host_mips)) \
|
||||
|| (defined(__hpux) && defined(__HP_aCC)) \
|
||||
|| (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
|
||||
# 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_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
|
||||
return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
|
||||
#else
|
||||
return !!(*data_ == *rhs.data_);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT {
|
||||
#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
|
||||
}
|
||||
|
||||
#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_prefinal_t;
|
||||
|
||||
# if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <class T> class cvr_saver{};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
|
||||
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;
|
||||
|
||||
return typeid(type);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT {
|
||||
#ifdef BOOST_NO_RTTI
|
||||
return value.boost_type_index_type_id_runtime_();
|
||||
#else
|
||||
return typeid(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#undef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
|
297
include/boost/type_index/type_index_facade.hpp
Normal file
297
include/boost/type_index/type_index_facade.hpp
Normal file
@ -0,0 +1,297 @@
|
||||
//
|
||||
// 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_TYPE_INDEX_FACADE_HPP
|
||||
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#if !defined(BOOST_NO_IOSTREAM)
|
||||
#if !defined(BOOST_NO_IOSFWD)
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
#else
|
||||
#include <ostream>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \class type_index_facade
|
||||
///
|
||||
/// This class takes care about the comparison operators, hash functions and
|
||||
/// ostream operators. Use this class as a public base class for defining new
|
||||
/// type_info-conforming classes.
|
||||
///
|
||||
/// \b Example:
|
||||
/// \code
|
||||
/// class stl_type_index: public type_index_facade<stl_type_index, std::type_info>
|
||||
/// {
|
||||
/// public:
|
||||
/// typedef std::type_info type_info_t;
|
||||
/// private:
|
||||
/// const type_info_t* data_;
|
||||
///
|
||||
/// public:
|
||||
/// stl_type_index(const type_info_t& data) noexcept
|
||||
/// : data_(&data)
|
||||
/// {}
|
||||
/// // ...
|
||||
/// };
|
||||
/// \endcode
|
||||
///
|
||||
/// \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
|
||||
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 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 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().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 {
|
||||
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 {
|
||||
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 {
|
||||
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::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.
|
||||
/// \tparam T Type for which type_index must be created.
|
||||
/// \return type_index for type T.
|
||||
template <class T>
|
||||
static Derived type_id() BOOST_NOEXCEPT;
|
||||
|
||||
/// This is a factory method that is used to create instances of Derived classes.
|
||||
/// 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.
|
||||
/// \tparam T Type for which type_index must be created.
|
||||
/// \return type_index for type T.
|
||||
template <class T>
|
||||
static Derived type_id_with_cvr() BOOST_NOEXCEPT;
|
||||
|
||||
/// This is a factory method that is used to create instances of Derived classes.
|
||||
/// 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.
|
||||
/// \return type_index with runtime type of variable.
|
||||
template <class T>
|
||||
static Derived type_id_runtime(const T& variable) BOOST_NOEXCEPT;
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/// @cond
|
||||
template <class Derived, class TypeInfo>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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);
|
||||
}
|
||||
|
||||
// ######################### COMPARISONS with Derived ############################ //
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator == (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return Derived(lhs) == rhs;
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator < (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return Derived(lhs) < rhs;
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator > (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return rhs < Derived(lhs);
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator <= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return !(Derived(lhs) > rhs);
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator >= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return !(Derived(lhs) < rhs);
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator != (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
|
||||
return !(Derived(lhs) == rhs);
|
||||
}
|
||||
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
|
||||
return lhs == Derived(rhs);
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
|
||||
return lhs < Derived(rhs);
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
|
||||
return Derived(rhs) < lhs;
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
|
||||
return !(lhs > Derived(rhs));
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
|
||||
return !(lhs < Derived(rhs));
|
||||
}
|
||||
|
||||
template <class Derived, class TypeInfo>
|
||||
inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
|
||||
return !(lhs == Derived(rhs));
|
||||
}
|
||||
|
||||
// ######################### COMPARISONS with Derived END ############################ //
|
||||
|
||||
/// @endcond
|
||||
|
||||
#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;
|
||||
|
||||
/// noexcept comparison operators for type_index_facade and it's TypeInfo classes.
|
||||
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;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_IOSTREAM
|
||||
#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
|
||||
/// @cond
|
||||
/// 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 << static_cast<Derived const&>(ind).pretty_name();
|
||||
return ostr;
|
||||
}
|
||||
/// @endcond
|
||||
#else
|
||||
/// Ostream operator that will output demangled name.
|
||||
template <class CharT, class TriatT, class Derived, class TypeInfo>
|
||||
inline std::basic_ostream<CharT, TriatT>& operator<<(
|
||||
std::basic_ostream<CharT, TriatT>& ostr,
|
||||
const type_index_facade<Derived, TypeInfo>& ind)
|
||||
{
|
||||
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::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>
|
@ -1,273 +0,0 @@
|
||||
[library Boost.TypeIndex
|
||||
[quickbook 1.6]
|
||||
[version 2.1]
|
||||
[copyright 2012-2013 Antony Polukhin]
|
||||
[category Language Features Emulation]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
[@http://www.boost.org/LICENSE_1_0.txt])
|
||||
]
|
||||
]
|
||||
|
||||
[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:
|
||||
|
||||
* `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 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
|
||||
* no nice and portable way to get human readable type names
|
||||
|
||||
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 During the Boost review was decided, that it is better to use interface close to v1.0 of this library. Version 3.0 will attempt to fix all the issues found during the review. ]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Getting started]
|
||||
|
||||
`boost::type_info` is a drop-in replacement for `std::type_info` and `boost::type_index` is a drop-in
|
||||
replacement for `std::type_index`. Unlike Standard Library versions those classes may work without RTTI.
|
||||
|
||||
`boost::type_index` provides the full set of comparison operators, hashing functions and ostream
|
||||
operators, so it can be used with any container class.
|
||||
|
||||
To start using Boost.TypeIndex:
|
||||
|
||||
[table:porting
|
||||
[[Replace this:][With the following:]]
|
||||
[[``
|
||||
#include <typeinfo>
|
||||
#include <typeindex>
|
||||
``][``
|
||||
#include <boost/type_index/type_info.hpp>
|
||||
#include <boost/type_index/type_index.hpp>
|
||||
`` or ``
|
||||
#include <boost/type_index.hpp>
|
||||
``]]
|
||||
|
||||
[[``
|
||||
std::type_info
|
||||
std::type_index
|
||||
``][``
|
||||
boost::type_info
|
||||
boost::type_index
|
||||
``]]
|
||||
|
||||
[[``
|
||||
typeid(T)
|
||||
typeid(please_save_modifiers<T>)
|
||||
typeid(T).name() // not human readable
|
||||
typeid(variable)
|
||||
``][``
|
||||
boost::type_id<T>()
|
||||
boost::type_id_with_cvr<T>()
|
||||
boost::type_id<T>().name_demangled() // human readable
|
||||
boost::type_id_rtti_only(variable)
|
||||
``]]
|
||||
]
|
||||
|
||||
|
||||
Here is how TypeIndex could be used in `boost/any.hpp`:
|
||||
[table:any
|
||||
[[Before] [With TypeIndex]]
|
||||
[[``#include <typeinfo>``][``#include <boost/type_index/type_info.hpp>``]]
|
||||
[[``
|
||||
virtual const std::type_info & type() const BOOST_NOEXCEPT
|
||||
{
|
||||
// requires RTTI
|
||||
return typeid(ValueType);
|
||||
}
|
||||
``] [``
|
||||
virtual const boost::type_info & type() const BOOST_NOEXCEPT
|
||||
{
|
||||
// now works even with RTTI disabled
|
||||
return boost::type_id<ValueType>();
|
||||
}
|
||||
``]]
|
||||
]
|
||||
|
||||
|
||||
Here is how TypeIndex could be used in `boost/variant/variant.hpp`:
|
||||
[table:variant
|
||||
[[Before] [With TypeIndex]]
|
||||
|
||||
[[``
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
#include <typeinfo> // for typeid, std::type_info
|
||||
#endif // BOOST_NO_TYPEID
|
||||
``][``
|
||||
#include <boost/type_info/type_info.hpp>
|
||||
``]]
|
||||
[[``
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
|
||||
class reflect
|
||||
: public static_visitor<const std::type_info&>
|
||||
{
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename T>
|
||||
const std::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
{
|
||||
return typeid(T);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_TYPEID
|
||||
``][``
|
||||
class reflect
|
||||
: public static_visitor<const boost::type_info&>
|
||||
{
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename T>
|
||||
const boost::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::type_id<T>();
|
||||
}
|
||||
|
||||
};
|
||||
``]]
|
||||
[[``
|
||||
#if !defined(BOOST_NO_TYPEID)
|
||||
const std::type_info& type() const
|
||||
{
|
||||
detail::variant::reflect visitor;
|
||||
return this->apply_visitor(visitor);
|
||||
}
|
||||
#endif
|
||||
``] [``
|
||||
const boost::type_info& type() const
|
||||
{
|
||||
detail::variant::reflect visitor;
|
||||
return this->apply_visitor(visitor);
|
||||
}
|
||||
``]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Examples]
|
||||
|
||||
[import ../examples/demangled_names.cpp]
|
||||
[section Getting human readable and mangled type names] [type_index_names_example] [endsect]
|
||||
|
||||
[import ../examples/registry.cpp]
|
||||
[section Storing information about a type in container ] [type_index_registry_example] [endsect]
|
||||
|
||||
[import ../examples/inheritance.cpp]
|
||||
[section Getting through the inheritance to receive a real type name ] [type_index_derived_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]
|
||||
|
||||
[endsect]
|
||||
|
||||
[xinclude autodoc.xml]
|
||||
|
||||
[section Space and Performance]
|
||||
|
||||
* `template_info` uses macro for getting full text representation of function name which could lead to code bloat,
|
||||
so prefer using `type_info` type.
|
||||
* `type_index` and `template_index` classes hold a single pointer, so they are easy and fast to copy.
|
||||
* Calls to `const char* 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`.
|
||||
* Calls to `std::string name_demangled()` 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::type_info` class to `boost::template_info`.
|
||||
`boost::template_info` 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.
|
||||
|
||||
This leads to big strings in binary file:
|
||||
```
|
||||
static const char* boost::detail::ctti<T>::n() [with T = int]
|
||||
static const char* boost::detail::ctti<T>::n() [with T = user_defined_type]
|
||||
```
|
||||
While using RTTI, you'll get the following (more compact) string in binary file:
|
||||
|
||||
```
|
||||
i
|
||||
17user_defined_type
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Compiler support]
|
||||
|
||||
TypeIndex has been tested and successfully work on MSVC2010, GCC-4.5, 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:
|
||||
|
||||
# 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
|
||||
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.
|
||||
|
||||
Consider the following example:
|
||||
|
||||
With `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` set to `0`,
|
||||
`boost::template_id<int>().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`
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Mixing sources with RTTI on and RTTI off]
|
||||
|
||||
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 `boost::template_index` instead of `boost::type_index` class
|
||||
and `boost::template_info` instead of `boost::type_info` class.
|
||||
|
||||
[note Do not forget to rebuild *all* the projects with `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` macro defined ]
|
||||
|
||||
You must know that linking RTTI on and RTTI off binaries may succeed even without defining the
|
||||
`BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` macro, but that does not mean that you'll get a
|
||||
working binary. Such actions may break the One Definition Rule. Take a look at the table below,
|
||||
that shows how the `boost::type_index get_integer();` function will look like with different
|
||||
RTTI flags:
|
||||
|
||||
[table:diffs
|
||||
[[RTTI on] [RTTI off]]
|
||||
[[`boost::type_index get_integer();`] [`boost::template_index get_integer();`]]
|
||||
]
|
||||
|
||||
Such differences are usually not detected by linker and lead to errors at runtime.
|
||||
|
||||
[warning
|
||||
Even with `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` defined there is no guarantee
|
||||
that everything will be OK. Libraries that use their own workarounds for disabled RTTI
|
||||
may fail to link or to work correctly.
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Acknowledgements]
|
||||
|
||||
In order of helping and advising:
|
||||
|
||||
* Peter Dimov for writing source codes in late 2007, ideas from which were refined and put into this library.
|
||||
* Agustín Bergé K-ballo for helping with docs and fixing a lot of typos.
|
||||
* Niall Douglas for generating a lot of great ideas and reviewing the sources.
|
||||
|
||||
[endsect]
|
@ -1,50 +0,0 @@
|
||||
// Copyright 2013 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_example
|
||||
/*`
|
||||
The following example shows how short (mangled) and human readable type names could be obtained from a type.
|
||||
Works with and without RTTI.
|
||||
*/
|
||||
|
||||
|
||||
#include <boost/type_index/type_info.hpp>
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
void foo(T) {
|
||||
std::cout << "\n Short name: " << boost::type_id<T>().name();
|
||||
std::cout << "\n Readable name: " << boost::type_id<T>().name_demangled();
|
||||
}
|
||||
|
||||
struct user_defined_type{};
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/*`
|
||||
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`.
|
||||
*/
|
||||
|
||||
//] [/type_index_names_example]
|
@ -1,34 +0,0 @@
|
||||
// Copyright 2013 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_derived_example
|
||||
/*`
|
||||
The following example shows that `boost::type_info` is able to store the real type, successfully getting through
|
||||
all the inheritances.
|
||||
|
||||
Example works with RTTI only. Without RTTI support it won't compile, producing a compile-time error with message:
|
||||
"boost::type_id_rtti_only(T&) requires RTTI"
|
||||
*/
|
||||
|
||||
#include <boost/type_index/type_info.hpp>
|
||||
#include <iostream>
|
||||
|
||||
struct A { virtual ~A(){} };
|
||||
struct B: public A {};
|
||||
struct C: public B {};
|
||||
|
||||
void print_real_type(const A& a) {
|
||||
std::cout << boost::type_id_rtti_only(a).name_demangled() << '\n';
|
||||
}
|
||||
|
||||
int main() {
|
||||
C c;
|
||||
const A& c_as_a = c;
|
||||
print_real_type(c_as_a); // Outputs `struct C`
|
||||
print_real_type(B()); // Outputs `struct B`
|
||||
}
|
||||
|
||||
//] [/type_index_derived_example]
|
@ -1,36 +0,0 @@
|
||||
// Copyright 2013 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_registry_example
|
||||
/*`
|
||||
The following example shows how an information about a type could be stored.
|
||||
Example works with and without RTTI.
|
||||
*/
|
||||
|
||||
#include <boost/type_index/type_index.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <cassert>
|
||||
|
||||
int main() {
|
||||
boost::unordered_set<boost::type_index> types;
|
||||
|
||||
// Storing some `boost::type_info`s
|
||||
types.insert(boost::type_id<int>());
|
||||
types.insert(boost::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(boost::type_id<const int>()).second;
|
||||
assert(!is_inserted);
|
||||
assert(types.erase(boost::type_id<float&>()) == 1);
|
||||
|
||||
// We have erased the `float` type, only `int` remains
|
||||
assert(*types.begin() == boost::type_id<int>());
|
||||
}
|
||||
|
||||
//] [/type_index_registry_example]
|
@ -1,62 +0,0 @@
|
||||
# Copyright (C) 2012-2013 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)
|
||||
#
|
||||
|
||||
import testing ;
|
||||
import feature ;
|
||||
|
||||
|
||||
# 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 libraries that CANNOT work between rtti-on/rtti-off modules
|
||||
obj test_lib_nortti-obj : test_lib.cpp : <link>shared <rtti>off ;
|
||||
obj test_lib_rtti-obj : test_lib.cpp : <link>shared ;
|
||||
lib test_lib_rtti : test_lib_rtti-obj : <link>shared ;
|
||||
lib test_lib_nortti : test_lib_nortti-obj : <link>shared <rtti>off ;
|
||||
|
||||
# Making libraries that can work between rtti-on/rtti-off modules
|
||||
obj test_lib_nortti_compat-obj : test_lib.cpp : <link>shared $(nortti) $(compat) ;
|
||||
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) ;
|
||||
|
||||
|
||||
test-suite type_index
|
||||
:
|
||||
[ run type_index_test.cpp $(tlib) ]
|
||||
[ run template_index_test.cpp $(tlib) ]
|
||||
[ run testing_both.cpp $(tlib) ]
|
||||
[ run testing_both_no_rtti.cpp $(tlib) : : : <rtti>off ]
|
||||
[ run testing_crossmodule.cpp test_lib_rtti $(tlib) ]
|
||||
[ run testing_crossmodule.cpp test_lib_nortti $(tlib) : : : <rtti>off : testing_crossmodule_no_rtti ]
|
||||
|
||||
# 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 ]
|
||||
|
||||
# Examples that must work even with RTTI disabled
|
||||
[ run ../examples/registry.cpp : : : <rtti>off : registry_no_rtti ]
|
||||
[ run ../examples/exact_types_match.cpp : : : <rtti>off : exact_types_match_no_rtti ]
|
||||
[ run ../examples/demangled_names.cpp : : : <rtti>off : demangled_names_no_rtti ]
|
||||
[ compile-fail ../examples/inheritance.cpp : <rtti>off : failing_inheritance_example ]
|
||||
;
|
||||
|
||||
# Assuring that examples compile and run. Adding sources from `examples` directory to the `type_index` test suite.
|
||||
for local p in [ glob ../examples/*.cpp ]
|
||||
{
|
||||
type_index += [ run $(p) ] ;
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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 template_index_test_module
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/type_index/template_index.hpp>
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
|
||||
namespace my_namespace2 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
#include "template_index_tests.ipp"
|
||||
|
@ -1,199 +0,0 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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/functional/hash.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE(names_matches_template_id)
|
||||
{
|
||||
using namespace boost;
|
||||
BOOST_CHECK_EQUAL(template_id<int>().name_demangled(), "int");
|
||||
BOOST_CHECK_EQUAL(template_id<double>().name_demangled(), "double");
|
||||
|
||||
BOOST_CHECK_EQUAL(template_id<int>().name(), template_id<int>().name());
|
||||
BOOST_CHECK_NE(template_id<int>().name(), template_id<double>().name());
|
||||
BOOST_CHECK_NE(template_id<double>().name(), template_id<int>().name());
|
||||
BOOST_CHECK_EQUAL(template_id<double>().name(), template_id<double>().name());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparators_template_id)
|
||||
{
|
||||
using namespace boost;
|
||||
template_index t_int = template_id<int>();
|
||||
template_index t_double = template_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_CHECK_LE(t_double, t_double);
|
||||
BOOST_CHECK_GE(t_double, t_double);
|
||||
BOOST_CHECK_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_AUTO_TEST_CASE(hash_code_template_id)
|
||||
{
|
||||
using namespace boost;
|
||||
std::size_t t_int1 = template_id<int>().hash_code();
|
||||
std::size_t t_double1 = template_id<double>().hash_code();
|
||||
|
||||
std::size_t t_int2 = template_id<int>().hash_code();
|
||||
std::size_t t_double2 = template_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);
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
static void test_with_modofiers() {
|
||||
using namespace boost;
|
||||
|
||||
template_index t1 = template_id_with_cvr<T1>();
|
||||
template_index t2 = template_id_with_cvr<T2>();
|
||||
|
||||
BOOST_CHECK_NE(t2, t1);
|
||||
BOOST_CHECK(t1 < t2 || t2 < t1);
|
||||
BOOST_CHECK(t1 > t2 || t2 > t1);
|
||||
|
||||
BOOST_CHECK_EQUAL(t1, template_id_with_cvr<T1>());
|
||||
BOOST_CHECK_EQUAL(t2, template_id_with_cvr<T2>());
|
||||
|
||||
BOOST_CHECK_EQUAL(t1.hash_code(), template_id_with_cvr<T1>().hash_code());
|
||||
BOOST_CHECK_EQUAL(t2.hash_code(), template_id_with_cvr<T2>().hash_code());
|
||||
|
||||
BOOST_CHECK_NE(t1.hash_code(), template_id_with_cvr<T2>().hash_code());
|
||||
BOOST_CHECK_NE(t2.hash_code(), template_id_with_cvr<T1>().hash_code());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(template_id_storing_modifiers)
|
||||
{
|
||||
test_with_modofiers<int, const int>();
|
||||
test_with_modofiers<int, const int&>();
|
||||
test_with_modofiers<int, int&>();
|
||||
test_with_modofiers<int, volatile int>();
|
||||
test_with_modofiers<int, volatile int&>();
|
||||
test_with_modofiers<int, const volatile int>();
|
||||
test_with_modofiers<int, const volatile int&>();
|
||||
|
||||
test_with_modofiers<const int, int>();
|
||||
test_with_modofiers<const int, const int&>();
|
||||
test_with_modofiers<const int, int&>();
|
||||
test_with_modofiers<const int, volatile int>();
|
||||
test_with_modofiers<const int, volatile int&>();
|
||||
test_with_modofiers<const int, const volatile int>();
|
||||
test_with_modofiers<const int, const volatile int&>();
|
||||
|
||||
test_with_modofiers<const int&, int>();
|
||||
test_with_modofiers<const int&, const int>();
|
||||
test_with_modofiers<const int&, int&>();
|
||||
test_with_modofiers<const int&, volatile int>();
|
||||
test_with_modofiers<const int&, volatile int&>();
|
||||
test_with_modofiers<const int&, const volatile int>();
|
||||
test_with_modofiers<const int&, const volatile int&>();
|
||||
|
||||
test_with_modofiers<int&, const int>();
|
||||
test_with_modofiers<int&, const int&>();
|
||||
test_with_modofiers<int&, int>();
|
||||
test_with_modofiers<int&, volatile int>();
|
||||
test_with_modofiers<int&, volatile int&>();
|
||||
test_with_modofiers<int&, const volatile int>();
|
||||
test_with_modofiers<int&, const volatile int&>();
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
test_with_modofiers<int&&, const int>();
|
||||
test_with_modofiers<int&&, const int&>();
|
||||
test_with_modofiers<int&&, const int&&>();
|
||||
test_with_modofiers<int&&, int>();
|
||||
test_with_modofiers<int&&, volatile int>();
|
||||
test_with_modofiers<int&&, volatile int&>();
|
||||
test_with_modofiers<int&&, volatile int&&>();
|
||||
test_with_modofiers<int&&, const volatile int>();
|
||||
test_with_modofiers<int&&, const volatile int&>();
|
||||
test_with_modofiers<int&&, const volatile int&&>();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void test_storing_nonstoring_modifiers_templ() {
|
||||
using namespace boost;
|
||||
|
||||
template_index t1 = template_id_with_cvr<T>();
|
||||
template_index t2 = template_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_CHECK_EQUAL(t2.name_demangled(), t1.name_demangled());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(template_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::template_index t1 = boost::template_id_with_cvr<const int>();
|
||||
boost::template_index t2 = boost::template_id<int>();
|
||||
BOOST_CHECK_NE(t2, t1);
|
||||
BOOST_CHECK(t1.name_demangled() == "const int" || t1.name_demangled() == "int const");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(template_index_stream_operator_via_lexical_cast_testing)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
std::string s_int2 = lexical_cast<std::string>(template_id<int>());
|
||||
BOOST_CHECK_EQUAL(s_int2, "int");
|
||||
|
||||
std::string s_double2 = lexical_cast<std::string>(template_id<double>());
|
||||
BOOST_CHECK_EQUAL(s_double2, "double");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(template_index_stripping_cvr_test)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
BOOST_CHECK_EQUAL(template_id<int>(), template_id<const int>());
|
||||
BOOST_CHECK_EQUAL(template_id<int>(), template_id<const volatile int>());
|
||||
BOOST_CHECK_EQUAL(template_id<int>(), template_id<const volatile int&>());
|
||||
|
||||
BOOST_CHECK_EQUAL(template_id<int>(), template_id<int&>());
|
||||
BOOST_CHECK_EQUAL(template_id<int>(), template_id<volatile int>());
|
||||
BOOST_CHECK_EQUAL(template_id<int>(), template_id<volatile int&>());
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(template_id<double>(), template_id<const double>());
|
||||
BOOST_CHECK_EQUAL(template_id<double>(), template_id<const volatile double>());
|
||||
BOOST_CHECK_EQUAL(template_id<double>(), template_id<const volatile double&>());
|
||||
|
||||
BOOST_CHECK_EQUAL(template_id<double>(), template_id<double&>());
|
||||
BOOST_CHECK_EQUAL(template_id<double>(), template_id<volatile double>());
|
||||
BOOST_CHECK_EQUAL(template_id<double>(), template_id<volatile double&>());
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(template_index_user_defined_class_test)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
BOOST_CHECK_EQUAL(template_id<my_namespace1::my_class>(), template_id<my_namespace1::my_class>());
|
||||
BOOST_CHECK_EQUAL(template_id<my_namespace2::my_class>(), template_id<my_namespace2::my_class>());
|
||||
|
||||
BOOST_CHECK_NE(template_id<my_namespace1::my_class>(), template_id<my_namespace2::my_class>());
|
||||
BOOST_CHECK_NE(
|
||||
template_id<my_namespace1::my_class>().name_demangled().find("my_namespace1::my_class"),
|
||||
std::string::npos);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
#define TEST_LIB_SOURCE
|
||||
#include "test_lib.hpp"
|
||||
|
||||
namespace user_defined_namespace {
|
||||
class user_defined{};
|
||||
}
|
||||
|
||||
namespace test_lib {
|
||||
|
||||
boost::type_index get_integer() {
|
||||
return boost::type_id<int>();
|
||||
}
|
||||
|
||||
boost::type_index get_user_defined_class() {
|
||||
return boost::type_id<user_defined_namespace::user_defined>();
|
||||
}
|
||||
|
||||
boost::type_index get_const_integer() {
|
||||
return boost::type_id_with_cvr<const int>();
|
||||
}
|
||||
|
||||
boost::type_index get_const_user_defined_class() {
|
||||
return boost::type_id_with_cvr<const user_defined_namespace::user_defined>();
|
||||
}
|
||||
|
||||
|
||||
// Just do nothing
|
||||
void accept_typeindex(const boost::type_index&) {}
|
||||
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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_both_test_module
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
|
||||
namespace my_namespace2 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
#include "type_index_tests.ipp"
|
||||
#include "template_index_tests.ipp"
|
||||
|
@ -1,27 +0,0 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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_both_test_module
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
#error "This test must be run with disabled RTTI"
|
||||
#endif
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
|
||||
namespace my_namespace2 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
#include "type_index_tests.ipp"
|
||||
#include "template_index_tests.ipp"
|
||||
|
@ -1,45 +0,0 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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/type_index.hpp>
|
||||
#include "test_lib.hpp"
|
||||
|
||||
namespace user_defined_namespace {
|
||||
class user_defined{};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparing_types_between_modules)
|
||||
{
|
||||
boost::type_index t_const_int = boost::type_id_with_cvr<const int>();
|
||||
boost::type_index t_int = boost::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::type_index t_const_userdef = boost::type_id_with_cvr<const user_defined_namespace::user_defined>();
|
||||
boost::type_index t_userdef = boost::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_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());
|
||||
|
||||
test_lib::accept_typeindex(t_int);
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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_both_test_module
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/type_index/type_index_minimal.hpp>
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
#error "This test must be run with disabled RTTI"
|
||||
#endif
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
|
||||
namespace my_namespace2 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
#include "type_index_tests.ipp"
|
||||
|
@ -1,22 +0,0 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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/type_index.hpp>
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
|
||||
namespace my_namespace2 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
#include "type_index_tests.ipp"
|
@ -1,302 +0,0 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012.
|
||||
//
|
||||
// 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/functional/hash.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE(names_matches_type_id)
|
||||
{
|
||||
using namespace boost;
|
||||
BOOST_CHECK_EQUAL(type_id<int>().name_demangled(), "int");
|
||||
BOOST_CHECK_EQUAL(type_id<double>().name_demangled(), "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_AUTO_TEST_CASE(comparators_type_id)
|
||||
{
|
||||
using namespace boost;
|
||||
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_CHECK_LE(t_double, t_double);
|
||||
BOOST_CHECK_GE(t_double, t_double);
|
||||
BOOST_CHECK_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_AUTO_TEST_CASE(hash_code_type_id)
|
||||
{
|
||||
using namespace boost;
|
||||
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);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparators_type_id_vs_type_info)
|
||||
{
|
||||
using namespace boost;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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_CHECK(t_double <= typeid(int));
|
||||
BOOST_CHECK(typeid(double) <= t_int);
|
||||
BOOST_CHECK(typeid(int) >= t_double);
|
||||
BOOST_CHECK(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_CHECK(t_double >= typeid(int));
|
||||
BOOST_CHECK(typeid(double) >= t_int);
|
||||
BOOST_CHECK(typeid(int) <= t_double);
|
||||
BOOST_CHECK(t_int <= typeid(double));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_RTTI
|
||||
|
||||
template <class T1, class T2>
|
||||
static void test_with_modofiers_type_id() {
|
||||
using namespace boost;
|
||||
|
||||
type_index t1 = type_id_with_cvr<T1>();
|
||||
type_index t2 = type_id_with_cvr<T2>();
|
||||
|
||||
BOOST_CHECK_NE(t2, t1);
|
||||
BOOST_CHECK(t1 < t2 || t2 < t1);
|
||||
BOOST_CHECK(t1 > t2 || t2 > t1);
|
||||
|
||||
BOOST_CHECK_EQUAL(t1, type_id_with_cvr<T1>());
|
||||
BOOST_CHECK_EQUAL(t2, 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_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_AUTO_TEST_CASE(type_id_storing_modifiers)
|
||||
{
|
||||
test_with_modofiers_type_id<int, const int>();
|
||||
test_with_modofiers_type_id<int, const int&>();
|
||||
test_with_modofiers_type_id<int, int&>();
|
||||
test_with_modofiers_type_id<int, volatile int>();
|
||||
test_with_modofiers_type_id<int, volatile int&>();
|
||||
test_with_modofiers_type_id<int, const volatile int>();
|
||||
test_with_modofiers_type_id<int, const volatile int&>();
|
||||
|
||||
test_with_modofiers_type_id<const int, int>();
|
||||
test_with_modofiers_type_id<const int, const int&>();
|
||||
test_with_modofiers_type_id<const int, int&>();
|
||||
test_with_modofiers_type_id<const int, volatile int>();
|
||||
test_with_modofiers_type_id<const int, volatile int&>();
|
||||
test_with_modofiers_type_id<const int, const volatile int>();
|
||||
test_with_modofiers_type_id<const int, const volatile int&>();
|
||||
|
||||
test_with_modofiers_type_id<const int&, int>();
|
||||
test_with_modofiers_type_id<const int&, const int>();
|
||||
test_with_modofiers_type_id<const int&, int&>();
|
||||
test_with_modofiers_type_id<const int&, volatile int>();
|
||||
test_with_modofiers_type_id<const int&, volatile int&>();
|
||||
test_with_modofiers_type_id<const int&, const volatile int>();
|
||||
test_with_modofiers_type_id<const int&, const volatile int&>();
|
||||
|
||||
test_with_modofiers_type_id<int&, const int>();
|
||||
test_with_modofiers_type_id<int&, const int&>();
|
||||
test_with_modofiers_type_id<int&, int>();
|
||||
test_with_modofiers_type_id<int&, volatile int>();
|
||||
test_with_modofiers_type_id<int&, volatile int&>();
|
||||
test_with_modofiers_type_id<int&, const volatile int>();
|
||||
test_with_modofiers_type_id<int&, const volatile int&>();
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
test_with_modofiers_type_id<int&&, const int>();
|
||||
test_with_modofiers_type_id<int&&, const int&>();
|
||||
test_with_modofiers_type_id<int&&, const int&&>();
|
||||
test_with_modofiers_type_id<int&&, int>();
|
||||
test_with_modofiers_type_id<int&&, volatile int>();
|
||||
test_with_modofiers_type_id<int&&, volatile int&>();
|
||||
test_with_modofiers_type_id<int&&, volatile int&&>();
|
||||
test_with_modofiers_type_id<int&&, const volatile int>();
|
||||
test_with_modofiers_type_id<int&&, const volatile int&>();
|
||||
test_with_modofiers_type_id<int&&, const volatile int&&>();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void test_storing_nonstoring_modifiers() {
|
||||
using namespace boost;
|
||||
|
||||
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_CHECK_EQUAL(t2.name_demangled(), t1.name_demangled());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_id_storing_modifiers_vs_nonstoring)
|
||||
{
|
||||
test_storing_nonstoring_modifiers<int>();
|
||||
test_storing_nonstoring_modifiers<my_namespace1::my_class>();
|
||||
test_storing_nonstoring_modifiers<my_namespace2::my_class>();
|
||||
|
||||
boost::type_index t1 = boost::type_id_with_cvr<const int>();
|
||||
boost::type_index t2 = boost::type_id<int>();
|
||||
BOOST_CHECK_NE(t2, t1);
|
||||
BOOST_CHECK(t1.name_demangled() == "const int" || t1.name_demangled() == "int const");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_index_stream_operator_via_lexical_cast_testing)
|
||||
{
|
||||
using namespace boost;
|
||||
std::string s_int1 = lexical_cast<std::string>(type_id<int>());
|
||||
BOOST_CHECK_EQUAL(s_int1, "int");
|
||||
|
||||
std::string s_double1 = lexical_cast<std::string>(type_id<double>());
|
||||
BOOST_CHECK_EQUAL(s_double1, "double");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_index_stripping_cvr_test)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
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_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_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_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_AUTO_TEST_CASE(type_index_user_defined_class_test)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
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>());
|
||||
|
||||
#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>());
|
||||
#endif
|
||||
|
||||
BOOST_CHECK_NE(type_id<my_namespace1::my_class>(), type_id<my_namespace2::my_class>());
|
||||
BOOST_CHECK_NE(
|
||||
type_id<my_namespace1::my_class>().name_demangled().find("my_namespace1::my_class"),
|
||||
std::string::npos);
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
|
||||
class A { public: virtual ~A(){} };
|
||||
class B: public A{};
|
||||
class C: public B {};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(comparators_type_id_rtti_only)
|
||||
{
|
||||
C c1;
|
||||
B b1;
|
||||
A* pc1 = &c1;
|
||||
A& rc1 = c1;
|
||||
A* pb1 = &b1;
|
||||
A& rb1 = b1;
|
||||
BOOST_CHECK(typeid(rc1) == typeid(*pc1));
|
||||
BOOST_CHECK(typeid(rb1) == typeid(*pb1));
|
||||
|
||||
BOOST_CHECK(typeid(rc1) != typeid(*pb1));
|
||||
BOOST_CHECK(typeid(rb1) != typeid(*pc1));
|
||||
|
||||
BOOST_CHECK(typeid(&rc1) == typeid(pb1));
|
||||
BOOST_CHECK(typeid(&rb1) == typeid(pc1));
|
||||
|
||||
BOOST_CHECK_EQUAL(boost::type_id_rtti_only(rc1), boost::type_id_rtti_only(*pc1));
|
||||
BOOST_CHECK_EQUAL(boost::type_id_rtti_only(rb1), boost::type_id_rtti_only(*pb1));
|
||||
|
||||
BOOST_CHECK_NE(boost::type_id_rtti_only(rc1), boost::type_id_rtti_only(*pb1));
|
||||
BOOST_CHECK_NE(boost::type_id_rtti_only(rb1), boost::type_id_rtti_only(*pc1));
|
||||
BOOST_CHECK_EQUAL(boost::type_id_rtti_only(&rc1), boost::type_id_rtti_only(pb1));
|
||||
BOOST_CHECK_EQUAL(boost::type_id_rtti_only(&rb1), boost::type_id_rtti_only(pc1));
|
||||
|
||||
BOOST_CHECK(boost::type_id_rtti_only(rc1) == typeid(*pc1));
|
||||
BOOST_CHECK(boost::type_id_rtti_only(rb1) == typeid(*pb1));
|
||||
|
||||
BOOST_CHECK(boost::type_id_rtti_only(rc1) != typeid(*pb1));
|
||||
BOOST_CHECK(boost::type_id_rtti_only(rb1) != typeid(*pc1));
|
||||
BOOST_CHECK(boost::type_id_rtti_only(&rc1) == typeid(pb1));
|
||||
BOOST_CHECK(boost::type_id_rtti_only(&rb1) == typeid(pc1));
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_RTTI
|
||||
|
||||
|
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"
|
||||
}
|
@ -3,3 +3,7 @@ patches for Boost libraries to work without RTTI
|
||||
|
||||
Here are the patches that are TESTED and work well with RTTI disabled and enabled.
|
||||
Patches add tests for some of the libraries to make sure that library compile and work without RTTI.
|
||||
|
||||
Patches remove duplicate code, improve output, allow compilation with RTTI off...
|
||||
|
||||
Libraries Boost.Graph, Boost.XPressive, Boost.PropertyMap and others may also benefit from TypeIndex library.
|
||||
|
@ -1,12 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
test-suite any :
|
||||
[ run ../any_test.cpp ]
|
||||
+ [ run ../any_test.cpp : : : <rtti>off : testing_any_no_rtti ]
|
||||
[ run any_test_rv.cpp ]
|
||||
[ compile-fail any_cast_cv_failed.cpp ]
|
||||
[ compile-fail any_test_temporary_to_ref_failed.cpp ]
|
@ -1,91 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -15,7 +15,7 @@
|
||||
// when: July 2001, April 2013 - May 2013
|
||||
|
||||
#include <algorithm>
|
||||
-#include <typeinfo>
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
|
||||
#include "boost/config.hpp"
|
||||
#include <boost/type_traits/remove_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
|
||||
-
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4172) // Mistakenly warns: returning address of local variable or temporary
|
||||
@@ -149,9 +138,9 @@
|
||||
any().swap(*this);
|
||||
}
|
||||
|
||||
- const std::type_info & type() const BOOST_NOEXCEPT
|
||||
+ const boost::type_info & type() const BOOST_NOEXCEPT
|
||||
{
|
||||
- return content ? content->type() : typeid(void);
|
||||
+ return content ? content->type() : boost::type_id<void>();
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
@@ -170,7 +159,7 @@
|
||||
|
||||
public: // queries
|
||||
|
||||
- virtual const std::type_info & type() const BOOST_NOEXCEPT = 0;
|
||||
+ virtual const boost::type_info & type() const BOOST_NOEXCEPT = 0;
|
||||
|
||||
virtual placeholder * clone() const = 0;
|
||||
|
||||
@@ -194,9 +183,9 @@
|
||||
#endif
|
||||
public: // queries
|
||||
|
||||
- virtual const std::type_info & type() const BOOST_NOEXCEPT
|
||||
+ virtual const boost::type_info & type() const BOOST_NOEXCEPT
|
||||
{
|
||||
- return typeid(ValueType);
|
||||
+ return boost::type_id<ValueType>();
|
||||
}
|
||||
|
||||
virtual placeholder * clone() const
|
||||
@@ -237,7 +226,12 @@
|
||||
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
|
||||
@@ -251,11 +245,7 @@
|
||||
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
|
||||
+ operand->type() == boost::type_id<ValueType>()
|
||||
? &static_cast<any::holder<ValueType> *>(operand->content)->held
|
||||
: 0;
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -91,7 +91,10 @@
|
||||
|
||||
check_true(value.empty(), "empty");
|
||||
check_null(any_cast<int>(&value), "any_cast<int>");
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
check_equal(value.type(), typeid(void), "type");
|
||||
+#endif
|
||||
+ check_equal(value.type(), boost::type_id<void>(), "type boost");
|
||||
}
|
||||
|
||||
void test_converting_ctor()
|
||||
@@ -100,7 +103,10 @@
|
||||
any value = text;
|
||||
|
||||
check_false(value.empty(), "empty");
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
check_equal(value.type(), typeid(std::string), "type");
|
||||
+#endif
|
||||
+ check_equal(value.type(), boost::type_id<std::string>(), "type boost");
|
||||
check_null(any_cast<int>(&value), "any_cast<int>");
|
||||
check_non_null(any_cast<std::string>(&value), "any_cast<std::string>");
|
||||
check_equal(
|
||||
@@ -158,7 +164,10 @@
|
||||
any * assign_result = &(value = text);
|
||||
|
||||
check_false(value.empty(), "type");
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
check_equal(value.type(), typeid(std::string), "type");
|
||||
+#endif
|
||||
+ check_equal(value.type(), boost::type_id<std::string>(), "type boost");
|
||||
check_null(any_cast<int>(&value), "any_cast<int>");
|
||||
check_non_null(any_cast<std::string>(&value), "any_cast<std::string>");
|
||||
check_equal(
|
||||
@@ -191,7 +200,10 @@
|
||||
|
||||
check_true(original.empty(), "empty on original");
|
||||
check_false(swapped.empty(), "empty on swapped");
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
check_equal(swapped.type(), typeid(std::string), "type");
|
||||
+#endif
|
||||
+ check_equal(swapped.type(), boost::type_id<std::string>(), "type boost");
|
||||
check_equal(
|
||||
text, any_cast<std::string>(swapped),
|
||||
"comparing swapped copy against original text");
|
||||
@@ -264,8 +276,12 @@
|
||||
check_false(value1.empty(), "type");
|
||||
check_false(value2.empty(), "type");
|
||||
|
||||
+#ifndef BOOST_NO_RTTI
|
||||
check_equal(value1.type(), typeid(const char*), "type");
|
||||
check_equal(value2.type(), typeid(const char*), "type");
|
||||
+#endif
|
||||
+ check_equal(value1.type(), boost::type_id<const char*>(), "type boost");
|
||||
+ check_equal(value2.type(), boost::type_id<const char*>(), "type boost");
|
||||
|
||||
check_non_null(any_cast<const char*>(&value1), "any_cast<const char*>");
|
||||
check_non_null(any_cast<const char*>(&value2), "any_cast<const char*>");
|
@ -1,29 +1,45 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86532)
|
||||
+++ . (working copy)
|
||||
@@ -15,121 +15,15 @@
|
||||
From b77c0af6af8bc4797defc3627878acc3cf7a6f39 Mon Sep 17 00:00:00 2001
|
||||
From: Antony Polukhin <antoshkka@gmail.com>
|
||||
Date: Thu, 20 Feb 2014 17:57:24 +0400
|
||||
Subject: [PATCH] detail/sp_typeinfo.hpp now uses TypeIndex
|
||||
|
||||
---
|
||||
include/boost/detail/sp_typeinfo.hpp | 123 +++--------------------------------
|
||||
1 file changed, 8 insertions(+), 115 deletions(-)
|
||||
|
||||
diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp
|
||||
index 43fae78..fbdf86d 100644
|
||||
--- a/include/boost/detail/sp_typeinfo.hpp
|
||||
+++ b/include/boost/detail/sp_typeinfo.hpp
|
||||
@@ -10,126 +10,19 @@
|
||||
// detail/sp_typeinfo.hpp
|
||||
//
|
||||
// Copyright 2007 Peter Dimov
|
||||
+// Copyright 2014 Antony Polukhin
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
-#include <boost/config.hpp>
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
|
||||
-#if defined( BOOST_NO_TYPEID )
|
||||
+#include <boost/type_index.hpp>
|
||||
+namespace boost { namespace detail {
|
||||
|
||||
-#include <boost/current_function.hpp>
|
||||
-#include <functional>
|
||||
+typedef boost::type_info sp_typeinfo;
|
||||
|
||||
-namespace boost
|
||||
-{
|
||||
+
|
||||
+typedef boost::typeind::type_info sp_typeinfo;
|
||||
+
|
||||
+}} // namespace boost::detail
|
||||
|
||||
-#if defined( BOOST_NO_TYPEID )
|
||||
-
|
||||
-#include <boost/current_function.hpp>
|
||||
-#include <functional>
|
||||
-
|
||||
-namespace boost
|
||||
-{
|
||||
-
|
||||
-namespace detail
|
||||
-{
|
||||
+#define BOOST_SP_TYPEID(T) (boost::type_id<T>())
|
||||
|
||||
-
|
||||
-class sp_typeinfo
|
||||
-{
|
||||
-private:
|
||||
@ -127,6 +143,9 @@ Index: .
|
||||
-#define BOOST_SP_TYPEID(T) typeid(T)
|
||||
-
|
||||
-#endif
|
||||
-
|
||||
+#define BOOST_SP_TYPEID(T) (boost::typeind::type_id<T>().type_info())
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
|
||||
+
|
||||
--
|
||||
1.8.5.3
|
||||
|
156
patched/boost_exception.patch
Normal file
156
patched/boost_exception.patch
Normal file
@ -0,0 +1,156 @@
|
||||
From 8f57d59bfbc978673a2493a90b4f3e7e54ddbf18 Mon Sep 17 00:00:00 2001
|
||||
From: Antony Polukhin <antoshkka@gmail.com>
|
||||
Date: Thu, 20 Feb 2014 18:30:11 +0400
|
||||
Subject: [PATCH] Boost.Exception now uses TypeIndex to reduce duplicate code
|
||||
and simplify name demanglings
|
||||
|
||||
---
|
||||
include/boost/exception/detail/type_info.hpp | 43 +++-------------------
|
||||
include/boost/exception/diagnostic_information.hpp | 2 +-
|
||||
include/boost/exception/exception.hpp | 3 +-
|
||||
include/boost/exception/info.hpp | 2 +-
|
||||
test/Jamfile.v2 | 2 +
|
||||
5 files changed, 12 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/include/boost/exception/detail/type_info.hpp b/include/boost/exception/detail/type_info.hpp
|
||||
index 6e5942d..a247b71 100644
|
||||
--- a/include/boost/exception/detail/type_info.hpp
|
||||
+++ b/include/boost/exception/detail/type_info.hpp
|
||||
@@ -12,13 +12,7 @@
|
||||
#pragma warning(push,1)
|
||||
#endif
|
||||
|
||||
-#include <boost/detail/sp_typeinfo.hpp>
|
||||
-#include <boost/current_function.hpp>
|
||||
-#include <boost/config.hpp>
|
||||
-//#ifndef BOOST_NO_TYPEID
|
||||
-//#include <boost/units/detail/utility.hpp>
|
||||
-//#endif
|
||||
-#include <string>
|
||||
+#include <boost/type_index.hpp>
|
||||
|
||||
namespace
|
||||
boost
|
||||
@@ -28,11 +22,7 @@ boost
|
||||
std::string
|
||||
tag_type_name()
|
||||
{
|
||||
-#ifdef BOOST_NO_TYPEID
|
||||
- return BOOST_CURRENT_FUNCTION;
|
||||
-#else
|
||||
- return /*units::detail::demangle*/(typeid(T*).name());
|
||||
-#endif
|
||||
+ return boost::typeind::type_id<T*>().pretty_name();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -40,41 +30,20 @@ boost
|
||||
std::string
|
||||
type_name()
|
||||
{
|
||||
-#ifdef BOOST_NO_TYPEID
|
||||
- return BOOST_CURRENT_FUNCTION;
|
||||
-#else
|
||||
- return /*units::detail::demangle*/(typeid(T).name());
|
||||
-#endif
|
||||
+ return boost::typeind::type_id<T>().pretty_name();
|
||||
}
|
||||
|
||||
namespace
|
||||
exception_detail
|
||||
{
|
||||
- struct
|
||||
- type_info_
|
||||
- {
|
||||
- detail::sp_typeinfo const * type_;
|
||||
-
|
||||
- explicit
|
||||
- type_info_( detail::sp_typeinfo const & type ):
|
||||
- type_(&type)
|
||||
- {
|
||||
- }
|
||||
-
|
||||
- friend
|
||||
- bool
|
||||
- operator<( type_info_ const & a, type_info_ const & b )
|
||||
- {
|
||||
- return 0!=(a.type_->before(*b.type_));
|
||||
- }
|
||||
- };
|
||||
+ typedef boost::typeind::type_index type_info_;
|
||||
}
|
||||
}
|
||||
|
||||
-#define BOOST_EXCEPTION_STATIC_TYPEID(T) ::boost::exception_detail::type_info_(BOOST_SP_TYPEID(T))
|
||||
+#define BOOST_EXCEPTION_STATIC_TYPEID(T) ::boost::typeind::type_id<T>()
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
-#define BOOST_EXCEPTION_DYNAMIC_TYPEID(x) ::boost::exception_detail::type_info_(typeid(x))
|
||||
+#define BOOST_EXCEPTION_DYNAMIC_TYPEID(x) ::boost::typeind::type_id_runtime(x)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
|
||||
diff --git a/include/boost/exception/diagnostic_information.hpp b/include/boost/exception/diagnostic_information.hpp
|
||||
index 2f5cb88..0f8b5e8 100644
|
||||
--- a/include/boost/exception/diagnostic_information.hpp
|
||||
+++ b/include/boost/exception/diagnostic_information.hpp
|
||||
@@ -151,7 +151,7 @@ boost
|
||||
#ifndef BOOST_NO_RTTI
|
||||
if ( verbose )
|
||||
tmp << std::string("Dynamic exception type: ") <<
|
||||
- /*units::detail::demangle*/((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n';
|
||||
+ /*units::detail::demangle*/((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se)))) << '\n';
|
||||
#endif
|
||||
if( with_what && se && verbose )
|
||||
tmp << "std::exception::what: " << wh << '\n';
|
||||
diff --git a/include/boost/exception/exception.hpp b/include/boost/exception/exception.hpp
|
||||
index 9f20a04..53c341f 100644
|
||||
--- a/include/boost/exception/exception.hpp
|
||||
+++ b/include/boost/exception/exception.hpp
|
||||
@@ -12,6 +12,8 @@
|
||||
#pragma warning(push,1)
|
||||
#endif
|
||||
|
||||
+#include <boost/exception/detail/type_info.hpp>
|
||||
+
|
||||
namespace
|
||||
boost
|
||||
{
|
||||
@@ -151,7 +153,6 @@ boost
|
||||
exception_detail
|
||||
{
|
||||
class error_info_base;
|
||||
- struct type_info_;
|
||||
|
||||
struct
|
||||
error_info_container
|
||||
diff --git a/include/boost/exception/info.hpp b/include/boost/exception/info.hpp
|
||||
index edbf058..e0f4950 100644
|
||||
--- a/include/boost/exception/info.hpp
|
||||
+++ b/include/boost/exception/info.hpp
|
||||
@@ -96,7 +96,7 @@ boost
|
||||
{
|
||||
shared_ptr<error_info_base> const & p = i->second;
|
||||
#ifndef BOOST_NO_RTTI
|
||||
- BOOST_ASSERT( *BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==*ti.type_ );
|
||||
+ BOOST_ASSERT(BOOST_EXCEPTION_DYNAMIC_TYPEID(*p)==ti );
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
|
||||
index d2dfcd6..5bd076d 100644
|
||||
--- a/test/Jamfile.v2
|
||||
+++ b/test/Jamfile.v2
|
||||
@@ -35,7 +35,9 @@ run enable_error_info_test.cpp helper1.cpp ;
|
||||
run throw_exception_test.cpp helper2.cpp ;
|
||||
run errno_test.cpp ;
|
||||
run error_info_test.cpp ;
|
||||
+run error_info_test.cpp : : : <rtti>off : error_info_test_rtti ;
|
||||
run diagnostic_information_test.cpp ;
|
||||
+run diagnostic_information_test.cpp : : : <rtti>off : diagnostic_information_test_rtti ;
|
||||
run refcount_ptr_test.cpp ;
|
||||
run current_exception_cast_test.cpp ;
|
||||
run no_exceptions_test.cpp : : : <exception-handling>off ;
|
||||
--
|
||||
1.8.5.3
|
||||
|
26
patched/boost_smart_ptr.patch
Normal file
26
patched/boost_smart_ptr.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 03194eefcb9c3314054855d28bd9a90d3188768d Mon Sep 17 00:00:00 2001
|
||||
From: Antony Polukhin <antoshkka@gmail.com>
|
||||
Date: Thu, 20 Feb 2014 18:50:10 +0400
|
||||
Subject: [PATCH] Use TypeIndex features in Boost.SharedPtr to avoid type_info
|
||||
related bugs
|
||||
|
||||
---
|
||||
include/boost/smart_ptr/detail/sp_counted_impl.hpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp
|
||||
index a7b43ae..5955036 100644
|
||||
--- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp
|
||||
+++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp
|
||||
@@ -155,7 +155,7 @@ public:
|
||||
|
||||
virtual void * get_deleter( detail::sp_typeinfo const & ti )
|
||||
{
|
||||
- return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
|
||||
+ return ti == boost::typeind::type_id<D>()? &reinterpret_cast<char&>( del ): 0;
|
||||
}
|
||||
|
||||
virtual void * get_untyped_deleter()
|
||||
--
|
||||
1.8.5.3
|
||||
|
@ -1 +0,0 @@
|
||||
To be honest sp_typeinfo.hpp won't be required with Boost.TypeIndex, because Boost.TypeIndex is more functional then sp_typeinfo and requires much less macro for usage. sp_typeinfo.patch contains a temporary solution for easy migration. Later sp_typeinfo may be removed and BOOST_SP_TYPEID(T) macro deprecated.
|
@ -1,23 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -59,6 +59,10 @@
|
||||
/boost/test//boost_test_exec_monitor/<link>static
|
||||
../build//boost_graph
|
||||
../../regex/build//boost_regex : --log_level=all ]
|
||||
+ [ run graphviz_test.cpp
|
||||
+ /boost/test//boost_test_exec_monitor/<link>static
|
||||
+ ../build//boost_graph
|
||||
+ ../../regex/build//boost_regex : --log_level=all : : <rtti>off : testing_graphviz_no_rtti ]
|
||||
[ run metis_test.cpp : $(METIS_INPUT_FILE) ]
|
||||
[ run gursoy_atun_layout_test.cpp ]
|
||||
[ run layout_test.cpp : : : <test-info>always_show_run_output <toolset>intel:<debug-symbols>off ]
|
||||
@@ -124,6 +128,7 @@
|
||||
[ run two_graphs_common_spanning_trees_test.cpp ]
|
||||
[ run random_spanning_tree_test.cpp ../build//boost_graph ]
|
||||
[ run graphml_test.cpp ../build//boost_graph : : "graphml_test.xml" ]
|
||||
+ [ run graphml_test.cpp ../build//boost_graph : : "graphml_test.xml" : <rtti>off : testing_graphml_no_rtti ]
|
||||
[ run mas_test.cpp ../../test/build//boost_unit_test_framework/<link>static : $(TEST_DIR) ]
|
||||
[ run stoer_wagner_test.cpp ../../test/build//boost_unit_test_framework/<link>static : $(TEST_DIR) ]
|
||||
[ compile filtered_graph_properties_dijkstra.cpp ]
|
@ -1,83 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/graph/dll_import_export.hpp>
|
||||
#include <boost/graph/graphviz.hpp> // for exceptions
|
||||
-#include <typeinfo>
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/find.hpp>
|
||||
@@ -218,16 +218,16 @@
|
||||
class get_type_name
|
||||
{
|
||||
public:
|
||||
- get_type_name(const std::type_info& type, const char** type_names, std::string& type_name)
|
||||
+ get_type_name(const boost::type_info& type, const char** type_names, std::string& type_name)
|
||||
: m_type(type), m_type_names(type_names), m_type_name(type_name) {}
|
||||
template <typename Type>
|
||||
void operator()(Type)
|
||||
{
|
||||
- if (typeid(Type) == m_type)
|
||||
+ if (boost::type_id<Type>() == m_type)
|
||||
m_type_name = m_type_names[mpl::find<Types,Type>::type::pos::value];
|
||||
}
|
||||
private:
|
||||
- const std::type_info &m_type;
|
||||
+ const boost::type_info &m_type;
|
||||
const char** m_type_names;
|
||||
std::string &m_type_name;
|
||||
};
|
||||
@@ -262,18 +262,18 @@
|
||||
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
|
||||
{
|
||||
std::string key_id = "key" + lexical_cast<std::string>(key_count++);
|
||||
- if (i->second->key() == typeid(Graph*))
|
||||
+ if (i->second->key() == boost::type_id<Graph*>())
|
||||
graph_key_ids[i->first] = key_id;
|
||||
- else if (i->second->key() == typeid(vertex_descriptor))
|
||||
+ else if (i->second->key() == boost::type_id<vertex_descriptor>())
|
||||
vertex_key_ids[i->first] = key_id;
|
||||
- else if (i->second->key() == typeid(edge_descriptor))
|
||||
+ else if (i->second->key() == boost::type_id<edge_descriptor>())
|
||||
edge_key_ids[i->first] = key_id;
|
||||
else
|
||||
continue;
|
||||
std::string type_name = "string";
|
||||
mpl::for_each<value_types>(get_type_name<value_types>(i->second->value(), type_names, type_name));
|
||||
out << " <key id=\"" << encode_char_entities(key_id) << "\" for=\""
|
||||
- << (i->second->key() == typeid(Graph*) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\""
|
||||
+ << (i->second->key() == boost::type_id<Graph*>() ? "graph" : (i->second->key() == boost::type_id<vertex_descriptor>() ? "node" : "edge")) << "\""
|
||||
<< " attr.name=\"" << i->first << "\""
|
||||
<< " attr.type=\"" << type_name << "\""
|
||||
<< " />\n";
|
||||
@@ -287,7 +287,7 @@
|
||||
// Output graph data
|
||||
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
|
||||
{
|
||||
- if (i->second->key() == typeid(Graph*))
|
||||
+ if (i->second->key() == boost::type_id<Graph*>())
|
||||
{
|
||||
// The const_cast here is just to get typeid correct for property
|
||||
// map key; the graph should not be mutated using it.
|
||||
@@ -304,7 +304,7 @@
|
||||
// Output data
|
||||
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
|
||||
{
|
||||
- if (i->second->key() == typeid(vertex_descriptor))
|
||||
+ if (i->second->key() == boost::type_id<vertex_descriptor>())
|
||||
{
|
||||
out << " <data key=\"" << vertex_key_ids[i->first] << "\">"
|
||||
<< encode_char_entities(i->second->get_string(*v)) << "</data>\n";
|
||||
@@ -325,7 +325,7 @@
|
||||
// Output data
|
||||
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
|
||||
{
|
||||
- if (i->second->key() == typeid(edge_descriptor))
|
||||
+ if (i->second->key() == boost::type_id<edge_descriptor>())
|
||||
{
|
||||
out << " <data key=\"" << edge_key_ids[i->first] << "\">"
|
||||
<< encode_char_entities(i->second->get_string(*e)) << "</data>\n";
|
@ -1,30 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdio.h> // for FILE
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
@@ -489,7 +490,7 @@
|
||||
bool first = true;
|
||||
for (dynamic_properties::const_iterator i = dp->begin();
|
||||
i != dp->end(); ++i) {
|
||||
- if (typeid(key) == i->second->key()) {
|
||||
+ if (boost::type_id<Descriptor>() == i->second->key()) {
|
||||
if (first) out << " [";
|
||||
else out << ", ";
|
||||
first = false;
|
||||
@@ -518,7 +519,7 @@
|
||||
bool first = true;
|
||||
for (dynamic_properties::const_iterator i = dp->begin();
|
||||
i != dp->end(); ++i) {
|
||||
- if (typeid(key) == i->second->key()
|
||||
+ if (boost::type_id<Descriptor>() == i->second->key()
|
||||
&& i->first != *node_id) {
|
||||
if (first) out << " [";
|
||||
else out << ", ";
|
@ -1,40 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
#include <boost/random/uniform_int.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
-#include <typeinfo>
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
|
||||
namespace boost { namespace parallel {
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
virtual void* address() { return &distribution_; }
|
||||
virtual const void* address() const { return &distribution_; }
|
||||
- virtual const std::type_info& type() const { return typeid(Distribution); }
|
||||
+ virtual const boost::type_info& type() const { return boost::type_id<Distribution>(); }
|
||||
|
||||
private:
|
||||
Distribution distribution_;
|
||||
@@ -106,7 +106,7 @@
|
||||
template<typename T>
|
||||
T* as()
|
||||
{
|
||||
- if (distribution_->type() == typeid(T))
|
||||
+ if (distribution_->type() == boost::type_id<T>())
|
||||
return static_cast<T*>(distribution_->address());
|
||||
else
|
||||
return 0;
|
||||
@@ -115,7 +115,7 @@
|
||||
template<typename T>
|
||||
const T* as() const
|
||||
{
|
||||
- if (distribution_->type() == typeid(T))
|
||||
+ if (distribution_->type() == boost::type_id<T>())
|
||||
return static_cast<T*>(distribution_->address());
|
||||
else
|
||||
return 0;
|
@ -1,3 +0,0 @@
|
||||
This patch requires additional care.
|
||||
|
||||
It works and tested through the Boost.Graph tests, but in some places `typeid(variable)` were replaced with `typeid(Type)`.
|
@ -1,80 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/function/function3.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
-#include <typeinfo>
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
@@ -60,8 +60,8 @@
|
||||
virtual boost::any get(const any& key) = 0;
|
||||
virtual std::string get_string(const any& key) = 0;
|
||||
virtual void put(const any& key, const any& value) = 0;
|
||||
- virtual const std::type_info& key() const = 0;
|
||||
- virtual const std::type_info& value() const = 0;
|
||||
+ virtual const boost::type_info& key() const = 0;
|
||||
+ virtual const boost::type_info& value() const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
using boost::put;
|
||||
|
||||
key_type key = any_cast<key_type>(in_key);
|
||||
- if (in_value.type() == typeid(value_type)) {
|
||||
+ if (in_value.type() == boost::type_id<value_type>()) {
|
||||
put(property_map_, key, any_cast<value_type>(in_value));
|
||||
} else {
|
||||
// if in_value is an empty string, put a default constructed value_type.
|
||||
@@ -188,8 +188,8 @@
|
||||
writable_property_map_tag*>::value)>());
|
||||
}
|
||||
|
||||
- virtual const std::type_info& key() const { return typeid(key_type); }
|
||||
- virtual const std::type_info& value() const { return typeid(value_type); }
|
||||
+ virtual const boost::type_info& key() const { return boost::type_id<key_type>(); }
|
||||
+ virtual const boost::type_info& value() const { return boost::type_id<value_type>(); }
|
||||
|
||||
PropertyMap& base() { return property_map_; }
|
||||
const PropertyMap& base() const { return property_map_; }
|
||||
@@ -283,7 +283,7 @@
|
||||
{
|
||||
for (dynamic_properties::iterator i = dp.lower_bound(name);
|
||||
i != dp.end() && i->first == name; ++i) {
|
||||
- if (i->second->key() == typeid(key)) {
|
||||
+ if (i->second->key() == boost::type_id<Key>()) {
|
||||
i->second->put(key, value);
|
||||
return true;
|
||||
}
|
||||
@@ -305,7 +305,7 @@
|
||||
{
|
||||
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
|
||||
i != dp.end() && i->first == name; ++i) {
|
||||
- if (i->second->key() == typeid(key))
|
||||
+ if (i->second->key() == boost::type_id<Key>())
|
||||
return any_cast<Value>(i->second->get(key));
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@
|
||||
{
|
||||
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
|
||||
i != dp.end() && i->first == name; ++i) {
|
||||
- if (i->second->key() == typeid(key))
|
||||
+ if (i->second->key() == boost::type_id<Key>())
|
||||
return any_cast<Value>(i->second->get(key));
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@
|
||||
{
|
||||
for (dynamic_properties::const_iterator i = dp.lower_bound(name);
|
||||
i != dp.end() && i->first == name; ++i) {
|
||||
- if (i->second->key() == typeid(key))
|
||||
+ if (i->second->key() == boost::type_id<Key>())
|
||||
return i->second->get_string(key);
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -650,7 +650,7 @@
|
||||
}
|
||||
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
|
||||
std::string("conversion of data to type \"") +
|
||||
- typeid(Type).name() + "\" failed", data()));
|
||||
+ boost::type_id<Type>().name_demangled() + "\" failed", data()));
|
||||
}
|
||||
|
||||
template<class K, class D, class C>
|
||||
@@ -805,7 +805,7 @@
|
||||
data() = *o;
|
||||
} else {
|
||||
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
|
||||
- std::string("conversion of type \"") + typeid(Type).name() +
|
||||
+ std::string("conversion of type \"") + boost::type_id<Type>().name_demangled() +
|
||||
"\" to data failed", boost::any()));
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86532)
|
||||
+++ . (working copy)
|
||||
@@ -53,6 +53,7 @@
|
||||
<toolset>clang:<cxxflags>-fno-exceptions
|
||||
: variant_noexcept_test
|
||||
]
|
||||
+ [ run recursive_variant_test.cpp : : : <rtti>off : variant_nortti_test ]
|
||||
[ run variant_swap_test.cpp ]
|
||||
;
|
||||
|
@ -1,57 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86532)
|
||||
+++ . (working copy)
|
||||
@@ -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/type_info.hpp"
|
||||
|
||||
#include "boost/variant/detail/config.hpp"
|
||||
#include "boost/mpl/aux_/value_wknd.hpp"
|
||||
@@ -830,23 +828,19 @@
|
||||
// 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::type_info&>
|
||||
{
|
||||
public: // visitor interfaces
|
||||
|
||||
template <typename T>
|
||||
- const std::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
+ const boost::type_info& operator()(const T&) const BOOST_NOEXCEPT
|
||||
{
|
||||
- return typeid(T);
|
||||
+ return boost::type_id<T>();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
-#endif // BOOST_NO_TYPEID
|
||||
-
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// (detail) class comparer
|
||||
//
|
||||
@@ -2155,13 +2149,11 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
-#if !defined(BOOST_NO_TYPEID)
|
||||
- const std::type_info& type() const
|
||||
+ const boost::type_info& type() const
|
||||
{
|
||||
detail::variant::reflect visitor;
|
||||
return this->apply_visitor(visitor);
|
||||
}
|
||||
-#endif
|
||||
|
||||
public: // prevent comparison with foreign types
|
||||
|
@ -1,38 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -19,7 +19,7 @@
|
||||
#endif
|
||||
#include <stack>
|
||||
#include <limits>
|
||||
-#include <typeinfo>
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/version.hpp>
|
||||
@@ -144,7 +144,7 @@
|
||||
explicit xpression_linker(Traits const &tr)
|
||||
: back_stack_()
|
||||
, traits_(&tr)
|
||||
- , traits_type_(&typeid(Traits))
|
||||
+ , traits_type_(&boost::type_id<Traits>())
|
||||
, has_backrefs_(false)
|
||||
{
|
||||
}
|
||||
@@ -310,13 +310,13 @@
|
||||
template<typename Traits>
|
||||
Traits const &get_traits() const
|
||||
{
|
||||
- BOOST_ASSERT(*this->traits_type_ == typeid(Traits));
|
||||
+ BOOST_ASSERT(*this->traits_type_ == boost::type_id<Traits>());
|
||||
return *static_cast<Traits const *>(this->traits_);
|
||||
}
|
||||
|
||||
std::stack<void const *> back_stack_;
|
||||
void const *traits_;
|
||||
- std::type_info const *traits_type_;
|
||||
+ boost::type_info const *traits_type_;
|
||||
bool has_backrefs_;
|
||||
};
|
||||
|
@ -1,33 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -25,9 +25,9 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
-#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include <boost/config.hpp>
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/integer.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
@@ -72,7 +72,7 @@
|
||||
//
|
||||
struct type_info_less
|
||||
{
|
||||
- bool operator()(std::type_info const *left, std::type_info const *right) const
|
||||
+ bool operator()(boost::type_info const *left, boost::type_info const *right) const
|
||||
{
|
||||
return 0 != left->before(*right);
|
||||
}
|
||||
@@ -679,7 +679,7 @@
|
||||
typedef typename proto::result_of::value<right_type>::type arg_right_type;
|
||||
BOOST_MPL_ASSERT((proto::matches<Arg, detail::ActionArgBinding>));
|
||||
BOOST_MPL_ASSERT((is_same<typename arg_left_type::type, arg_right_type>));
|
||||
- this->args_[&typeid(proto::value(proto::left(arg)))] = &proto::value(proto::right(arg));
|
||||
+ this->args_[&boost::type_id<arg_left_type>()] = &proto::value(proto::right(arg));
|
||||
return *this;
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
Index: .
|
||||
===================================================================
|
||||
--- . (revision 86520)
|
||||
+++ . (working copy)
|
||||
@@ -14,7 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
-#include <typeinfo>
|
||||
+#include <boost/type_index/type_info.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
@@ -250,9 +250,9 @@
|
||||
if(0 == this->traits_)
|
||||
{
|
||||
this->traits_ = &tr;
|
||||
- this->traits_type_ = &typeid(Traits);
|
||||
+ this->traits_type_ = &boost::type_id<Traits>();
|
||||
}
|
||||
- else if(*this->traits_type_ != typeid(Traits) || this->get_traits_<Traits>() != tr)
|
||||
+ else if(*this->traits_type_ != boost::type_id<Traits>() || this->get_traits_<Traits>() != tr)
|
||||
{
|
||||
this->fail(); // traits mis-match! set all and bail
|
||||
}
|
||||
@@ -265,7 +265,7 @@
|
||||
template<typename Traits>
|
||||
Traits const &get_traits_() const
|
||||
{
|
||||
- BOOST_ASSERT(!!(*this->traits_type_ == typeid(Traits)));
|
||||
+ BOOST_ASSERT(!!(*this->traits_type_ == boost::type_id<Traits>()));
|
||||
return *static_cast<Traits const *>(this->traits_);
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
bool str_icase_;
|
||||
bool line_start_;
|
||||
void const *traits_;
|
||||
- std::type_info const *traits_type_;
|
||||
+ boost::type_info const *traits_type_;
|
||||
int leading_simple_repeat_;
|
||||
bool has_backrefs_;
|
||||
};
|
81
test/Jamfile.v2
Normal file
81
test/Jamfile.v2
Normal file
@ -0,0 +1,81 @@
|
||||
# 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)
|
||||
#
|
||||
|
||||
import testing ;
|
||||
import feature ;
|
||||
import os ;
|
||||
|
||||
# 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.
|
||||
# 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 $(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) ;
|
||||
obj test_lib_rtti_compat-obj : test_lib.cpp : <link>shared $(nortti) $(compat) ;
|
||||
lib test_lib_nortti_compat : test_lib_nortti_compat-obj : <link>shared $(nortti) $(compat) ;
|
||||
lib test_lib_rtti_compat : test_lib_rtti_compat-obj : <link>shared $(nortti) $(compat) ;
|
||||
|
||||
exe testing_crossmodule_anonymous_no_rtti : testing_crossmodule_anonymous.cpp test_lib_anonymous_nortti : <rtti>off $(norttidefines) ;
|
||||
|
||||
test-suite type_index
|
||||
:
|
||||
[ run type_index_test.cpp ]
|
||||
[ run type_index_runtime_cast_test.cpp ]
|
||||
[ run type_index_constexpr_test.cpp ]
|
||||
[ run type_index_test.cpp : : : <rtti>off $(norttidefines) : type_index_test_no_rtti ]
|
||||
[ run ctti_print_name.cpp : : : <test-info>always_show_run_output ]
|
||||
[ run testing_crossmodule.cpp test_lib_rtti ]
|
||||
[ run testing_crossmodule.cpp test_lib_nortti : : : <rtti>off $(norttidefines) : testing_crossmodule_no_rtti ]
|
||||
[ run testing_crossmodule_anonymous.cpp test_lib_anonymous_rtti : : : <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
|
||||
|
||||
# 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.
|
||||
for local p in [ glob ../examples/*.cpp ]
|
||||
{
|
||||
# RTTI on
|
||||
type_index += [ run $(p) ] ;
|
||||
|
||||
# RTTI off
|
||||
local target_name = $(p[1]:B)_no_rtti ;
|
||||
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;
|
||||
}
|
||||
|
40
test/test_lib.cpp
Normal file
40
test/test_lib.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// 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"
|
||||
|
||||
namespace user_defined_namespace {
|
||||
class user_defined{};
|
||||
}
|
||||
|
||||
namespace test_lib {
|
||||
|
||||
boost::typeindex::type_index get_integer() {
|
||||
return boost::typeindex::type_id<int>();
|
||||
}
|
||||
|
||||
boost::typeindex::type_index get_user_defined_class() {
|
||||
return boost::typeindex::type_id<user_defined_namespace::user_defined>();
|
||||
}
|
||||
|
||||
boost::typeindex::type_index get_const_integer() {
|
||||
return boost::typeindex::type_id_with_cvr<const int>();
|
||||
}
|
||||
|
||||
boost::typeindex::type_index get_const_user_defined_class() {
|
||||
return boost::typeindex::type_id_with_cvr<const user_defined_namespace::user_defined>();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
|
||||
// Just do nothing
|
||||
void accept_typeindex(const boost::typeindex::type_index&) {}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2013.
|
||||
// Copyright 2012-2022 Antony Polukhin.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -25,14 +25,16 @@
|
||||
|
||||
namespace test_lib {
|
||||
|
||||
TEST_LIB_DECL boost::type_index get_integer();
|
||||
TEST_LIB_DECL boost::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::type_index get_const_integer();
|
||||
TEST_LIB_DECL boost::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::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
|
||||
|
57
test/testing_crossmodule.cpp
Normal file
57
test/testing_crossmodule.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
//
|
||||
// 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/type_index.hpp>
|
||||
#include "test_lib.hpp"
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
namespace user_defined_namespace {
|
||||
class user_defined{};
|
||||
}
|
||||
|
||||
void comparing_types_between_modules()
|
||||
{
|
||||
boost::typeindex::type_index t_const_int = boost::typeindex::type_id_with_cvr<const int>();
|
||||
boost::typeindex::type_index t_int = boost::typeindex::type_id<int>();
|
||||
|
||||
BOOST_TEST_EQ(t_int, test_lib::get_integer());
|
||||
BOOST_TEST_EQ(t_const_int, test_lib::get_const_integer());
|
||||
BOOST_TEST_NE(t_const_int, test_lib::get_integer());
|
||||
BOOST_TEST_NE(t_int, test_lib::get_const_integer());
|
||||
|
||||
|
||||
boost::typeindex::type_index t_const_userdef
|
||||
= 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_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_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());
|
||||
|
||||
// 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();
|
||||
}
|
400
test/type_index_test.cpp
Normal file
400
test/type_index_test.cpp
Normal file
@ -0,0 +1,400 @@
|
||||
//
|
||||
// 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/type_index.hpp>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
namespace my_namespace1 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
|
||||
namespace my_namespace2 {
|
||||
class my_class{};
|
||||
}
|
||||
|
||||
|
||||
void names_matches_type_id()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
BOOST_TEST_EQ(type_id<int>().pretty_name(), "int");
|
||||
BOOST_TEST_EQ(type_id<double>().pretty_name(), "double");
|
||||
|
||||
BOOST_TEST_EQ(type_id<int>().name(), type_id<int>().name());
|
||||
BOOST_TEST_NE(type_id<int>().name(), type_id<double>().name());
|
||||
BOOST_TEST_NE(type_id<double>().name(), type_id<int>().name());
|
||||
BOOST_TEST_EQ(type_id<double>().name(), type_id<double>().name());
|
||||
}
|
||||
|
||||
void default_construction()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
type_index ti1, ti2;
|
||||
BOOST_TEST_EQ(ti1, ti2);
|
||||
BOOST_TEST_EQ(type_id<void>(), ti1);
|
||||
|
||||
BOOST_TEST_EQ(type_id<void>().name(), ti1.name());
|
||||
BOOST_TEST_NE(type_id<int>(), ti1);
|
||||
}
|
||||
|
||||
|
||||
void copy_construction()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
type_index ti1, ti2 = type_id<int>();
|
||||
BOOST_TEST_NE(ti1, ti2);
|
||||
ti1 = ti2;
|
||||
BOOST_TEST_EQ(ti2, ti1);
|
||||
|
||||
const type_index ti3(ti1);
|
||||
BOOST_TEST_EQ(ti3, ti1);
|
||||
}
|
||||
|
||||
void comparators_type_id()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
type_index t_int = type_id<int>();
|
||||
type_index t_double = type_id<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_TEST_LE(t_double, t_double);
|
||||
BOOST_TEST_GE(t_double, t_double);
|
||||
BOOST_TEST_NE(t_double, t_int);
|
||||
|
||||
BOOST_TEST(t_double < t_int || t_int < t_double);
|
||||
BOOST_TEST(t_double > t_int || t_int > t_double);
|
||||
}
|
||||
|
||||
void hash_code_type_id()
|
||||
{
|
||||
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_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::typeindex;
|
||||
|
||||
type_index t1 = type_id_with_cvr<T1>();
|
||||
type_index t2 = type_id_with_cvr<T2>();
|
||||
|
||||
BOOST_TEST_NE(t2, t1);
|
||||
BOOST_TEST(t2 != t1.type_info());
|
||||
BOOST_TEST(t2.type_info() != t1);
|
||||
|
||||
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 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_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_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_TEST_NE(t1.hash_code(), type_id_with_cvr<T2>().hash_code());
|
||||
BOOST_TEST_NE(t2.hash_code(), type_id_with_cvr<T1>().hash_code());
|
||||
}
|
||||
|
||||
void type_id_storing_modifiers()
|
||||
{
|
||||
test_with_modofiers<int, const int>();
|
||||
test_with_modofiers<int, const int&>();
|
||||
test_with_modofiers<int, int&>();
|
||||
test_with_modofiers<int, volatile int>();
|
||||
test_with_modofiers<int, volatile int&>();
|
||||
test_with_modofiers<int, const volatile int>();
|
||||
test_with_modofiers<int, const volatile int&>();
|
||||
|
||||
test_with_modofiers<const int, int>();
|
||||
test_with_modofiers<const int, const int&>();
|
||||
test_with_modofiers<const int, int&>();
|
||||
test_with_modofiers<const int, volatile int>();
|
||||
test_with_modofiers<const int, volatile int&>();
|
||||
test_with_modofiers<const int, const volatile int>();
|
||||
test_with_modofiers<const int, const volatile int&>();
|
||||
|
||||
test_with_modofiers<const int&, int>();
|
||||
test_with_modofiers<const int&, const int>();
|
||||
test_with_modofiers<const int&, int&>();
|
||||
test_with_modofiers<const int&, volatile int>();
|
||||
test_with_modofiers<const int&, volatile int&>();
|
||||
test_with_modofiers<const int&, const volatile int>();
|
||||
test_with_modofiers<const int&, const volatile int&>();
|
||||
|
||||
test_with_modofiers<int&, const int>();
|
||||
test_with_modofiers<int&, const int&>();
|
||||
test_with_modofiers<int&, int>();
|
||||
test_with_modofiers<int&, volatile int>();
|
||||
test_with_modofiers<int&, volatile int&>();
|
||||
test_with_modofiers<int&, const volatile int>();
|
||||
test_with_modofiers<int&, const volatile int&>();
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
test_with_modofiers<int&&, const int>();
|
||||
test_with_modofiers<int&&, const int&>();
|
||||
test_with_modofiers<int&&, const int&&>();
|
||||
test_with_modofiers<int&&, int>();
|
||||
test_with_modofiers<int&&, volatile int>();
|
||||
test_with_modofiers<int&&, volatile int&>();
|
||||
test_with_modofiers<int&&, volatile int&&>();
|
||||
test_with_modofiers<int&&, const volatile int>();
|
||||
test_with_modofiers<int&&, const volatile int&>();
|
||||
test_with_modofiers<int&&, const volatile int&&>();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void test_storing_nonstoring_modifiers_templ() {
|
||||
using namespace boost::typeindex;
|
||||
|
||||
type_index t1 = type_id_with_cvr<T>();
|
||||
type_index t2 = type_id<T>();
|
||||
|
||||
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_TEST_EQ(t2.pretty_name(), t1.pretty_name());
|
||||
}
|
||||
|
||||
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::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");
|
||||
}
|
||||
|
||||
void type_index_stream_operator_via_lexical_cast_testing()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
|
||||
std::string s_int2 = boost::lexical_cast<std::string>(type_id<int>());
|
||||
BOOST_TEST_EQ(s_int2, "int");
|
||||
|
||||
std::string s_double2 = boost::lexical_cast<std::string>(type_id<double>());
|
||||
BOOST_TEST_EQ(s_double2, "double");
|
||||
}
|
||||
|
||||
void type_index_stripping_cvr_test()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
|
||||
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_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_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_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&>());
|
||||
}
|
||||
|
||||
|
||||
void type_index_user_defined_class_test()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
|
||||
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_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_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
|
||||
virtual ~A(){}
|
||||
};
|
||||
|
||||
struct B: public A {
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
};
|
||||
|
||||
struct C: public B {
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
};
|
||||
|
||||
void comparators_type_id_runtime()
|
||||
{
|
||||
C c1;
|
||||
B b1;
|
||||
A* pc1 = &c1;
|
||||
A& rc1 = c1;
|
||||
A* pb1 = &b1;
|
||||
A& rb1 = b1;
|
||||
|
||||
#ifndef BOOST_NO_RTTI
|
||||
BOOST_TEST(typeid(rc1) == typeid(*pc1));
|
||||
BOOST_TEST(typeid(rb1) == typeid(*pb1));
|
||||
|
||||
BOOST_TEST(typeid(rc1) != typeid(*pb1));
|
||||
BOOST_TEST(typeid(rb1) != typeid(*pc1));
|
||||
|
||||
BOOST_TEST(typeid(&rc1) == typeid(pb1));
|
||||
BOOST_TEST(typeid(&rb1) == typeid(pc1));
|
||||
#else
|
||||
BOOST_TEST(boost::typeindex::type_index(pc1->boost_type_index_type_id_runtime_()).raw_name());
|
||||
#endif
|
||||
|
||||
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_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_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_TEST(boost::typeindex::type_id_runtime(rc1) == typeid(*pc1));
|
||||
BOOST_TEST(boost::typeindex::type_id_runtime(rb1) == typeid(*pb1));
|
||||
|
||||
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
|
||||
|
||||
void comparators_type_id_vs_type_info()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
type_index t_int = type_id<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_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_TEST(t_double < typeid(int));
|
||||
BOOST_TEST(typeid(double) < t_int);
|
||||
BOOST_TEST(typeid(int) > t_double);
|
||||
BOOST_TEST(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_TEST(t_double > typeid(int));
|
||||
BOOST_TEST(typeid(double) > t_int);
|
||||
BOOST_TEST(typeid(int) < t_double);
|
||||
BOOST_TEST(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();
|
||||
}
|
||||
|
18
test/type_index_test_ctti_alignment.cpp
Normal file
18
test/type_index_test_ctti_alignment.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// 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/type_index/ctti_type_index.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
int main() {
|
||||
BOOST_STATIC_ASSERT_MSG(
|
||||
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."
|
||||
);
|
||||
}
|
||||
|
15
test/type_index_test_ctti_construct_fail.cpp
Normal file
15
test/type_index_test_ctti_construct_fail.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// 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/type_index/ctti_type_index.hpp>
|
||||
|
||||
int main() {
|
||||
using namespace boost::typeindex;
|
||||
ctti_type_index::type_info_t t;
|
||||
(void)t;
|
||||
}
|
||||
|
15
test/type_index_test_ctti_copy_fail.cpp
Normal file
15
test/type_index_test_ctti_copy_fail.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// 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/type_index/ctti_type_index.hpp>
|
||||
|
||||
int main() {
|
||||
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