Compare commits

...

215 Commits

Author SHA1 Message Date
bdfd7b91c2 Rework as esp-idf component 2023-11-23 17:17:05 +01:00
cca370a918 update copyright years 2022-01-30 15:01:13 +03:00
97fc5b9838 do not use depth 1 for checkouts in CI 2021-09-20 21:56:00 +03:00
0cc169ecd6 modernize CI setup 2021-09-11 18:18:54 +03:00
a3c6a957ee Update CMakeLists.txt 2021-06-10 00:48:35 +03:00
04cc1734ef use HTTPS links in Readme 2021-04-27 11:22:44 +03:00
f395836779 gather coverage in CI from more platforms 2021-04-24 21:53:20 +03:00
4f51b1f4eb update Readme with new CI links and new doc links, do not gather coverage twice, remove drone 2021-04-24 18:53:27 +03:00
a2ef72c907 CI updates: proper setup of clang-7 and restore sanitizers for gcc-10 2021-04-24 14:28:28 +03:00
331c26760e Use clang-7 in CI instead of clang-3.8; do not sanitize with GCC-10 2021-04-24 14:20:46 +03:00
d6d07a8ce8 add missing include and do not tests on clang-3.7 2021-04-24 13:49:52 +03:00
4468903f8f modernize CI 2021-04-24 12:47:19 +03:00
88c5d9a998 fix broken link 2021-04-24 12:46:59 +03:00
f0b87ea7d3 Merge pull request #35 from sdarwin/githubactions
GitHub Actions config
2021-04-18 14:10:35 +03:00
03794d6144 Add GitHub Actions config [ci skip] 2021-03-04 18:22:58 +00:00
62154d3b19 Merge pull request #33 from sdarwin/drone
Drone config
2021-01-27 10:29:41 +03:00
b4014f385d Merge pull request #32 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-01-27 10:25:31 +03:00
0dc42bab8f add drone config [ci skip] 2021-01-26 15:29:49 +00:00
a4726d239f [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-21 16:26:02 -05:00
f40f4731e1 Merge github.com:apolukhin/type_index into develop 2021-01-04 18:29:36 +03:00
754fb0f348 CI fix attempt (1) 2021-01-04 13:32:09 +03:00
6fa4f57e7d CI fix attempt 2021-01-04 13:23:42 +03:00
c79f1c8d5d Specify address model for MSVC
Relates boostorg/build#659
2021-01-04 11:04:54 +03:00
843ee6848b update copyright years 2021-01-03 20:01:31 +03:00
6fc5b35b00 Merge pull request #31 from sdarwin/lcov
update .travis.yml to correct lcov error messages
2021-01-03 12:49:28 +03:00
84d68f32e2 update lcov in .travis.yml 2020-12-31 00:51:49 +00:00
1dacdb561e Merge pull request #29 from Kojoley/cease-dependence-on-smart_ptr
Cease dependence on SmartPtr
2020-08-27 12:03:36 +03:00
9862011b6b CI fixes 2020-07-06 11:36:48 +03:00
321749796e Cease dependence on SmartPtr
by forward declaring `boost::shared_ptr`
2020-05-26 02:56:12 +03:00
f2e395a7f3 update copyright years 2020-01-22 23:26:24 +03:00
9936c31851 Attempt to fix CI 2019-11-12 09:00:57 +03:00
560c7d2ef6 Change header file to include 2019-11-11 20:56:04 +03:00
bf33e63feb CI fixes 2019-11-11 18:47:46 +03:00
2152466531 CI fixes 2019-08-29 19:12:02 +03:00
389f621450 CI + inspect tool fixes 2019-08-29 16:00:48 +03:00
0b65c1a8d8 Disable some of the inspect tool checks 2019-08-28 20:59:16 +03:00
216c21b728 Fix issues found by inspect too and add it to CI 2019-08-28 17:54:46 +03:00
afd1b6cdc8 Merge pull request #28 from Breakthrough/develop
Add CTTI name prettifying for GHS C++ compiler.
2019-03-02 11:33:11 +03:00
d69a8a211b Add CTTI name prettifying for GHS C++ compiler. 2019-02-28 12:33:14 -05:00
ebe74ba4ba Merge pull request #27 from Mike-Devel/min_cmake
[CMake] Add minimal cmake file
2019-02-20 21:27:23 -10:00
ac4fec435f [CMake] Add minimal cmake support
CMake file only supports add_subdirectory workflow.
No installation and no unit tests.
2019-02-14 17:32:53 +01:00
f68d6dc073 update copyrights 2019-01-17 22:45:35 +03:00
85f43ece0d Merge remote-tracking branch 'lastique/optimize_ctti_strcmp' into develop 2018-12-23 12:24:16 +03:00
a2de6a56f3 Merge pull request #26 from boostorg/feature/ci-update
CI update: Better CI with many new platforms
2018-12-16 20:15:14 +03:00
c585d74669 Disable part of the tests for _MSC_VER == 1916 and below 2018-12-16 11:55:04 +03:00
32909cb25a fixes for tests 2018-12-16 11:30:59 +03:00
7af1661709 Fixes for travis CI 2018-12-15 22:06:18 +03:00
351cedf404 ADjust sanitizers in CI builds 2018-12-15 21:26:25 +03:00
098c84481e Merge branch 'develop' into feature/ci-update 2018-12-15 16:33:40 +03:00
d9d13b9574 ci update 2018-12-14 11:56:02 +03:00
44ca756e32 Merge pull request #25 from boostorg/pr/ctti-clang-win
Fix compile_time_type_info for clang-cl
2018-11-16 11:15:15 +03:00
acb536a67e Fix compile_time_type_info for clang-cl 2018-11-16 02:06:10 +02:00
7654c26594 Increase MSVC requirements for constexpr sorted test (refs #24) 2018-11-16 01:58:18 +03:00
075b3682ae Disable constexpr sort test for MSVC <= 1914 (refs #24) 2018-11-15 21:58:17 +03:00
a60e25a74d Better diagnostics for missing PRETTY_FUNCTION macro (refs #24) 2018-11-14 09:09:37 +03:00
cd1c905f87 Optimize string comparison used to implement CTTI comparison.
When the strings are known to be runtime objects, use compiler builtin
for strcmp for comparing strings. The compiler will generate a runtime
call for the (presumably, well-optimized) strcmp instead of rolling
a local per-character comparison loop. When the builtin is not available
or we cannot detect compile-time strings, use the local loop as before.

Also, when C++14 constexpr is not available, use strcmp right away,
since there is no use for the local loop in this case.
2018-10-28 02:56:30 +03:00
f3da852bca Update stl_type_index.hpp 2018-10-20 20:19:04 +03:00
a8fafd93f9 Merge pull request #21 from Kojoley/do-not-include-container-hash-if-possible
Do not include container_hash if possible
2018-10-20 20:12:07 +03:00
01944bf377 Do not include container_hash if possible
The `boost/container_hash/hash.hpp` has significant inclusion times.
Not including it results in 30% faster `boost/type_traits.hpp` parsing.
(kind of regression introduced in 82ed016577)
2018-10-20 19:59:20 +03:00
09f0bc23c5 fix b2 warnings 2018-09-22 22:13:42 +03:00
718af3e8dc Fix tests which did not return report_errors() 2018-09-17 07:43:19 -04:00
c9c1412a05 Tests to reproduce the track issue 13621 2018-07-28 17:44:17 +03:00
c2caa340ab Merge pull request #19 from jlapolla-cray/edg-ctti-support
CTTI parameters for EDG based compilers
2018-04-15 12:48:26 +03:00
da0a181117 ctti parameters for EDG based compilers
- Needed for Cray Compiling Environment to work with Boost.TypeIndex.
2018-04-10 09:19:22 -05:00
be9f5a4b9b Droped dependency on MPL 2018-03-24 09:50:37 +03:00
bd19ed1a87 Disable link-fail tests and restore MinGW CI 2018-01-23 10:40:56 +03:00
727cdadc86 Restore link-fail 2018-01-16 01:21:20 +03:00
5bc4f54183 Dropped -fail to check the MSVC builds 2018-01-16 01:10:28 +03:00
918e59c109 One more fix in tests for /GR- flag 2018-01-16 00:44:11 +03:00
cd659212aa Workaround for /GR- override in tests 2018-01-16 00:28:48 +03:00
70e51a62e9 Workaround for /GR- override that disables link time assertions 2018-01-15 23:21:34 +03:00
05feacf14b Relax comparing_anonymous_types_between_modules test as it was failing to too many builds (fixes #17) 2018-01-15 00:14:47 +03:00
82ed016577 Use hash_fwd header and use new paths to boost::hash* 2018-01-14 23:41:33 +03:00
1a7226bc0f Do not define BOOST_TEST_*E macros, as they are now defined in boost/core/lightweight_test.hpp 2017-10-01 22:30:59 +03:00
be08eda196 Do not suppress already suppressed warnings 2017-09-26 22:05:57 +03:00
baa5019c90 Merge pull request #16 from bebuch/develop
fix ctti_type_index for GCC 7
2017-07-29 20:13:04 +03:00
4585bab3c3 __PRETTY_FUNCTION__ is slightly different in GCC 7
The output of an unsigned int literal dosn't contain the u anymore.

	#include <iostream>

	template < typename T >
	struct ctti{
		template < unsigned int D = 1 >
		static constexpr auto name()noexcept{
			return __PRETTY_FUNCTION__;
		}
	};

	int main(){
		using ctti = ctti< int >;
		std::cout << ctti::name() << '\n';
	}
2017-07-28 15:07:19 +02:00
93e7b2458b Fixed some warnings 2017-06-25 14:05:08 +03:00
09ac338acc Fix compiler warnings about unused initialized variables, and unused formal parameters
Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-06-08 19:05:02 +02:00
b0737f4169 Fix formatting in README 2017-05-18 22:51:47 +03:00
be74716251 Use native hash_code() when possible on GCC-like compilers 2017-05-18 22:50:25 +03:00
f82eab8882 Merge pull request #15 from ecatmur/ecatmur-stl-hash
Include <boost/functional/hash.hpp> if required
2017-05-06 10:26:30 +03:00
af61d6b8ed Merge pull request #13 from cdglove/split_register_and_implement
Add support for using runtime_cast without requiring type_id_runtime.
2017-02-28 05:33:07 +04:00
d3d4e8d18a Change runtime cast test to use the separated macro (BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST) and add a new test that ensures BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS does indeed supply both functions. 2017-02-25 15:35:34 -05:00
7f8af2a6e9 Merge branch 'develop' into split_register_and_implement 2017-02-25 13:19:16 -05:00
342d835289 Run MinGW tests too (thanks to Pavel Filinov for showing that appveyor apability) 2017-02-23 21:35:40 +03:00
5cacb67510 Make it derived class responsibility to include <boost/functional/hash.hpp> 2017-02-16 21:55:12 +00:00
f2616bcd17 Correct preprocessor condition to match below 2017-02-16 16:30:52 +00:00
8c582362d0 Include <boost/functional/hash.hpp> if required 2017-02-16 16:18:48 +00:00
f71d9eb3f2 Fix undefined macro warning (trac 12739) 2017-01-18 22:33:13 +03:00
cfcdcd647d Update CI script version 2016-12-04 02:39:22 +03:00
8bee2f6939 Fix coverage info gathering in travisCI script for GCC-6 2016-12-04 02:29:02 +03:00
40985de221 Update CI scripts and tests 2016-11-18 22:31:01 +03:00
d8bdbad2ec Add BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST, which implementes the functionality for runtime_cast to function, but does not include the BOOST_TYPE_INDEX_REGISTER_CLASS macro.
Reimplement BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS to simply call BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST and BOOST_TYPE_INDEX_REGISTER_CLASS.

This allows users to opt-in to one or the other, instead of forcing them to generate both virtual functions.
2016-11-05 16:04:13 -04:00
c52fdfe30c Add, and update, documentation build targets. 2016-10-07 23:07:37 -05:00
7f840c882e Fix build in C++98 mode 2016-10-02 10:39:54 +03:00
b669f0244e Changed std::size_t to unsigned int in compile_time_type_infohelpers. Now the code is more platform independant. 2016-10-02 10:32:50 +03:00
d656e1879a Merge pull request #12 from cdglove/runtime_cast_test_fixes
Cleanup of shared_ptr ifdef.
2016-10-02 10:58:49 +04:00
b1ed011b6e Cleaner removal of std::shared_ptr tests on compilers without C++11 shared_ptr 2016-10-01 14:49:28 -04:00
4d1cf425e0 Merge pull request #11 from cdglove/runtime_cast_test_fixes
Runtime cast test fixes
2016-09-30 21:34:10 +04:00
d6ca24ff3c Merge branch 'runtime_cast' into runtime_cast_test_fixes 2016-09-29 22:31:07 -04:00
4459af9532 FIx a unit test so that the NULL check happens before the dereference. 2016-09-29 22:29:35 -04:00
b61a7423b7 Update unit test to remove shared_ptr on compilers less than C++11. 2016-09-29 22:29:10 -04:00
1a918009fd Fix comment. 2016-09-29 22:27:10 -04:00
045ab1d779 Merge pull request #8 from cdglove/runtime_cast
Add the concept of runtime_cast to type index as an emulation of dynamic_cast..
2016-09-29 00:45:39 +04:00
6cf5288a8c Merge pull request #9 from efcs/clang-4-fix
Support Clang version 4.0.
2016-08-30 22:43:14 +04:00
4453acf867 Support Clang 4.0 and newer 2016-08-29 22:10:34 -06:00
b6b23bad3a Cleanup line endings, file endings, some spacing etc. 2016-08-21 12:47:44 -04:00
3bb646d19b - Use boost::addressof instead of &
- Remove nullptr from test
- add boost::typeindex::bad_runtime_cast, remove std::bad_cast
2016-08-21 11:01:26 -04:00
9cd218bbc4 Add missing include to example. 2016-08-19 18:42:22 -04:00
ad26256d09 Initial documentation. 2016-08-11 10:31:16 -04:00
5af925602e Invoke smart_ptr tests. 2016-08-10 10:06:41 -04:00
2fb667a6a0 Experiment with a version of runtime_cast that has only a single registration macro. 2016-08-09 23:13:54 -04:00
12751e0f83 Split runtime_cast into several files so clients can selectively include only what they use.
Add support for shared_ptrs.
2016-08-09 14:51:36 -04:00
0b006b6af6 Remove all references to std::type_traits
Replace variadic template with boost preprocessor.
2016-08-08 12:16:58 -04:00
76cae485cb Merge branch 'runtime_cast' of github.com:cdglove/type_index into runtime_cast
# Conflicts:
#	include/boost/type_index/runtime_cast.hpp
#	test/runtime_cast_test.cpp
2016-07-15 17:18:42 -04:00
ee7b15a493 First version.
TODO: Error messages when using mismatched types are not clear. Needs consideration.
2016-07-15 16:30:16 -04:00
1dc8310826 Optimization: Don't check all bases. 2016-07-15 10:10:07 -04:00
b230140529 First version. 2016-07-15 08:49:54 -04:00
31ec1d2524 Fix link in README 2016-06-05 13:02:56 +03:00
40e9bd336a Test on same Boost branch when running Appveyor 2016-06-04 21:10:20 +03:00
767c724983 README now shows build status on Windows platform 2016-06-04 15:59:29 +03:00
24708cc109 One more example and integrate examples into the docs 2016-03-30 23:24:53 +03:00
57205874ae Added namespace detection example 2016-03-30 22:28:53 +03:00
1b4a85764f Fixing test under Windows 2016-03-29 23:16:17 +03:00
1976355e8f appveyor update 1 2016-03-29 22:36:12 +03:00
0efc48e16c Add appveyor integration and increment minor version of the library 2016-03-29 21:45:50 +03:00
e96a6e8f80 Use constexpr in documentation 2016-03-29 21:38:46 +03:00
8e3466ece5 Log(N) complexity and templates depth in make_index_seq_impl, avoid usage of slow sizeof...(I), workaround GCC ICE in constexpr tests 2016-03-29 21:21:04 +03:00
8b6c3facb3 Fixes and GCC related improvements 2016-03-28 22:42:39 +03:00
ffb98af0dd Attempt to use libc++ in TravisCi tests no. 6 2016-03-27 22:05:40 +03:00
9122022faf Attempt to use libc++ in TravisCi tests no. 5 2016-03-27 21:50:33 +03:00
18dbaea6ee Attempt to use libc++ in TravisCi tests no. 4 2016-03-27 21:42:08 +03:00
6dabf11504 Third attempt to use libc++ in TravisCi tests 2016-03-27 21:32:18 +03:00
7bd788c5d7 Second attempt to use libc++ in TravisCi tests 2016-03-27 21:27:10 +03:00
2d87bc6194 Attempt to use libc++ in travisCi tests 2016-03-27 18:38:08 +03:00
36efa3969b Use the cstring workaround only for GCC 2016-03-27 14:46:27 +03:00
551535f8cf Dropped the using syntax 2016-03-26 16:43:22 +03:00
3f004511a2 Do not use decltype 2016-03-26 16:24:51 +03:00
30bb93bd23 Test on clang too 2016-03-26 16:01:42 +03:00
7f2b9fd31a Combine klemens-morgenstern ideas with mine. Must compile and work at least on GCC-5 2016-03-26 15:49:09 +03:00
c9f1370d0c Merge tests from klemens-morgenstern 2016-03-25 21:34:30 +03:00
1ec4460244 Merge .travis.yml from klemens-morgenstern 2016-03-25 21:26:47 +03:00
1ed55a2f12 Merge branch 'constexpr14' of github.com:boostorg/type_index into constexpr14 2016-03-25 21:16:21 +03:00
1c685fa119 Initial C++14 constexpr version of ctti_type_index. No ABI breakage 2016-03-25 21:15:52 +03:00
37484c19ec Merge pull request #5 from klemens-morgenstern/develop
FIxed space removal
2016-02-13 23:50:45 +03:00
bb02f97414 Merge remote-tracking branch 'remotes/fork/develop' into develop 2016-02-13 19:12:19 +01:00
b9db462091 fixed length with noexcept 2016-02-13 19:11:04 +01:00
cf4f09b520 Merge branch 'develop' of https://github.com/boostorg/type_index into develop 2016-02-13 19:09:13 +01:00
5de7f5def6 added comparison test 2016-02-13 19:08:59 +01:00
1c8190cc62 FIxed space removal
I only tested that with templates, the space removal was too much.

I'll add a test for that, sry.
2016-02-13 18:52:29 +01:00
6ff2a75da3 Merge pull request #4 from klemens-morgenstern/develop
added in variant for MSVC with noexcept
2016-02-13 19:48:26 +03:00
58b0f69e52 added in variant for MSVC with noexcept 2016-02-12 10:00:44 +01:00
478da3512a Merge pull request #7 from norbertwenzel/develop
fixed two typos in documentation
2016-01-28 22:51:50 +03:00
a373a4c7ed fixed two typos in documentation 2016-01-27 20:13:40 +01:00
34835b90e3 Ignore tests coverage for unrelated libraries 2016-01-05 16:49:41 +03:00
236fdc8dba Update .travisci to use non-sudo approach 2016-01-05 16:39:43 +03:00
1ff942f329 Fix old MSVC warning 2015-12-10 20:55:45 +03:00
f58844637c travis fixes 2015-08-22 21:21:46 +03:00
9fede62a7c Fix travis build 2015-08-22 12:55:55 +03:00
48d50ae178 Run TravisCI tests using valgrind 2015-08-22 11:44:54 +03:00
743b2a8851 Initial C++14 constexpr version of ctti_type_index. No ABI breakage 2015-08-01 20:13:38 +03:00
7e2a538eb5 Fixed semicolon warnings 2015-07-30 23:00:41 +03:00
e5e105013a Fix shadow warning for name variable (svn #11503) 2015-07-28 22:53:24 +03:00
d7ec25e56b Use lightweight tests to avoid Boost.Test warnings, RTTI issues and minimize compilation times 2015-06-21 23:16:46 +03:00
c0f75c27fa Avoid warnings in some tests and do more checks 2015-06-18 22:01:45 +03:00
3e6695971d Removed applied patches 2015-06-17 21:54:04 +03:00
8d3127935d Drop dependency to Boost.Functional 2015-04-25 12:44:27 +03:00
d585fc3673 Merge pull request #6 from akumta/patch-1
Update compile_time_type_info.hpp
2015-03-12 16:20:12 +04:00
6b5d2743c5 Update compile_time_type_info.hpp
Update for ticket 11099
2015-03-10 13:44:18 -07:00
8558fd66ef remove the always failing testing_crossmodule_anonymous_no_rtti test from test suite and add notes for users about emulation limitations testing 2014-12-29 16:27:08 +03:00
8ddc5feac4 Updated README.md and added .travis.yml 2014-12-23 14:33:20 +03:00
8b7534889b Merge pull request #5 from MarcelRaad/patch-1
Allow BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY for MSVC
2014-12-17 23:04:38 +03:00
697e09bda9 Allow BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY for MSVC
BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY had no effect for MSVC. With this change, it is treated like BOOST_NO_RTTI also for MSVC.
2014-12-08 18:31:09 +01:00
242d9a0bed Use detect_mismatch pragma when possible (refs #10404 in track) 2014-08-26 14:41:54 +04:00
99f58714d1 Fix a lot of typos [refs #10294](https://svn.boost.org/trac/boost/ticket/10294) 2014-08-02 16:15:00 +04:00
7b04caa160 Fixed problems reported by inspection program 2014-08-01 12:34:34 +04:00
4d221d4f71 Minor changes: added consts and replaced BOOST_THROW_EXCEPTION with throw_exception 2014-06-16 09:42:21 +04:00
806a192df1 Merge pull request #4 from Lastique/patch-1
Thanks a lot!
2014-06-16 09:31:49 +04:00
1633adfee4 Changed implementation to use the low level interface for demangling.
Added a check for demangling errors, an exception is thrown in this case. The new implementation also does not allocate std::string until the parsing completes.
2014-06-12 22:23:48 +04:00
c3a26dff9a Port to Boost.Core demangle()
The port removes some conditional code from pretty_name() implementation. As a side effect, this improves portability (AFAICT, the previous version wouldn't do demangling on clang).

Additionally, the commit fixes a possible buffer overrun if demangle() returns a string equal to cvr_saver_name or cvr_saver_name with trailing spaces.
2014-06-11 23:41:04 +04:00
436ecd0b3e Added Configuration section to the docs and fixed minor issues 2014-06-02 15:56:12 +04:00
9fcbfd18ce Add more -DBOOST_NO_RTTI to Jamfile 2014-05-24 11:42:14 +04:00
1916e2b42f Fixes for Clang+Apple 2014-05-22 17:03:02 +04:00
56bd9b401a Gix a Boost.test another chance, more macro definitions in build scripts 2014-05-22 12:38:32 +04:00
e2c227d4aa Fix a typo and improve macro definitionas in Jamfile 2014-05-21 10:47:30 +04:00
80086cbc4f Do not use Boost.Test at all 2014-05-21 10:33:22 +04:00
0f0902d11c Explicitly define BOOSTNO_RTTI: do not rely on ability of Boost.Config to detect RTTI 2014-05-20 21:26:33 +04:00
6857f23e6f Use minimal subset of Boost.Test and do not depend on ability of Boost.Test to work with rtti off 2014-05-20 21:22:40 +04:00
ce103443fd Merge pull request #3 from danieljames/redirect-fix
Redirect fix
2014-05-20 17:04:45 +04:00
b34d4d466d Fix the documentation redirect location. 2014-05-20 09:01:59 +01:00
441a71c3d1 Merge pull request #2 from danieljames/doc-build-fix
Put the doxygen dependency on the quickbook file, rather than boostbook.
2014-05-20 08:45:39 +04:00
ae946ee496 Put the doxygen dependency on the quickbook file, rather than boostbook.
Because when building the main documentation, the docbook target isn't
being triggered, which is breaking the build. Hopefully this will fix
it.
2014-05-19 23:11:59 +01:00
76dc3d1053 Added index.html 2014-05-19 11:28:27 +04:00
28c77f4036 Merge pull request #1 from danieljames/metadata
Add metadata file
2014-05-19 08:41:15 +04:00
631e592b7a Add metadata file 2014-05-18 23:30:16 +01:00
fa2fa1805c Added always_show_run_output to ctti_print_name test rule 2014-05-14 09:32:34 +04:00
0744f86a2c Simplify the ctti_print_name.cpp 2014-05-13 14:17:42 +04:00
61594ba1da Fix nortti builds on Intel compiler 2014-05-13 12:03:15 +04:00
e2ceb6cf36 Log to std::cerr in ctti_print_name test and implicitly include ctti. Define BOOST_NO_RTTI for nortti test, so that even old compilers could compile tests 2014-05-12 20:11:51 +04:00
a397391b0e Added ctti_print_name.cpp to ensure that BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING macro works 2014-05-11 16:13:12 +04:00
8c8d9c6c69 Simplify redefinition of parsing rules 2014-05-11 03:11:34 +04:00
eac9c8af2f Another attempt to disable table_of_names_no_rtti test 2014-05-08 11:37:09 +04:00
4cc0272bd2 Polished the docs and removed BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS and BOOST_TYPE_INDEX_REGISTER_STL_CLASS as was recommended during review. Moved helper headers to the detail folder. 2014-05-07 20:12:27 +04:00
ecac9ac83c Tune CTTI for different versions of Clang 2014-05-07 16:46:07 +04:00
8a8a3ec639 Fix build script 2014-05-07 16:37:57 +04:00
6931c1de4c Updated docs and removed applied patch 2014-05-07 15:29:52 +04:00
7ba3f29da1 Add ability to do runtime searches in CTTI and fix pretty_name() on clang-3.4 2014-05-07 12:14:00 +04:00
a184f3969f Fixed almost all the notes by Andrey Semashev except link-time assertions and ctti type name assertions 2014-05-06 18:23:26 +04:00
f7388d59b5 Fix some of the notes mentioned by Andrey Semashev (more to come) 2014-05-06 16:27:03 +04:00
2602569bc4 Fixed issueas mentioned by Mathieu Champlon during Boost review 2014-05-06 13:03:59 +04:00
172d4a25ca Fixed issues mentioned by Dominique Devienne during Boost review 2014-05-05 19:49:56 +04:00
6af608a827 Fixed notes mentioned by Klaim - Joël Lamotte during review 2014-05-04 20:28:45 +04:00
5ed8543025 Changed namespace to boost::typeindex 2014-05-04 14:42:12 +04:00
a66ffcfa50 Fixed issues noted by Paul A. Bristow during review 2014-05-04 14:22:25 +04:00
54 changed files with 3281 additions and 1051 deletions

178
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,178 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxflags: "cxxflags=--coverage"
linkflags: "linkflags=--coverage"
gcov_tool: "gcov-7"
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
launcher: "testing.launcher=LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6"
gcov_tool: "gcov-10"
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: clang-7
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
cxxflags: "cxxflags=-fsanitize=address,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=-fsanitize=address,undefined"
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 10 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init --depth 10 --jobs 2 tools/boostdep tools/inspect libs/filesystem
python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 3" filesystem
rm -rf libs/$LIBRARY/*
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--depth 10 --jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
./b2 -j4 variant=debug tools/inspect/build
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release "${{matrix.cxxflags}}" "${{matrix.linkflags}}" "${{matrix.launcher}}"
dist/bin/inspect libs/$LIBRARY
- name: Prepare coverage data
if: matrix.gcov_tool
run: |
mkdir -p $GITHUB_WORKSPACE/coveralls
echo -e "#!/bin/bash\nexec ${{matrix.gcov_tool}} \"\$@\"" > $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
chmod +x $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh
wget https://github.com/linux-test-project/lcov/archive/v1.15.zip
unzip v1.15.zip
LCOV="`pwd`/lcov-1.15/bin/lcov --gcov-tool $GITHUB_WORKSPACE/coveralls/gcov_wrapper.sh"
echo "$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory `pwd`/libs/$LIBRARY/test --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info"
$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory ../boost-root/ --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info
$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info "/usr*" "*/$LIBRARY/test/*" ${{matrix.ignore_coverage}} "*/$LIBRARY/tests/*" "*/$LIBRARY/examples/*" "*/$LIBRARY/example/*" -o $GITHUB_WORKSPACE/coveralls/coverage.info
cd ../boost-root
OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$LIBRARY\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
echo $OTHER_LIBS
eval "$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info $OTHER_LIBS -o $GITHUB_WORKSPACE/coveralls/coverage.info"
- name: Coveralls
uses: coverallsapp/github-action@master
if: matrix.gcov_tool
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coveralls/coverage.info
parallel: true
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.1
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2019
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 10 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
finish:
needs: posix
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.github_token }}
parallel-finished: true

47
CMakeLists.txt Normal file
View 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()

View File

@ -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: | [![CI](https://github.com/boostorg/type_index/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/type_index/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/197a5imq10dqx6r8/branch/develop?svg=true)](https://ci.appveyor.com/project/apolukhin/type-index/branch/develop) | [![Coverage Status](https://coveralls.io/repos/apolukhin/type_index/badge.png?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: | [![CI](https://github.com/boostorg/type_index/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/type_index/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/197a5imq10dqx6r8/branch/master?svg=true)](https://ci.appveyor.com/project/apolukhin/type-index/branch/master) | [![Coverage Status](https://coveralls.io/repos/apolukhin/type_index/badge.png?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).

View File

@ -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 ;

View File

@ -1,7 +1,7 @@
[library Boost.TypeIndex
[quickbook 1.6]
[version 3.0]
[copyright 2012-2014 Antony Polukhin]
[version 4.1]
[copyright 2012-2022 Antony Polukhin]
[category Language Features Emulation]
[license
Distributed under the Boost Software License, Version 1.0.
@ -11,10 +11,10 @@
]
[section Motivation]
Sometimes getting and storing information about a type at runtime is required. For such cases a construction like `&typeid(T)` or C++11 class `std::type_index` is usually used. And that is the point, where problems start:
Sometimes getting and storing information about a type at runtime is required. For such cases a construction like `&typeid(T)` or C++11 class `std::type_index` is usually used, which is where problems start:
* `typeid(T)` and `std::type_index` require Run Time Type Info (RTTI)
* some implementations of `typeid(T)` strip const, volatile and references from type, while others don't
* some implementations of `typeid(T)` erroneously do not strip const, volatile and references from type
* some compilers have bugs and do not correctly compare `std::type_info` objects across shared libraries
* only a few implementations of Standard Library currently provide `std::type_index`
* no easy way to store type info without stripping const, volatile and references
@ -25,63 +25,89 @@ Boost.TypeIndex library was designed to work around all those issues.
[note `T` means type here. Think of it as of `T` in `template <class T>` ]
[warning Version 3.0 of this library is waitning for Boost mini-review. ]
[endsect]
[section Getting started]
`boost::typeind::type_info` is a drop-in replacement for `std::type_info` and `boost::typeind::type_index`
is a drop-in replacement for `std::type_index`. Unlike Standard Library versions those classes may work without RTTI.
[classref boost::typeindex::type_info boost::typeindex::type_info] is a drop-in replacement for `std::type_info` and
[classref boost::typeindex::type_index boost::typeindex::type_index]
is a drop-in replacement for `std::type_index`. Unlike Standard Library versions those classes can work without RTTI.
`type_index` provides the full set of comparison operators, hashing functions and ostream
operators, so it can be used with any container class.
Through all the examples, we'll assume that the following namespace alias is in effect:
``namespace bti = boost::typeind;``
[section How to use]
To start using Boost.TypeIndex:
[table:porting
[[Replace this:][With the following:]]
[[Replace this:][With the following:][More Info]]
[[``
#include <typeinfo>
#include <typeindex>
``][``
#include <boost/type_index.hpp>
``]]
``][
[headerref boost/type_index.hpp more... ]
]]
[[``
std::type_index
``][``
bti::type_index
``]]
boost::typeindex::type_index
``][
[classref boost::typeindex::type_index more... ]
]]
[[``
typeid(T)
typeid(please_save_modifiers<T>)
typeid(T).name() // not human readable
typeid(variable)
``][``
bti::type_id<T>()
bti::type_id_with_cvr<T>()
bti::type_id<T>().pretty_name() // human readable
bti::type_id_runtime(variable)
``]]
boost::typeindex::type_id<T>()
boost::typeindex::type_id<T>().pretty_name() // human readable
boost::typeindex::type_id_runtime(variable)
``][
[funcref boost::typeindex::type_id more... ]
[classref boost::typeindex::type_index more... ]
[funcref boost::typeindex::type_id_runtime more... ]
]]
[[``
const std::type_info& v1 = typeid(int); // when reference to `std::type_info` is required
const std::type_info* v2 = &typeid(int); // other cases
// attempt to save const, volatile, reference
typeid(please_save_modifiers<T>)
``][``
const bti::type_info& v1 = bti::type_id<int>().type_info();
bti::type_index v2 = bti::type_id<int>();
``]]
// cvr = const, volatile, reference
boost::typeindex::type_id_with_cvr<T>()
``][
[funcref boost::typeindex::type_id_with_cvr more... ]
]]
[[``
// when reference to `std::type_info` is required
const std::type_info& v1 = typeid(int);
// other cases
const std::type_info* v2 = &typeid(int);
``][``
const boost::typeindex::type_info& v1
= boost::typeindex::type_id<int>().type_info();
boost::typeindex::type_index v2
= boost::typeindex::type_id<int>();
``][
[classref boost::typeindex::type_index more... ]
[funcref boost::typeindex::type_id more... ]
]]
]
If you are using `type_id_runtime()` methods and RTTI is disabled, make sure that classes that are
passed to `type_id_runtime()` are marked with `BOOST_TYPE_INDEX_REGISTER_CLASS` macro.
If you are using [funcref boost::typeindex::type_id_runtime type_id_runtime()] methods
and RTTI is disabled, make sure that classes that are passed to
`type_id_runtime()` are marked with
[macroref BOOST_TYPE_INDEX_REGISTER_CLASS BOOST_TYPE_INDEX_REGISTER_CLASS] macro.
[endsect]
@ -98,10 +124,10 @@ Here is how TypeIndex could be used in `boost/any.hpp`:
return typeid(ValueType);
}
``] [``
virtual const bti::type_info & type() const BOOST_NOEXCEPT
virtual const boost::typeindex::type_info & type() const BOOST_NOEXCEPT
{
// now works even with RTTI disabled
return bti::type_id<ValueType>().type_info();
return boost::typeindex::type_id<ValueType>().type_info();
}
``]]
]
@ -141,14 +167,14 @@ public: // visitor interfaces
#endif // BOOST_NO_TYPEID
``][``
class reflect
: public static_visitor<const bti::type_info&>
: public static_visitor<const boost::typeindex::type_info&>
{
public: // visitor interfaces
template <typename T>
const bti::type_info& operator()(const T&) const BOOST_NOEXCEPT
const boost::typeindex::type_info& operator()(const T&) const BOOST_NOEXCEPT
{
return bti::type_id<T>().type_info();
return boost::typeindex::type_id<T>().type_info();
}
};
@ -162,7 +188,7 @@ public: // visitor interfaces
}
#endif
``] [``
const bti::type_info& type() const
const boost::typeindex::type_info& type() const
{
detail::variant::reflect visitor;
return this->apply_visitor(visitor);
@ -173,16 +199,60 @@ public: // visitor interfaces
[endsect]
[endsect]
[section:config Configuring and building the library]
TypeIndex is a header only library and it does not use Boost libraries that require
building. You just need to `#include <boost/type_index.hpp>` to start using it.
The library supports a number of configuration macros, defining which require full
rebuild of all the projects that use TypeIndex:
[table Configuration macros
[[Macro name] [Short description]]
[[[macroref BOOST_TYPE_INDEX_USER_TYPEINDEX]] [ Macro that allows you to use your
own implementation of TypeIndex instead of the default all around the projects and libraries.]]
[[[macroref BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY]] [ Macro that must be defined
if you are mixing RTTI-on and RTTI-off.]]
[[[macroref BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING] and
[macroref BOOST_TYPE_INDEX_FUNCTION_SIGNATURE]] [ Macros that allow you to specify
parsing options and type name generating macro for RTTI-off cases. ]]
]
You can define configuration macros in the `bjam` command line using one of the following
approaches:
[pre
b2 variant=release define=BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY stage
]
[pre
b2 variant=release "define=BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='(39, 1, true, \\"T = \\")'" stage
]
However, it may be more convenient to define configuration macros in the "boost/config/user.hpp"
file in order to automatically define them both for the library and user's projects.
[endsect]
[section How it works]
`type_index` is just a typedef for `stl_type_index` or `ctti_type_index`.
`type_index` is just a typedef for [classref boost::typeindex::stl_type_index]
or [classref boost::typeindex::ctti_type_index].
Depending on the `typeid()` availability TypeIndex library will choose an optimal class for
`type_index`. In cases when at least basic support for `typeid()` is available `boost::typeind::stl_type_index`
will be used.
`type_index`. In cases when at least basic support for `typeid()` is available `stl_type_index` will be used.
`BOOST_TYPE_INDEX_REGISTER_CLASS` macro is a helper macro that places some virtual helper functions or
[macroref BOOST_TYPE_INDEX_REGISTER_CLASS] macro is a helper macro that places some virtual helper functions or
expands to nothing.
[macroref BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS] macro is a helper macro that places the same
helpers as BOOST_TYPE_INDEX_REGISTER_CLASS plus some additional helpers for boost::typeindex::runtime_cast
to function.
Issues with cross module type comparison on a bugged compilers are bypassed by directly comparing strings with type
(latest versions of those compilers resolved that issue using exactly the same approach).
[endsect]
[section Examples]
@ -196,16 +266,28 @@ expands to nothing.
[import ../examples/inheritance.cpp]
[section Getting through the inheritance to receive a real type name ] [type_index_derived_example] [endsect]
[import ../examples/runtime_cast.cpp]
[section Using runtime_cast where RTTI is unavailable or undesirable ] [type_index_runtime_cast_example] [endsect]
[import ../examples/exact_types_match.cpp]
[section Exact type match: storing type with const, volatile and reference ] [type_index_exact_type_match_example] [endsect]
[section Exact type matching: storing type with const, volatile and reference qualifiers] [type_index_exact_type_match_example] [endsect]
[import ../examples/table_of_names.cpp]
[section Table of raw_name() and pretty_name() outputs with and without RTTI ] [type_index_names_table] [endsect]
[import ../examples/constexpr14_namespace_check.cpp]
[section C++14: Checking namespace at compile time ] [type_index_constexpr14_namespace_example] [endsect]
[import ../examples/constexpr14_sort_check.cpp]
[section C++14: Checking lexigraphical order of provided types ] [type_index_constexpr14_sort_check_example] [endsect]
[endsect]
[xinclude autodoc.xml]
[section Making own type_index]
[section Making a custom type_index]
Sometimes there may be a need to create your own type info system. This may be usefull if you wish to store some more info about types (PODness, size of a type, pointers to common functions...) or if you have an idea of a more compact types representations.
Sometimes there may be a need to create your own type info system. This may be useful if you wish to store some more info about types (PODness, size of a type, pointers to common functions...) or if you have an idea of a more compact types representations.
[import ../examples/user_defined_typeinfo.hpp]
[import ../examples/user_defined_typeinfo.cpp]
@ -237,17 +319,17 @@ Sometimes there may be a need to create your own type info system. This may be u
* `ctti_type_index` uses macro for getting full text representation of function name which could lead to code bloat,
so prefer using `stl_type_index` type when possible.
* `type_index` class hold a single pointer, so it is easy and fast to copy.
* All the type_index classes hold a single pointer and are fast to copy.
* Calls to `const char* raw_name()` do not require dynamic memory allocation and usually just return a pointer to an array of chars in a read-only section of the binary image.
* Comparison operators are optimized as much as possible, and will at worst execute a single `std::strcmp`.
* Comparison operators are optimized as much as possible and execute a single `std::strcmp` in worst case.
* Calls to `std::string pretty_name()` usually require dynamic memory allocation and some computations, so they are not recommended for usage in performance critical sections.
[endsect]
[section Code bloat]
Without RTTI TypeIndex library will switch from using `boost::typeind::stl_type_index` class to
`boost::typeind::ctti_type_index`. `boost::typeind::ctti_type_index` uses macro for getting full
Without RTTI TypeIndex library will switch from using `boost::typeindex::stl_type_index` class to
`boost::typeindex::ctti_type_index`. `boost::typeindex::ctti_type_index` uses macro for getting full
text representation of function name for each type that is passed to `type_id()` and
`type_id_with_cvr()` functions.
@ -265,31 +347,96 @@ i
[endsect]
[section Compiler support]
[section RTTI emulation limitations]
TypeIndex has been tested and successfully work on MSVC2010, GCC-4.6, Clang-2.9. If your compiler is not
in a list of tested compilers, you must correctly define `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`,
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` macroses:
TypeIndex has been tested and successfully work on many compilers.
# define `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE` to a compiler specific macro, that outputs the *whole*
function signature, including template parameters
# define `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `0`
# get the output of `boost::template_id<int>().name()`
# set `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` equal to characters count before last occurrence of `int` in output
# set `BOOST_TYPE_INDEX_CTTI_END_SKIP` equal to characters count after last occurrence of `int` in output
# check that `boost::template_id<int>().name_demangled()` returns "int"
# (optional, but highly recomended) [@http://www.boost.org/support/bugs.html create ticket] with
[warning
With RTTI off classes with exactly the same names defined in different modules in anonymous namespaces may collapse:
```
// In A.cpp
namespace { struct user_defined{}; }
type_index foo_a() { return type_id<user_defined>(); }
// In B.cpp
namespace { struct user_defined{}; }
type_index foo_b() { return type_id<user_defined>(); }
// In main.cpp
assert(foo_a() != foo_b()); // will fail on some compilers
```
*Compilers that have that limitation:* GCC, CLANG, Intel.
*Test:* you can test this issue by runing the `testing_crossmodule_anonymous_no_rtti` that can be build if you run `../../../b2` in `type_index/test/` folder.
]
[section Define the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro]
If you get the following error during compilation
``
TypeIndex library could not detect your compiler.
Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use
correct compiler macro for getting the whole function name.
Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that.
``
then you are using a compiler that was not tested with this library.
[macroref BOOST_TYPE_INDEX_FUNCTION_SIGNATURE] must be defined to a compiler specific macro, that outputs the *whole*
function signature including template parameters.
[endsect]
[section Fixing pretty_name() output]
If the output of `boost::typeindex::ctti_type_index::type_id<int>().name()`
* returns not just `int` but also a lot of text around the `int`
* or does not return type at all
then you are using a compiler that was not tested with this library and you need to setup the
[macroref BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING] macro.
Here is a short instruction:
# get the output of `boost::typeindex::ctti_type_index::type_id<int>().name()`
# define [macroref BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING] to
`(skip_at_begin, skip_at_end, false, "")`, where
* `skip_at_begin` is equal to characters count before the first occurrence of `int` in output
* `skip_at_end` is equal to characters count after last occurrence of `int` in output
# check that `boost::typeindex::ctti_type_index::type_id<int>().name_demangled()` returns "int"
# if it does not return `int`, then define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to
`(skip_at_begin, skip_at_end, true, "T = ")`, where
* `skip_at_begin` is equal to `skip_at_begin` at step 2
* `skip_at_end` is equal to `skip_at_end` at step 2
* `"T = "` is equal to characters that are right before the `int` in output
# (optional, but highly recommended) [@http://www.boost.org/support/bugs.html create ticket] with
feature request to add your compiler to supported compilers list. Include
`BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`, `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and
`BOOST_TYPE_INDEX_CTTI_END_SKIP` values.
parameters provided to `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` macro.
Consider the following example:
With `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` set to `0`,
`boost::typeind::ctti_type_index::type_id<int>().raw_name()` returns
`boost::typeindex::ctti_type_index::type_id<int>().raw_name()` returns
"const char *__cdecl boost::detail::ctti<int>::n(void)". Then you shall set
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` to `sizeof("const char *__cdecl boost::detail::ctti<") - 1`
and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `sizeof(">::n(void)") - 1`.
`skip_at_begin` to `sizeof("const char *__cdecl boost::detail::ctti<") - 1`
and `skip_at_end` to `sizeof(">::n(void)") - 1`.
``
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (39, 6, false, "")
``
Another example:
`boost::typeindex::ctti_type_index::type_id<int>().raw_name()` returns
"static const char *boost::detail::ctti<int>::n() [T = int]"". Then you shall set
`skip_at_begin` to `sizeof("static const char *boost::detail::ctti<") - 1`
and `skip_at_end` to `sizeof("]") - 1` and last parameter of macro to "T = ".
``
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (39, 1, true, "T = ")
``
[endsect]
[endsect]
@ -297,9 +444,9 @@ and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `sizeof(">::n(void)") - 1`.
Linking a binary from source files that were compiled with different RTTI flags is not a very good
idea and may lead to a lot of surprises. However if there is a very strong need, TypeIndex library
provides a solution for mixing sources: just define `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY`
macro. This would lead to usage of same type_index class (`boost::typeind::ctti_type_index` or
`boost::typeind::stl_type_index`) all around the project.
provides a solution for mixing sources: just define [macroref BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY]
macro. This would lead to usage of same type_index class (`boost::typeindex::ctti_type_index` or
`boost::typeindex::stl_type_index`) all around the project.
[note Do not forget to rebuild *all* the projects with `BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY` macro defined ]
@ -311,7 +458,7 @@ RTTI flags:
[table:diffs
[[RTTI on] [RTTI off]]
[[`boost::typeind::stl_type_index get_integer();`] [`boost::typeind::ctti_type_index get_integer();`]]
[[`boost::typeindex::stl_type_index get_integer();`] [`boost::typeindex::ctti_type_index get_integer();`]]
]
Such differences are usually not detected by linker and lead to errors at runtime.
@ -331,5 +478,6 @@ In order of helping and advising:
* Peter Dimov for writing source codes in late 2007, that gave me an idea of how to emulate RTTI.
* Agustín Bergé K-ballo for helping with docs and fixing a lot of typos.
* Niall Douglas for generating a lot of great ideas, reviewing the sources and being the review manager for the library.
* All the library reviewers, especially Andrey Semashev, for making good notes and proposing improvements to the library.
[endsect]

View 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

View 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

View File

@ -1,4 +1,4 @@
// Copyright 2013-2014 Antony Polukhin
// Copyright 2013-2022 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
@ -14,38 +14,63 @@
#include <boost/type_index.hpp>
#include <iostream>
namespace bti = boost::typeind;
template <class T>
void foo(T) {
std::cout << "\n Short name: " << bti::type_id<T>().raw_name();
std::cout << "\n Readable name: " << bti::type_id<T>().pretty_name();
std::cout << "\n Short name: " << boost::typeindex::type_id<T>().raw_name();
std::cout << "\n Readable name: " << boost::typeindex::type_id<T>().pretty_name();
}
struct user_defined_type{};
namespace ns1 { namespace ns2 {
struct user_defined_type{};
}} // namespace ns1::ns2
namespace {
struct in_anon_type{};
} // anonymous namespace
int main() {
// Call to
foo(1);
// will output something like this:
//
// (RTTI on) (RTTI off)
// Short name: i Short name: int]
// Readable name: int Readable name: int
// (RTTI on) (RTTI off)
// Short name: i Short name: int]
// Readable name: int Readable name: int
user_defined_type t;
foo(t);
// Will output:
//
// (RTTI on) (RTTI off)
// Short name: 17user_defined_type user_defined_type]
// Readable name: user_defined_type user_defined_type
// (RTTI on) (RTTI off)
// Short name: 17user_defined_type user_defined_type]
// Readable name: user_defined_type user_defined_type
ns1::ns2::user_defined_type t_in_ns;
foo(t_in_ns);
// Will output:
//
// (RTTI on) (RTTI off)
// Short name: N3ns13ns217user_defined_typeE ns1::ns2::user_defined_type]
// Readable name: ns1::ns2::user_defined_type ns1::ns2::user_defined_type
in_anon_type anon_t;
foo(anon_t);
// Will output:
//
// (RTTI on) (RTTI off)
// Short name: N12_GLOBAL__N_112in_anon_typeE {anonymous}::in_anon_type]
// Readable name: (anonymous namespace)::in_anon_type {anonymous}::in_anon_type
}
/*`
Short names are very compiler dependant: some compiler will output `.H`, others `i`.
Readable names may also differ between compilers: `struct user_defined_type`, `user_defined_type`.
[warning With RTTI off different classes with same names in anonymous namespace may collapse. See 'RTTI emulation limitations'. ]
*/
//] [/type_index_names_example]

View File

@ -1,4 +1,4 @@
// Copyright 2013-2014 Antony Polukhin
// Copyright 2013-2022 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
@ -9,31 +9,47 @@
The following example shows that `type_index` (and `type_info`) is able to store the exact type,
without stripping const, volatile and references. Example works with and without RTTI.
In this example we'll create a class, that stores pointer to function and remembers the exact type of a
parameter that function accepts. When an attempt to call the stored function will be made, type of input
parameter will be checked for exact match with initially erased type of function.
In this example we'll create a class that stores a pointer to function and remembers the exact type of the
parameter the function accepts. When the call to the bound function is made, he actual input parameter
type is checked against the stored parameter type and an exception is thrown in case of mismatch.
*/
#include <boost/type_index.hpp>
#include <iostream>
#include <stdexcept>
#include <cstdlib>
//<-
// Making `#include <cassert>` visible in docs, while actually using hand-made check
// instead of `assert`. This is required to verify correct behavior even if NDEBUG
// is defined and to avoid `unused local variable` warnings with defined NDEBUG.
//
// boost-no-inspect
#ifdef assert
# undef assert
#endif
#define assert(X) if (!(X)) std::exit(__LINE__)
/* !Comment block is not closed intentionaly!
//->
#include <cassert>
namespace bti = boost::typeind;
//<-
!Closing comment block! */
//->
class type_erased_unary_function {
void* function_ptr_;
bti::type_index exact_param_t_;
void* function_ptr_;
boost::typeindex::type_index exact_param_t_;
public:
template <class ParamT>
type_erased_unary_function(void(*ptr)(ParamT))
: function_ptr_(reinterpret_cast<void*>(ptr)) // ptr - is a pointer to function returning `void` and accepting parameter of type `ParamT`
, exact_param_t_(bti::type_id_with_cvr<ParamT>())
, exact_param_t_(boost::typeindex::type_id_with_cvr<ParamT>())
{}
template <class ParamT>
void call(ParamT v) {
if (exact_param_t_ != bti::type_id_with_cvr<ParamT>()) {
if (exact_param_t_ != boost::typeindex::type_id_with_cvr<ParamT>()) {
throw std::runtime_error("Incorrect `ParamT`");
}
@ -51,7 +67,7 @@ int main() {
int i = 100;
// An attempt to convert stored function to a function accepting reference
func.call<int&>(i); // Will throw, because types `int&` and `int` missmatch
func.call<int&>(i); // Will throw, because types `int&` and `int` mismatch
assert(false);
} catch (const std::runtime_error& /*e*/) {}

View File

@ -1,4 +1,4 @@
// Copyright 2013-2014 Antony Polukhin
// Copyright 2013-2022 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
@ -13,8 +13,8 @@
*/
#include <boost/type_index.hpp>
#include <boost/type_index/runtime_cast/register_runtime_class.hpp>
#include <iostream>
namespace bti = boost::typeind;
struct A {
BOOST_TYPE_INDEX_REGISTER_CLASS
@ -22,9 +22,10 @@ struct A {
};
struct B: public A { BOOST_TYPE_INDEX_REGISTER_CLASS };
struct C: public B { BOOST_TYPE_INDEX_REGISTER_CLASS };
struct D: public C { BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS) };
void print_real_type(const A& a) {
std::cout << bti::type_id_runtime(a).pretty_name() << '\n';
std::cout << boost::typeindex::type_id_runtime(a).pretty_name() << '\n';
}
int main() {
@ -32,6 +33,15 @@ int main() {
const A& c_as_a = c;
print_real_type(c_as_a); // Outputs `struct C`
print_real_type(B()); // Outputs `struct B`
/*`
It's also possible to use type_id_runtime with the BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS, which adds additional
information for runtime_cast to work.
*/
D d;
const A& d_as_a = d;
print_real_type(d_as_a); // Outputs `struct D`
}
//] [/type_index_derived_example]

View File

@ -1,4 +1,4 @@
// Copyright 2013-2014 Antony Polukhin
// Copyright 2013-2022 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
@ -11,28 +11,45 @@
*/
#include <boost/type_index.hpp>
#include <boost/unordered_set.hpp>
#include <boost/functional/hash.hpp>
#include <boost/unordered/unordered_set.hpp>
//<-
// Making `#include <cassert>` visible in docs, while actually using `BOOST_TEST`
// instead of `assert`. This is required to verify correct behavior even if NDEBUG
// is defined and to avoid `unused local variable` warnings with defined NDEBUG.
//
// boost-no-inspect
#include <boost/core/lightweight_test.hpp>
#ifdef assert
# undef assert
#endif
#define assert(X) BOOST_TEST(X)
/* !Comment block is not closed intentionaly!
//->
#include <cassert>
namespace bti = boost::typeind;
//<-
!Closing comment block! */
//->
int main() {
boost::unordered_set<bti::type_index> types;
boost::unordered_set<boost::typeindex::type_index> types;
// Storing some `boost::type_info`s
types.insert(bti::type_id<int>());
types.insert(bti::type_id<float>());
types.insert(boost::typeindex::type_id<int>());
types.insert(boost::typeindex::type_id<float>());
// `types` variable contains two `boost::type_index`es:
assert(types.size() == 2);
// Const, volatile and reference will be striped from the type:
bool is_inserted = types.insert(bti::type_id<const int>()).second;
bool is_inserted = types.insert(boost::typeindex::type_id<const int>()).second;
assert(!is_inserted);
assert(types.erase(bti::type_id<float&>()) == 1);
assert(types.erase(boost::typeindex::type_id<float&>()) == 1);
// We have erased the `float` type, only `int` remains
assert(*types.begin() == bti::type_id<int>());
assert(*types.begin() == boost::typeindex::type_id<int>());
//<-
return boost::report_errors();
//->
}
//] [/type_index_registry_example]

90
examples/runtime_cast.cpp Normal file
View 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]

View 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]

View File

@ -1,4 +1,4 @@
// Copyright 2013-2014 Antony Polukhin
// Copyright 2013-2022 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
@ -7,7 +7,7 @@
//[type_index_my_type_index_worldwide_macro
/*`
There is an easy way to force `boost::typeind::type_id` to use your own type_index class.
There is an easy way to force `boost::typeindex::type_id` to use your own type_index class.
All we need to do is just define `BOOST_TYPE_INDEX_USER_TYPEINDEX` to the full path to header file
of your type index class:
@ -18,10 +18,15 @@
#include <boost/type_index.hpp>
//] [/type_index_my_type_index_worldwide_macro]
// boost-no-inspect
#include <boost/core/lightweight_test.hpp>
#ifdef assert
# undef assert
#endif
#define assert(X) BOOST_TEST(X)
using namespace my_namespace;
#include <cassert>
int main() {
//[type_index_my_type_index_usage
@ -56,10 +61,13 @@ int main() {
/*`
That's it! Now all TypeIndex global methods and typedefs will be using your class:
*/
boost::typeind::type_index worldwide = boost::typeind::type_id<my_classes>();
boost::typeindex::type_index worldwide = boost::typeindex::type_id<my_classes>();
assert(worldwide.pretty_name() == "my_classes");
assert(worldwide == my_type_index::type_id<my_classes>());
//][/type_index_my_type_index_worldwide_usage]
//<-
return boost::report_errors();
//->
}

View File

@ -1,4 +1,4 @@
// Copyright 2013-2014 Antony Polukhin
// Copyright 2013-2022 Antony Polukhin
// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
@ -47,11 +47,20 @@ namespace my_namespace { namespace detail {
template <> struct typenum<my_classes>{ enum {value = 3}; };
template <> struct typenum<my_string>{ enum {value = 4}; };
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable: 4510 4512 4610) // non-copyable non-constructable type
#endif
// my_typeinfo structure is used to save type number
struct my_typeinfo {
const char* const type_;
};
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
const my_typeinfo infos[5] = {
{"void"}, {"my_class"}, {"my_struct"}, {"my_classes"}, {"my_string"}
};
@ -70,12 +79,20 @@ namespace my_namespace { namespace detail {
`my_type_index` is a user created type_index class. If in doubt during this phase, you can always
take a look at the `<boost/type_index/ctti_type_index.hpp>` or `<boost/type_index/stl_type_index.hpp>`
files. Documentation for `type_index_facade` could be also useful.
*/
/*`
Since we are not going to override `type_index_facade::hash_code()` we must additionally include
`<boost/container_hash/hash.hpp>`.
*/
#include <boost/container_hash/hash.hpp>
/*`
See implementation of `my_type_index`:
*/
namespace my_namespace {
class my_type_index: public boost::typeind::type_index_facade<my_type_index, detail::my_typeinfo> {
class my_type_index: public boost::typeindex::type_index_facade<my_type_index, detail::my_typeinfo> {
const detail::my_typeinfo* data_;
public:
@ -118,7 +135,7 @@ public:
} // namespace my_namespace
/*`
Note that we have used the boost::typeind::type_index_facade class as base.
Note that we have used the boost::typeindex::type_index_facade class as base.
That class took care about all the helper function and operators (comparison, hashing, ostreaming and others).
*/
@ -186,7 +203,7 @@ struct my_struct: public my_class {
You'll also need to add some typedefs and macro to your "user_defined_typeinfo.hpp" header file:
*/
#define BOOST_TYPE_INDEX_REGISTER_CLASS MY_TYPEINDEX_REGISTER_CLASS
namespace boost { namespace typeind {
namespace boost { namespace typeindex {
typedef my_namespace::my_type_index type_index;
}}
//] [/type_index_my_type_index_worldwide_typedefs]

View File

@ -1,5 +1,5 @@
//
// Copyright (c) Antony Polukhin, 2012-2014.
// Copyright 2012-2022 Antony Polukhin.
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -12,54 +12,132 @@
/// \brief Includes minimal set of headers required to use the Boost.TypeIndex library.
///
/// By inclusion of this file most optimal type index classes will be included and used
/// as a boost::typeind::type_index and boost::typeind::type_info.
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/// as a boost::typeindex::type_index and boost::typeindex::type_info.
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
#if defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
# include BOOST_TYPE_INDEX_USER_TYPEINDEX
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
# pragma detect_mismatch( "boost__type_index__abi", "user defined type_index class is used: " BOOST_STRINGIZE(BOOST_TYPE_INDEX_USER_TYPEINDEX))
# endif
#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
# include <boost/type_index/stl_type_index.hpp>
# ifdef BOOST_NO_RTTI
# include <boost/type_index/stl_register_class.hpp>
# if defined(BOOST_NO_RTTI) || defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)
# include <boost/type_index/detail/stl_register_class.hpp>
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - typeid() is used only for templates")
# endif
# else
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is used")
# endif
# endif
#else
# include <boost/type_index/ctti_type_index.hpp>
# include <boost/type_index/ctti_register_class.hpp>
# include <boost/type_index/detail/ctti_register_class.hpp>
# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - using CTTI")
# endif
#endif
namespace boost { namespace typeind {
#ifndef BOOST_TYPE_INDEX_REGISTER_CLASS
#define BOOST_TYPE_INDEX_REGISTER_CLASS
#endif
namespace boost { namespace typeindex {
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::typeindex::ctti_type_index class to
/// deduce the name of a type. If your compiler is not recognized
/// by the TypeIndex library and you wish to work with boost::typeindex::ctti_type_index, you may
/// define this macro by yourself.
///
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro
/// that outputs the \b whole function signature \b including \b template \b parameters.
///
/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined,
/// then a compile-time error will arise at any attempt to use boost::typeindex::ctti_type_index classes.
///
/// See BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS and BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
/// for an information of how to tune the implementation to make a nice pretty_name() output.
#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION
/// \def BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
/// This is a helper macro for making correct pretty_names() with RTTI off.
///
/// BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING macro may be defined to
/// '(begin_skip, end_skip, runtime_skip, runtime_skip_until)' with parameters for adding a
/// support for compilers, that by default are not recognized by TypeIndex library.
///
/// \b Example:
///
/// Imagine the situation when
/// \code boost::typeindex::ctti_type_index::type_id<int>().pretty_name() \endcode
/// returns the following string:
/// \code "static const char *boost::detail::ctti<int>::n() [T = int]" \endcode
/// and \code boost::typeindex::ctti_type_index::type_id<short>().pretty_name() \endcode returns the following:
/// \code "static const char *boost::detail::ctti<short>::n() [T = short]" \endcode
///
/// As we may see first 39 characters are "static const char *boost::detail::ctti<" and they do not depend on
/// the type T. After first 39 characters we have a human readable type name which is duplicated at the end
/// of a string. String always ends on ']', which consumes 1 character.
///
/// Now if we define `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` to
/// `(39, 1, false, "")` we'll be getting \code "int>::n() [T = int" \endcode
/// for `boost::typeindex::ctti_type_index::type_id<int>().pretty_name()` and \code "short>::n() [T = short" \endcode
/// for `boost::typeindex::ctti_type_index::type_id<short>().pretty_name()`.
///
/// Now we need to take additional care of the characters that go before the last mention of our type. We'll
/// do that by telling the macro that we need to cut off everything that goes before the "T = " including the "T = "
/// itself:
///
/// \code (39, 1, true, "T = ") \endcode
///
/// In case of GCC or Clang command line we need to add the following line while compiling all the sources:
///
/// \code
/// -DBOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='(39, 1, true, "T = ")'
/// \endcode
/// \param begin_skip How many characters must be skipped at the beginning of the type holding string.
/// Must be a compile time constant.
/// \param end_skip How many characters must be skipped at the end of the type holding string.
/// Must be a compile time constant.
/// \param runtime_skip Do we need additional checks at runtime to cut off the more characters.
/// Must be `true` or `false`.
/// \param runtime_skip_until Skip all the characters before the following string (including the string itself).
/// Must be a compile time array of characters.
///
/// See [RTTI emulation limitations](boost_typeindex/rtti_emulation_limitations.html) for more info.
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (0, 0, false, "")
/// Depending on a compiler flags, optimal implementation of type_index will be used
/// as a default boost::typeind::type_index.
/// as a default boost::typeindex::type_index.
///
/// Could be a boost::typeind::stl_type_index, boost::typeind::ctti_type_index or
/// Could be a boost::typeindex::stl_type_index, boost::typeindex::ctti_type_index or
/// user defined type_index class.
typedef platform-specific type_index;
///
/// \b See boost::typeindex::type_index_facade for a full description of type_index functions.
typedef platform_specific type_index;
#elif defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
// Nothing to do
#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
typedef boost::typeind::stl_type_index type_index;
# ifdef BOOST_NO_RTTI
# define BOOST_TYPE_INDEX_REGISTER_CLASS BOOST_TYPE_INDEX_REGISTER_STL_CLASS
# else
# define BOOST_TYPE_INDEX_REGISTER_CLASS
# endif
typedef boost::typeindex::stl_type_index type_index;
#else
typedef boost::typeind::ctti_type_index type_index;
# define BOOST_TYPE_INDEX_REGISTER_CLASS BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS
typedef boost::typeindex::ctti_type_index type_index;
#endif
/// Depending on a compiler flags, optimal implementation of type_info will be used
/// as a default boost::typeind::type_info.
/// as a default boost::typeindex::type_info.
///
/// Could be a std::type_info, boost::typeind::detail::ctti_data or
/// Could be a std::type_info, boost::typeindex::detail::ctti_data or
/// some user defined class.
///
/// type_info \b is \b not copyable or default constructible. It is \b not assignable too!
@ -71,16 +149,17 @@ typedef type_index::type_info_t type_info;
/// BOOST_TYPE_INDEX_USER_TYPEINDEX can be defined to the path to header file
/// with user provided implementation of type_index.
///
/// See "Making own type_index" section of documentation for usage example.
/// See [Making a custom type_index](boost_typeindex/making_a_custom_type_index.html) section
/// of documentation for usage example.
#define BOOST_TYPE_INDEX_USER_TYPEINDEX <full/absolute/path/to/header/with/type_index.hpp>
/// \def BOOST_TYPE_INDEX_REGISTER_CLASS
/// \def BOOST_TYPE_INDEX_REGISTER_CLASSis used to help to emulate RTTI.
/// BOOST_TYPE_INDEX_REGISTER_CLASS is used to help to emulate RTTI.
/// Put this macro into the public section of polymorphic class to allow runtime type detection.
///
/// Depending on the typeid() availability this macro will expand to nothing or to virtual helper function
/// `virtual const type_info& type_id_runtime() const`.
/// `virtual const type_info& boost_type_info_type_id_runtime_() const noexcept`.
///
/// \b Example:
/// \code
@ -102,20 +181,21 @@ typedef type_index::type_info_t type_info;
///
/// C c1;
/// A* pc1 = &c1;
/// assert(boost::typeind::type_id<C>() == boost::typeind::type_id_runtime(*pc1));
/// assert(boost::typeindex::type_id<C>() == boost::typeindex::type_id_runtime(*pc1));
/// \endcode
#define BOOST_TYPE_INDEX_REGISTER_CLASS nothing-or-some-virtual-functions
/// \def BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY is a helper macro that must be defined if mixing
/// RTTI on/off modules. See "Mixing sources with RTTI on and RTTI off" section of documentation
/// for more info.
/// RTTI on/off modules. See
/// [Mixing sources with RTTI on and RTTI off](boost_typeindex/mixing_sources_with_rtti_on_and_.html)
/// section of documentation for more info.
#define BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
#endif // defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
/// Function to get boost::type_index for a type T.
/// Function to get boost::typeindex::type_index for a type T.
/// Removes const, volatile && and & modifiers from T.
///
/// \b Example:
@ -126,13 +206,13 @@ typedef type_index::type_info_t type_info;
///
/// \tparam T Type for which type_index must be created.
/// \throw Nothing.
/// \return boost::typeind::type_index with information about the specified type T.
/// \return boost::typeindex::type_index with information about the specified type T.
template <class T>
inline type_index type_id() BOOST_NOEXCEPT {
return type_index::type_id<T>();
}
/// Function for constructing boost::type_index instance for type T.
/// Function for constructing boost::typeindex::type_index instance for type T.
/// Does not remove const, volatile, & and && modifiers from T.
///
/// If T has no const, volatile, & and && modifiers, then returns exactly
@ -146,7 +226,7 @@ inline type_index type_id() BOOST_NOEXCEPT {
///
/// \tparam T Type for which type_index must be created.
/// \throw Nothing.
/// \return boost::typeind::type_index with information about the specified type T.
/// \return boost::typeindex::type_index with information about the specified type T.
template <class T>
inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
return type_index::type_id_with_cvr<T>();
@ -154,7 +234,7 @@ inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index.
///
/// Retunrs runtime information about specified type.
/// Returns runtime information about specified type.
///
/// \b Requirements: RTTI available or Base and Derived classes must be marked with BOOST_TYPE_INDEX_REGISTER_CLASS.
///
@ -169,15 +249,15 @@ inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
/// std::cout << ti.pretty_name(); // Outputs 'Derived'
/// \endcode
///
/// \param runtime_val Varaible which runtime type must be returned.
/// \param runtime_val Variable which runtime type must be returned.
/// \throw Nothing.
/// \return boost::typeind::type_index with information about the specified variable.
/// \return boost::typeindex::type_index with information about the specified variable.
template <class T>
inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT {
return type_index::type_id_runtime(runtime_val);
}
}} // namespace boost::typeind
}} // namespace boost::typeindex

View File

@ -1,44 +0,0 @@
//
// Copyright (c) Antony Polukhin, 2013-2014.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
#define BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/// \file ctti_register_class.hpp
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS macro.
#include <boost/type_index/ctti_type_index.hpp>
namespace boost { namespace typeind { namespace detail {
template <class T>
inline const ctti_data& ctti_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
return ctti_construct<T>();
}
}}} // namespace boost::typeind::detail
/// \def BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS
/// BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS is used by BOOST_TYPE_INDEX_REGISTER_CLASS when RTTI is off
/// and `typeid()` does not work.
///
/// BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS macro expands to declaration and implementation of
/// `virtual const detail::ctti_data& type_id_runtime() const` method.
#define BOOST_TYPE_INDEX_REGISTER_CTTI_CLASS \
virtual const boost::typeind::detail::ctti_data& type_id_runtime() const BOOST_NOEXCEPT { \
return boost::typeind::detail::ctti_construct_typeid_ref(this); \
} \
/**/
#endif // BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP

View File

@ -1,5 +1,5 @@
//
// Copyright (c) Antony Polukhin, 2013-2014.
// Copyright 2013-2022 Antony Polukhin.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -9,15 +9,10 @@
#ifndef BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/// \file ctti_type_index.hpp
/// \brief Contains boost::typeind::ctti_type_index class.
/// \brief Contains boost::typeindex::ctti_type_index class that is constexpr if C++14 constexpr is supported by compiler.
///
/// boost::typeind::ctti_type_index class can be used as a drop-in replacement
/// boost::typeindex::ctti_type_index class can be used as a drop-in replacement
/// for std::type_index.
///
/// It is used in situations when typeid() method is not available or
@ -27,40 +22,66 @@
#include <boost/type_index/detail/compile_time_type_info.hpp>
#include <cstring>
#include <boost/container_hash/hash.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace typeind {
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost { namespace typeindex {
namespace detail {
// That's the most trickiest part of the TypeIndex library:
// 1) we do not whant to give user ability to manually construct and compare `struct-that-represents-type`
// 2) we need to distinguish beteween `struct-that-represents-type` and `const char*`
// 1) we do not want to give user ability to manually construct and compare `struct-that-represents-type`
// 2) we need to distinguish between `struct-that-represents-type` and `const char*`
// 3) we need a thread-safe way to have references to instances `struct-that-represents-type`
// 4) we need a compile-time control to make shure that user does not copy or
// 4) we need a compile-time control to make sure that user does not copy or
// default construct `struct-that-represents-type`
//
// Solution would be a standard-layout class with private constructors and assignment operators.
// Solution would be the following:
/// \class ctti_data
/// Standard-layout class with private constructors and assignment operators.
///
/// You can not work with this class directly. The purpose of this class is to hold type info
/// \b when \b RTTI \b is \b off and allow ctti_type_index construction from itself.
///
/// \b Example:
/// \code
/// const detail::ctti_data& foo();
/// ...
/// type_index ti = type_index(foo());
/// std::cout << ti.pretty_name();
/// \endcode
class ctti_data {
#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
public:
ctti_data() = delete;
ctti_data(const ctti_data&) = delete;
ctti_data& operator=(const ctti_data&) = delete;
#else
private:
ctti_data();
ctti_data(const ctti_data&);
ctti_data& operator=(const ctti_data&);
#endif
};
} // namespace detail
/// Helper method for getting detail::ctti_data of a tempalte patameter T.
/// Helper method for getting detail::ctti_data of a template parameter T.
template <class T>
inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
// Standard C++11, 5.2.10 Reinterpret cast:
// An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue
// v of type pointer to T1 is converted to the type pointer to cv T2, the result is static_cast<cv
// v of type "pointer to T1" is converted to the type "pointer to cv T2", the result is static_cast<cv
// T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment
// requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type
// pointer to T1 to the type pointer to T2 (where T1 and T2 are object types and where the alignment
// "pointer to T1" to the type "pointer to T2" (where T1 and T2 are object types and where the alignment
// requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer
// value.
//
@ -69,35 +90,52 @@ inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
}
/// \class ctti_type_index
/// This class is a wrapper that pretends to work exactly like stl_type_index, but does
/// not require RTTI support. For description of functions see type_index_facade.
/// This class is a wrapper that pretends to work exactly like stl_type_index, but does
/// not require RTTI support. \b For \b description \b of \b functions \b see type_index_facade.
///
/// This class produces slightly longer type names, so consider using stl_type_index
/// This class on C++14 compatible compilers has following functions marked as constexpr:
/// * default constructor
/// * copy constructors and assignemnt operations
/// * class methods: name(), before(const ctti_type_index& rhs), equal(const ctti_type_index& rhs)
/// * static methods type_id<T>(), type_id_with_cvr<T>()
/// * comparison operators
///
/// This class produces slightly longer type names, so consider using stl_type_index
/// in situations when typeid() is working.
class ctti_type_index: public type_index_facade<ctti_type_index, detail::ctti_data> {
const detail::ctti_data* data_;
const char* data_;
inline std::size_t get_raw_name_length() const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline explicit ctti_type_index(const char* data) BOOST_NOEXCEPT
: data_(data)
{}
public:
typedef detail::ctti_data type_info_t;
inline ctti_type_index() BOOST_NOEXCEPT
: data_(&ctti_construct<void>())
BOOST_CXX14_CONSTEXPR inline ctti_type_index() BOOST_NOEXCEPT
: data_(boost::detail::ctti<void>::n())
{}
inline ctti_type_index(const type_info_t& data) BOOST_NOEXCEPT
: data_(&data)
: data_(reinterpret_cast<const char*>(&data))
{}
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
inline const char* raw_name() const BOOST_NOEXCEPT;
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline const char* raw_name() const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline const char* name() const BOOST_NOEXCEPT;
inline std::string pretty_name() const;
inline std::size_t hash_code() const BOOST_NOEXCEPT;
template <class T>
inline static ctti_type_index type_id() BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline bool equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline bool before(const ctti_type_index& rhs) const BOOST_NOEXCEPT;
template <class T>
inline static ctti_type_index type_id_with_cvr() BOOST_NOEXCEPT;
BOOST_CXX14_CONSTEXPR inline static ctti_type_index type_id() BOOST_NOEXCEPT;
template <class T>
BOOST_CXX14_CONSTEXPR inline static ctti_type_index type_id_with_cvr() BOOST_NOEXCEPT;
template <class T>
inline static ctti_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
@ -105,49 +143,71 @@ public:
inline const ctti_type_index::type_info_t& ctti_type_index::type_info() const BOOST_NOEXCEPT {
return *data_;
return *reinterpret_cast<const detail::ctti_data*>(data_);
}
BOOST_CXX14_CONSTEXPR inline bool ctti_type_index::equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT {
const char* const left = raw_name();
const char* const right = rhs.raw_name();
return /*left == right ||*/ !boost::typeindex::detail::constexpr_strcmp(left, right);
}
BOOST_CXX14_CONSTEXPR inline bool ctti_type_index::before(const ctti_type_index& rhs) const BOOST_NOEXCEPT {
const char* const left = raw_name();
const char* const right = rhs.raw_name();
return /*left != right &&*/ boost::typeindex::detail::constexpr_strcmp(left, right) < 0;
}
template <class T>
inline ctti_type_index ctti_type_index::type_id() BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline ctti_type_index ctti_type_index::type_id() BOOST_NOEXCEPT {
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_t;
return ctti_construct<no_cvr_t>();
return ctti_type_index(boost::detail::ctti<no_cvr_t>::n());
}
template <class T>
inline ctti_type_index ctti_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
return ctti_construct<T>();
BOOST_CXX14_CONSTEXPR inline ctti_type_index ctti_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
return ctti_type_index(boost::detail::ctti<T>::n());
}
template <class T>
inline ctti_type_index ctti_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
return variable.type_id_runtime();
return variable.boost_type_index_type_id_runtime_();
}
inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
return reinterpret_cast<const char*>(data_);
BOOST_CXX14_CONSTEXPR inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
return data_;
}
BOOST_CXX14_CONSTEXPR inline const char* ctti_type_index::name() const BOOST_NOEXCEPT {
return data_;
}
inline std::size_t ctti_type_index::get_raw_name_length() const BOOST_NOEXCEPT {
return std::strlen(raw_name() + detail::ctti_skip_size_at_end);
}
inline std::string ctti_type_index::pretty_name() const {
std::size_t len = std::strlen(raw_name() + detail::ctti_skip_size_at_end);
std::size_t len = get_raw_name_length();
while (raw_name()[len - 1] == ' ') --len; // MSVC sometimes adds whitespaces
return std::string(raw_name(), len);
}
inline std::size_t ctti_type_index::hash_code() const BOOST_NOEXCEPT {
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name() + detail::ctti_skip_size_at_end));
return boost::hash_range(raw_name(), raw_name() + get_raw_name_length());
}
}} // namespace boost::typeind
}} // namespace boost::typeindex
#endif // BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP

View File

@ -1,5 +1,5 @@
//
// Copyright (c) Antony Polukhin, 2012-2014.
// Copyright 2012-2022 Antony Polukhin.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -9,131 +9,331 @@
#ifndef BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
#define BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
/// \file compile_time_type_info.hpp
/// \brief Contains helper macros and implementation details of boost::typeindex::ctti_type_index.
/// Not intended for inclusion from user's code.
#include <cstring>
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/integral_constant.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
/// \file compile_time_type_info.hpp
/// \brief Contains implementation of boost::ctti class.
///
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
namespace boost { namespace typeind { namespace detail {
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::template_info class to
/// deduce the name of a template parameter. If your compiler is not recognized
/// by the TypeIndex library and you wish to work with boost::template_info, you may
/// define this macro by yourself.
///
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro,
/// that outputs the WHOLE function signature, including template parameters.
///
/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined,
/// then a compile-time error will arise at any attempt to use boost::template_info or
/// boost::template_index classes.
#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION
/// \def BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
///
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE, BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
/// and BOOST_TYPE_INDEX_CTTI_END_SKIP macroses are used for adding a
/// support for compilers, that by default are not recognized by TypeIndex library.
///
/// See Compiler support for more info
#define BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP 0
/// \def BOOST_TYPE_INDEX_CTTI_END_SKIP
///
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE, BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
/// and BOOST_TYPE_INDEX_CTTI_END_SKIP macroses are used for adding a
/// support for compilers, that by default are not recognized by TypeIndex library.
///
/// See Compiler support for more info
#define BOOST_TYPE_INDEX_CTTI_END_SKIP 0
#elif defined(BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP) && defined(BOOST_TYPE_INDEX_CTTI_END_SKIP)
// skip user specified bytes count
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP);
// skip user specified bytes count
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = BOOST_TYPE_INDEX_CTTI_END_SKIP);
#elif defined _MSC_VER
// sizeof("const char *__cdecl boost::detail::ctti<") - 1
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 40);
// sizeof(">::n(void)") - 1
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 10);
#elif defined __clang__
// sizeof("static const char *boost::detail::ctti<") - 1
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 39);
// == sizeof(">::n()") - 1
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 6);
#elif defined __GNUC__
// sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 57);
// == sizeof("]") - 1
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 1);
#else
// TODO: Code for other platforms
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 0); // skip nothing
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 0); // skip nothing
/// @cond
#if defined(__has_builtin)
#if __has_builtin(__builtin_constant_p)
#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
#endif
#if __has_builtin(__builtin_strcmp)
#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2)
#endif
#elif defined(__GNUC__)
#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2)
#endif
}}} // namespace boost::typeind::detail
#define BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(begin_skip, end_skip, runtime_skip, runtime_skip_until) \
namespace boost { namespace typeindex { namespace detail { \
BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_begin = begin_skip; \
BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_end = end_skip; \
BOOST_STATIC_CONSTEXPR bool ctti_skip_more_at_runtime = runtime_skip; \
BOOST_STATIC_CONSTEXPR char ctti_skip_until_runtime[] = runtime_skip_until; \
}}} /* namespace boost::typeindex::detail */ \
/**/
/// @endcond
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
/* Nothing to document. All the macro docs are moved to <boost/type_index.hpp> */
#elif defined(BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING)
# include <boost/preprocessor/facilities/expand.hpp>
BOOST_PP_EXPAND( BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING )
#elif defined(_MSC_VER) && !defined(__clang__) && defined (BOOST_NO_CXX11_NOEXCEPT)
// sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "")
#elif defined(_MSC_VER) && !defined(__clang__) && !defined (BOOST_NO_CXX11_NOEXCEPT)
// sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void) noexcept") - 1
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 19, false, "")
#elif defined(__clang__) && defined(__APPLE__)
// Someone made __clang_major__ equal to LLVM version rather than compiler version
// on APPLE platform.
//
// Using less efficient solution because there is no good way to detect real version of Clang.
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "???????????>::n() [T = int"
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
#elif defined(__clang__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ == 0))
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof(">::n()") - 1
// note: checked on 3.0
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "")
#elif defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ > 0))
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "int>::n() [T = int"
// note: checked on 3.1, 3.4
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
#elif defined(__EDG__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
// sizeof("static cha boost::detail::ctti<T>::s() [with I = 40U, T = ") - 1, sizeof("]") - 1
// note: checked on 4.14
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(58, 1, false, "")
#elif defined(__EDG__) && defined(BOOST_NO_CXX14_CONSTEXPR)
// sizeof("static const char *boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
// note: checked on 4.14
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
#elif defined(__GNUC__) && (__GNUC__ < 7) && !defined(BOOST_NO_CXX14_CONSTEXPR)
// sizeof("static constexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0u; T = ") - 1, sizeof("]") - 1
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(81, 1, false, "")
#elif defined(__GNUC__) && (__GNUC__ >= 7) && !defined(BOOST_NO_CXX14_CONSTEXPR)
// sizeof("static constexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0; T = ") - 1, sizeof("]") - 1
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(80, 1, false, "")
#elif defined(__GNUC__) && defined(BOOST_NO_CXX14_CONSTEXPR)
// sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
#elif defined(__ghs__)
// sizeof("static const char *boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
#else
// Deafult code for other platforms... Just skip nothing!
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "")
#endif
#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS
namespace boost { namespace typeindex { namespace detail {
template <bool Condition>
BOOST_CXX14_CONSTEXPR inline void assert_compile_time_legths() BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(
Condition,
"TypeIndex library is misconfigured for your compiler. "
"Please define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct values. See section "
"'RTTI emulation limitations' of the documentation for more information."
);
}
template <class T>
BOOST_CXX14_CONSTEXPR inline void failed_to_get_function_name() BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(
sizeof(T) && false,
"TypeIndex library could not detect your compiler. "
"Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use "
"correct compiler macro for getting the whole function name. "
"Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that."
);
}
#if defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT)
BOOST_CXX14_CONSTEXPR BOOST_FORCEINLINE bool is_constant_string(const char* str) BOOST_NOEXCEPT {
while (BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(*str)) {
if (*str == '\0')
return true;
++str;
}
return false;
}
#endif // defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT)
template <unsigned int ArrayLength>
BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::false_type) BOOST_NOEXCEPT {
return begin;
}
template<class ForwardIterator1, class ForwardIterator2>
BOOST_CXX14_CONSTEXPR inline ForwardIterator1 constexpr_search(
ForwardIterator1 first1,
ForwardIterator1 last1,
ForwardIterator2 first2,
ForwardIterator2 last2) BOOST_NOEXCEPT
{
if (first2 == last2) {
return first1; // specified in C++11
}
while (first1 != last1) {
ForwardIterator1 it1 = first1;
ForwardIterator2 it2 = first2;
while (*it1 == *it2) {
++it1;
++it2;
if (it2 == last2) return first1;
if (it1 == last1) return last1;
}
++first1;
}
return last1;
}
BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp_loop(const char *v1, const char *v2) BOOST_NOEXCEPT {
while (*v1 != '\0' && *v1 == *v2) {
++v1;
++v2;
}
return static_cast<int>(*v1) - *v2;
}
BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp(const char *v1, const char *v2) BOOST_NOEXCEPT {
#if !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT) && defined(BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP)
if (boost::typeindex::detail::is_constant_string(v1) && boost::typeindex::detail::is_constant_string(v2))
return boost::typeindex::detail::constexpr_strcmp_loop(v1, v2);
return BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(v1, v2);
#elif !defined(BOOST_NO_CXX14_CONSTEXPR)
return boost::typeindex::detail::constexpr_strcmp_loop(v1, v2);
#else
return std::strcmp(v1, v2);
#endif
}
template <unsigned int ArrayLength>
BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::true_type) BOOST_NOEXCEPT {
const char* const it = constexpr_search(
begin, begin + ArrayLength,
ctti_skip_until_runtime, ctti_skip_until_runtime + sizeof(ctti_skip_until_runtime) - 1
);
return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1);
}
template <unsigned int ArrayLength>
BOOST_CXX14_CONSTEXPR inline const char* skip_begining(const char* begin) BOOST_NOEXCEPT {
assert_compile_time_legths<(ArrayLength > ctti_skip_size_at_begin + ctti_skip_size_at_end)>();
return skip_begining_runtime<ArrayLength - ctti_skip_size_at_begin>(
begin + ctti_skip_size_at_begin,
boost::integral_constant<bool, ctti_skip_more_at_runtime>()
);
}
#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
template <unsigned int... I>
struct index_seq {};
template <typename Left, typename Right>
struct make_index_sequence_join;
template <unsigned int... Left, unsigned int... Right>
struct make_index_sequence_join<index_seq<Left...>, index_seq<Right...> > {
typedef index_seq<Left..., Right...> type;
};
template <unsigned int C, unsigned int D>
struct make_index_seq_impl {
typedef typename make_index_sequence_join<
typename make_index_seq_impl<C, D / 2>::type,
typename make_index_seq_impl<C + D / 2, (D + 1) / 2>::type
>::type type;
};
template <unsigned int C>
struct make_index_seq_impl<C, 0> {
typedef index_seq<> type;
};
template <unsigned int C>
struct make_index_seq_impl<C, 1> {
typedef index_seq<C> type;
};
template <char... C>
struct cstring {
static constexpr unsigned int size_ = sizeof...(C);
static constexpr char data_[size_] = { C... };
};
template <char... C>
constexpr char cstring<C...>::data_[];
#endif
}}} // namespace boost::typeindex::detail
namespace boost { namespace detail {
/// Noncopyable type_info that does not require RTTI.
/// CTTI == Compile Time Type Info.
/// This name must be as short as posible, to avoid code bloat
/// This name must be as short as possible, to avoid code bloat
template <class T>
struct ctti {
typedef T template_type;
typedef ctti this_type;
/// Returns raw name. Must be as short, as possible, to avoid code bloat
static const char* n() BOOST_NOEXCEPT {
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
return BOOST_TYPE_INDEX_FUNCTION_SIGNATURE + boost::typeind::detail::ctti_skip_size_at_begin;
#elif defined(__FUNCSIG__)
return __FUNCSIG__ + boost::typeind::detail::ctti_skip_size_at_begin;
#elif defined(__PRETTY_FUNCTION__) \
#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
//helper functions
template <unsigned int I>
constexpr static char s() BOOST_NOEXCEPT { // step
constexpr unsigned int offset =
(I >= 10u ? 1u : 0u)
+ (I >= 100u ? 1u : 0u)
+ (I >= 1000u ? 1u : 0u)
+ (I >= 10000u ? 1u : 0u)
+ (I >= 100000u ? 1u : 0u)
+ (I >= 1000000u ? 1u : 0u)
;
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
return BOOST_TYPE_INDEX_FUNCTION_SIGNATURE[I + offset];
#elif defined(__FUNCSIG__)
return __FUNCSIG__[I + offset];
#else
return __PRETTY_FUNCTION__[I + offset];
#endif
}
template <unsigned int ...Indexes>
constexpr static const char* impl(::boost::typeindex::detail::index_seq<Indexes...> ) BOOST_NOEXCEPT {
return ::boost::typeindex::detail::cstring<s<Indexes>()...>::data_;
}
template <unsigned int D = 0> // `D` means `Dummy`
constexpr static const char* n() BOOST_NOEXCEPT {
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
constexpr unsigned int size = sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
#elif defined(__FUNCSIG__)
constexpr unsigned int size = sizeof(__FUNCSIG__);
#elif defined(__PRETTY_FUNCTION__) \
|| defined(__GNUC__) \
|| (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|| (defined(__ICC) && (__ICC >= 600)) \
|| defined(__ghs__) \
|| defined(__DMC__)
constexpr unsigned int size = sizeof(__PRETTY_FUNCTION__);
#else
boost::typeindex::detail::failed_to_get_function_name<T>();
#endif
return __PRETTY_FUNCTION__ + boost::typeind::detail::ctti_skip_size_at_begin;
#else
BOOST_STATIC_ASSERT_MSG(
sizeof(T) && false,
"TypeIndex library could not detect your compiler. "
"Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use "
"correct compiler macro for getting the whole function name. "
"Do not forget to also define BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP and "
"BOOST_TYPE_INDEX_CTTI_END_SKIP."
);
#endif
}
boost::typeindex::detail::assert_compile_time_legths<
(size > boost::typeindex::detail::ctti_skip_size_at_begin + boost::typeindex::detail::ctti_skip_size_at_end + sizeof("const *") - 1)
>();
static_assert(!boost::typeindex::detail::ctti_skip_more_at_runtime, "Skipping for GCC in C++14 mode is unsupported");
/// Returns raw name
static const char* name() BOOST_NOEXCEPT {
return this_type::n();
typedef typename boost::typeindex::detail::make_index_seq_impl<
boost::typeindex::detail::ctti_skip_size_at_begin,
size - sizeof("const *") + 1 - boost::typeindex::detail::ctti_skip_size_at_begin
>::type idx_seq;
return impl(idx_seq());
}
#else
/// Returns raw name. Must be as short, as possible, to avoid code bloat
BOOST_CXX14_CONSTEXPR static const char* n() BOOST_NOEXCEPT {
#if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
#elif defined(__FUNCSIG__)
return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__);
#elif defined(__PRETTY_FUNCTION__) \
|| defined(__GNUC__) \
|| (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|| (defined(__ICC) && (__ICC >= 600)) \
|| defined(__ghs__) \
|| defined(__DMC__) \
|| defined(__clang__)
return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
#else
boost::typeindex::detail::failed_to_get_function_name<T>();
return "";
#endif
}
#endif
};
}} // namespace boost::detail
#endif // BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP

View 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

View 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

View 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

View File

@ -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

View File

@ -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

View 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

View 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

View 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

View File

@ -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

View File

@ -1,45 +0,0 @@
//
// Copyright (c) Antony Polukhin, 2013-2014.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
#define BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/// \file stl_register_class.hpp
/// \brief Contains BOOST_TYPE_INDEX_REGISTER_STL_CLASS macro.
#include <boost/type_index/stl_type_index.hpp>
namespace boost { namespace typeind { namespace detail {
template <class T>
inline const stl_type_index::type_info_t& stl_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
return typeid(T);
}
}}} // namespace boost::typeind::detail
/// \def BOOST_TYPE_INDEX_REGISTER_STL_CLASS
/// BOOST_TYPE_INDEX_REGISTER_STL_CLASS is used by BOOST_TYPE_INDEX_REGISTER_CLASS when RTTI is off
/// and `typeid()` does work.
///
/// BOOST_TYPE_INDEX_REGISTER_STL_CLASS macro expands to declaration and implementation of
/// `virtual const std::type_info& type_id_runtime() const` method.
#define BOOST_TYPE_INDEX_REGISTER_STL_CLASS \
virtual const boost::typeind::stl_type_index::type_info_t& type_id_runtime() const BOOST_NOEXCEPT { \
return boost::typeind::detail::stl_construct_typeid_ref(this); \
} \
/**/
#endif // BOOST_TYPE_INDEX_STL_REGISTER_CLASS_HPP

View File

@ -1,5 +1,5 @@
//
// Copyright (c) Antony Polukhin, 2013-2014.
// Copyright 2013-2022 Antony Polukhin.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -9,60 +9,60 @@
#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
/// \file stl_type_index.hpp
/// \brief Contains boost::typeind::stl_type_index class.
/// \brief Contains boost::typeindex::stl_type_index class.
///
/// boost::typeind::stl_type_index class can be used as a drop-in replacement
/// boost::typeindex::stl_type_index class can be used as a drop-in replacement
/// for std::type_index.
///
/// It is used in situations when RTTI is enabled or typeid() method is available.
/// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro
/// is defined boost::typeind::ctti is usually used instead of boost::typeind::stl_type_index.
/// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index.
#include <boost/type_index/type_index_facade.hpp>
// MSVC is capable of calling typeid(T) even when RTTI is off
#if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC)
#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available."
#endif
#include <typeinfo>
#include <cstring> // std::strcmp, std::strlen
#include <cstring> // std::strcmp, std::strlen, std::strstr
#include <stdexcept>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/core/demangle.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/if.hpp>
#include <boost/functional/hash_fwd.hpp>
#ifdef __GNUC__
# include <cxxabi.h> // abi::__cxa_demangle
#endif
#if !defined(BOOST_MSVC)
# include <boost/assert.hpp>
# include <boost/detail/no_exceptions_support.hpp>
#if (defined(_MSC_VER) && _MSC_VER > 1600) \
|| (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) \
|| (defined(__GNUC__) && __GNUC__ > 4 && __cplusplus >= 201103)
# define BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
#else
# include <boost/container_hash/hash.hpp>
#endif
#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
# include <boost/type_traits/is_arithmetic.hpp>
# include <boost/type_traits/is_signed.hpp>
# include <boost/type_traits/make_signed.hpp>
# include <boost/type_traits/type_identity.hpp>
#endif
namespace boost { namespace typeind {
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost { namespace typeindex {
/// \class stl_type_index
/// This class is a wrapper around std::type_info, that workarounds issues and provides
/// much more rich interface. For description of functions see type_index_facade.
/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
///
/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index.
class stl_type_index
@ -132,49 +132,60 @@ inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
}
inline std::string stl_type_index::pretty_name() const {
#if defined(_MSC_VER)
std::string ret = data_->name();
#else
std::string ret;
int status = 0;
char* demang = abi::__cxa_demangle(raw_name(), NULL, 0, &status);
BOOST_ASSERT(!status);
static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;
BOOST_TRY {
ret = demang; // may throw out of memory exception
} BOOST_CATCH (...) {
free(demang);
BOOST_RETHROW;
} BOOST_CATCH_END
// In case of MSVC demangle() is a no-op, and name() already returns demangled name.
// In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it.
const boost::core::scoped_demangled_name demangled_name(data_->name());
free(demang);
#endif
std::string::size_type pos = ret.find("boost::typeind::detail::cvr_saver<");
if (pos == std::string::npos) {
return ret;
const char* begin = demangled_name.get();
if (!begin) {
boost::throw_exception(std::runtime_error("Type name demangling failed"));
}
pos += sizeof("boost::typeind::detail::cvr_saver<") - 1;
while (ret[pos] == ' ') {
++ pos;
const std::string::size_type len = std::strlen(begin);
const char* end = begin + len;
if (len > cvr_saver_name_len) {
const char* b = std::strstr(begin, cvr_saver_name);
if (b) {
b += cvr_saver_name_len;
// Trim leading spaces
while (*b == ' ') { // the string is zero terminated, we won't exceed the buffer size
++ b;
}
// Skip the closing angle bracket
const char* e = end - 1;
while (e > b && *e != '>') {
-- e;
}
// Trim trailing spaces
while (e > b && *(e - 1) == ' ') {
-- e;
}
if (b < e) {
// Parsing seems to have succeeded, the type name is not empty
begin = b;
end = e;
}
}
}
std::string::size_type end = ret.rfind(">");
while (ret[end - 1] == ' ') {
-- end;
}
return ret.substr(pos, end - pos);
return std::string(begin, end);
}
inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
#if _MSC_VER > 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__))
#ifdef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
return data_->hash_code();
#else
#else
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
#endif
#endif
}
@ -187,42 +198,49 @@ inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
|| (defined(__sgi) && defined(__host_mips)) \
|| (defined(__hpux) && defined(__HP_aCC)) \
|| (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
# define BOOST_CLASSINFO_COMPARE_BY_NAMES
# define BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
# endif
/// @endcond
inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT {
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
#ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
#else
return *data_ == *rhs.data_;
return !!(*data_ == *rhs.data_);
#endif
}
inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT {
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
#ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
#else
return !!data_->before(*rhs.data_);
#endif
}
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
#undef BOOST_CLASSINFO_COMPARE_BY_NAMES
#endif
#undef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
template <class T>
inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT {
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_t;
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_prefinal_t;
# if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
BOOST_STATIC_ASSERT_MSG( !boost::is_arithmetic<no_cvr_t>::type::value
, "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions.");
// Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
// in typeid() expressions. Full template specialization for 'integral' fixes that issue:
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_signed<no_cvr_prefinal_t>::value,
boost::make_signed<no_cvr_prefinal_t>,
boost::type_identity<no_cvr_prefinal_t>
>::type no_cvr_prefinal_lazy_t;
typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t;
#else
typedef no_cvr_prefinal_t no_cvr_t;
#endif
return typeid(no_cvr_t);
@ -234,10 +252,8 @@ namespace detail {
template <class T>
inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
typedef typename boost::mpl::if_c<
boost::is_reference<T>::value
|| boost::is_const<T>::value
|| boost::is_volatile<T>::value,
typedef BOOST_DEDUCED_TYPENAME boost::conditional<
boost::is_reference<T>::value || boost::is_const<T>::value || boost::is_volatile<T>::value,
detail::cvr_saver<T>,
T
>::type type;
@ -248,15 +264,15 @@ inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
template <class T>
inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT {
#ifdef BOOST_NO_RTTI
return value.type_id_runtime();
#ifdef BOOST_NO_RTTI
return value.boost_type_index_type_id_runtime_();
#else
return typeid(value);
#endif
}
}} // namespace boost::typeind
}} // namespace boost::typeindex
#undef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP

View File

@ -1,5 +1,5 @@
//
// Copyright (c) Antony Polukhin, 2013-2014.
// Copyright 2013-2022 Antony Polukhin.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -9,13 +9,8 @@
#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/functional/hash_fwd.hpp>
#include <boost/container_hash/hash_fwd.hpp>
#include <string>
#include <cstring>
@ -27,7 +22,11 @@
#endif
#endif
namespace boost { namespace typeind {
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
namespace boost { namespace typeindex {
/// \class type_index_facade
///
@ -54,63 +53,71 @@ namespace boost { namespace typeind {
///
/// \tparam Derived Class derived from type_index_facade.
/// \tparam TypeInfo Class that will be used as a base type_info class.
/// \note Take a look at the protected methods. They are \b not \b defined in type_index_facade.
/// Protected member functions raw_name() \b must be defined in Derived class. All the other
/// methods are mandatory.
/// \see 'Making a custom type_index' section for more information about
/// creating your own type_index using type_index_facade.
template <class Derived, class TypeInfo>
class type_index_facade {
private:
/// @cond
const Derived & derived() const BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR const Derived & derived() const BOOST_NOEXCEPT {
return *static_cast<Derived const*>(this);
}
/// @endcond
public:
typedef TypeInfo type_info_t;
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
/// \return Const reference to underlying low level type_info_t.
inline const type_info_t& type_info() const BOOST_NOEXCEPT {
return derived().type_info();
}
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
/// \return Pointer to unredable/raw type name.
inline const char* raw_name() const BOOST_NOEXCEPT {
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
/// \return Name of a type. By default returns Derived::raw_name().
inline const char* name() const BOOST_NOEXCEPT {
return derived().raw_name();
}
/// \b Override: This function \b must be redefined in Derived class. Overrides may throw.
/// \return Human redable type name.
/// \b Override: This function \b may be redefined in Derived class. Overrides may throw.
/// \return Human readable type name. By default returns Derived::name().
inline std::string pretty_name() const {
return derived().pretty_name();
}
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
/// \return Name of a type. By default retuns raw_name().
inline const char* name() const BOOST_NOEXCEPT {
return raw_name();
return derived().name();
}
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
/// \return True if two types are equal. By default compares types by raw_name().
inline bool equal(const Derived& rhs) const BOOST_NOEXCEPT {
return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
const char* const left = derived().raw_name();
const char* const right = rhs.raw_name();
return left == right || !std::strcmp(left, right);
}
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
/// \return True if rhs is greater than this. By default compares types by raw_name().
inline bool before(const Derived& rhs) const BOOST_NOEXCEPT {
return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
const char* const left = derived().raw_name();
const char* const right = rhs.raw_name();
return left != right && std::strcmp(left, right) < 0;
}
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
/// \return Hash code of a type. By default hashes types by raw_name().
/// \note Derived class header \b must include <boost/container_hash/hash.hpp>, \b unless this function is redefined in
/// Derived class to not use boost::hash_range().
inline std::size_t hash_code() const BOOST_NOEXCEPT {
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
const char* const name_raw = derived().raw_name();
return boost::hash_range(name_raw, name_raw + std::strlen(name_raw));
}
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
protected:
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
/// \return Pointer to unredable/raw type name.
inline const char* raw_name() const BOOST_NOEXCEPT;
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
/// \return Const reference to underlying low level type_info_t.
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
/// This is a factory method that is used to create instances of Derived classes.
/// boost::typeind::type_id() will call this method, if Derived has same type as boost::typeind::type_index.
/// boost::typeindex::type_id() will call this method, if Derived has same type as boost::typeindex::type_index.
///
/// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
/// Overrides \b must remove const, volatile && and & modifiers from T.
@ -120,7 +127,7 @@ protected:
static Derived type_id() BOOST_NOEXCEPT;
/// This is a factory method that is used to create instances of Derived classes.
/// boost::typeind::type_id_with_cvr() will call this method, if Derived has same type as boost::typeind::type_index.
/// boost::typeindex::type_id_with_cvr() will call this method, if Derived has same type as boost::typeindex::type_index.
///
/// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
/// Overrides \b must \b not remove const, volatile && and & modifiers from T.
@ -130,7 +137,7 @@ protected:
static Derived type_id_with_cvr() BOOST_NOEXCEPT;
/// This is a factory method that is used to create instances of Derived classes.
/// boost::typeind::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeind::type_index.
/// boost::typeindex::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeindex::type_index.
///
/// \b Override: This function \b may be redefined and made public in Derived class.
/// \param variable Variable which runtime type will be stored in type_index.
@ -144,34 +151,34 @@ protected:
/// @cond
template <class Derived, class TypeInfo>
inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return static_cast<Derived const&>(lhs).equal(static_cast<Derived const&>(rhs));
}
template <class Derived, class TypeInfo>
inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));;
BOOST_CXX14_CONSTEXPR inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));
}
template <class Derived, class TypeInfo>
inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return rhs < lhs;
}
template <class Derived, class TypeInfo>
inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs > rhs);
}
template <class Derived, class TypeInfo>
inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs < rhs);
}
template <class Derived, class TypeInfo>
inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
BOOST_CXX14_CONSTEXPR inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs == rhs);
}
@ -244,13 +251,13 @@ inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
/// noexcept comparison operators for type_index_facade classes.
bool operator ? (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;
bool operator ==, !=, <, ... (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;
/// noexcept comparison operators for type_index_facade and it's TypeInfo classes.
bool operator ? (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;
bool operator ==, !=, <, ... (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;
/// noexcept comparison operators for type_index_facade's TypeInfo and type_index_facade classes.
bool operator ? (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
bool operator ==, !=, <, ... (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
#endif
@ -260,7 +267,7 @@ bool operator ? (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
/// Ostream operator that will output demangled name
template <class Derived, class TypeInfo>
inline std::ostream& operator<<(std::ostream& ostr, const type_index_facade<Derived, TypeInfo>& ind) {
ostr << ind.pretty_name();
ostr << static_cast<Derived const&>(ind).pretty_name();
return ostr;
}
/// @endcond
@ -271,19 +278,20 @@ inline std::basic_ostream<CharT, TriatT>& operator<<(
std::basic_ostream<CharT, TriatT>& ostr,
const type_index_facade<Derived, TypeInfo>& ind)
{
ostr << ind.pretty_name();
ostr << static_cast<Derived const&>(ind).pretty_name();
return ostr;
}
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
#endif // BOOST_NO_IOSTREAM
/// This free function is used by Boost's unordered containers.
/// \note <boost/container_hash/hash.hpp> has to be included if this function is used.
template <class Derived, class TypeInfo>
inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) BOOST_NOEXCEPT {
return static_cast<Derived const&>(lhs).hash_code();
}
}} // namespace boost::typeind
}} // namespace boost::typeindex
#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP

35
index.html Normal file
View 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>
&copy; 2014-2022 Antony Polukhin
</p>
</body>
</html>

15
meta/libraries.json Normal file
View 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"
}

View File

@ -1,131 +0,0 @@
From b59340efc30219492b095d2cfcdb8183b3e35b69 Mon Sep 17 00:00:00 2001
From: Antony Polukhin <antoshkka@gmail.com>
Date: Thu, 20 Feb 2014 17:06:44 +0400
Subject: [PATCH 1/2] Boost.Any not can work without RTTI support.
---
test/Jamfile.v2 | 1 +
1 file changed, 1 insertion(+)
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index cd167dc..76f9e5a 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -9,6 +9,7 @@
test-suite any :
[ run any_test.cpp ]
[ run any_test_rv.cpp ]
+ [ run any_test_rv.cpp : : : <rtti>off : any_test_rv_no_rtti ]
[ compile-fail any_cast_cv_failed.cpp ]
[ compile-fail any_test_temporary_to_ref_failed.cpp ]
[ compile-fail any_test_cv_to_rv_failed.cpp ]
--
1.8.5.3
From 62b9b01713fc50355f82e892bc0fd5618ce5c648 Mon Sep 17 00:00:00 2001
From: Antony Polukhin <antoshkka@gmail.com>
Date: Thu, 20 Feb 2014 17:30:42 +0400
Subject: [PATCH 2/2] Boost.Any not can work without RTTI support.
---
include/boost/any.hpp | 37 +++++++++++++------------------------
1 file changed, 13 insertions(+), 24 deletions(-)
diff --git a/include/boost/any.hpp b/include/boost/any.hpp
index a63fea4..bda00a2 100644
--- a/include/boost/any.hpp
+++ b/include/boost/any.hpp
@@ -15,9 +15,9 @@
// when: July 2001, April 2013 - May 2013
#include <algorithm>
-#include <typeinfo>
#include "boost/config.hpp"
+#include <boost/type_index.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/add_reference.hpp>
@@ -29,17 +29,6 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_const.hpp>
-// See boost/python/type_id.hpp
-// TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp
-# if defined(__GNUC__) \
- || defined(_AIX) \
- || ( defined(__sgi) && defined(__host_mips)) \
- || (defined(__hpux) && defined(__HP_aCC)) \
- || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
-# define BOOST_AUX_ANY_TYPE_ID_NAME
-#include <cstring>
-# endif
-
namespace boost
{
class any
@@ -144,9 +133,9 @@ namespace boost
any().swap(*this);
}
- const std::type_info & type() const BOOST_NOEXCEPT
+ const boost::typeind::type_info& type() const BOOST_NOEXCEPT
{
- return content ? content->type() : typeid(void);
+ return content ? content->type() : boost::typeind::type_id<void>().type_info();
}
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -165,7 +154,7 @@ namespace boost
public: // queries
- virtual const std::type_info & type() const BOOST_NOEXCEPT = 0;
+ virtual const boost::typeind::type_info& type() const BOOST_NOEXCEPT = 0;
virtual placeholder * clone() const = 0;
@@ -189,9 +178,9 @@ namespace boost
#endif
public: // queries
- virtual const std::type_info & type() const BOOST_NOEXCEPT
+ virtual const boost::typeind::type_info& type() const BOOST_NOEXCEPT
{
- return typeid(ValueType);
+ return boost::typeind::type_id<ValueType>().type_info();
}
virtual placeholder * clone() const
@@ -232,7 +221,12 @@ namespace boost
lhs.swap(rhs);
}
- class BOOST_SYMBOL_VISIBLE bad_any_cast : public std::bad_cast
+ class BOOST_SYMBOL_VISIBLE bad_any_cast :
+#ifndef BOOST_NO_RTTI
+ public std::bad_cast
+#else
+ public std::exception
+#endif
{
public:
virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
@@ -245,12 +239,7 @@ namespace boost
template<typename ValueType>
ValueType * any_cast(any * operand) BOOST_NOEXCEPT
{
- return operand &&
-#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
- std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0
-#else
- operand->type() == typeid(ValueType)
-#endif
+ return operand && operand->type() == boost::typeind::type_id<ValueType>()
? &static_cast<any::holder<ValueType> *>(operand->content)->held
: 0;
}
--
1.8.5.3

View File

@ -1,60 +0,0 @@
From 6f71069e85fab36d9b95d53ddb6d80b8d1bdb6b0 Mon Sep 17 00:00:00 2001
From: Antony Polukhin <antoshkka@gmail.com>
Date: Thu, 20 Feb 2014 18:33:20 +0400
Subject: [PATCH] Use TypeIndex in Boost.Function to remove duplicate code and
improve code performance
---
include/boost/function/function_base.hpp | 22 +---------------------
test/Jamfile.v2 | 2 ++
2 files changed, 3 insertions(+), 21 deletions(-)
diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp
index f3663d7..8fd2c8d 100644
--- a/include/boost/function/function_base.hpp
+++ b/include/boost/function/function_base.hpp
@@ -44,27 +44,7 @@
# pragma warning( disable : 4127 ) // "conditional expression is constant"
#endif
-// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
-#ifdef BOOST_NO_STD_TYPEINFO
-// Embedded VC++ does not have type_info in namespace std
-# define BOOST_FUNCTION_STD_NS
-#else
-# define BOOST_FUNCTION_STD_NS std
-#endif
-
-// Borrowed from Boost.Python library: determines the cases where we
-// need to use std::type_info::name to compare instead of operator==.
-#if defined( BOOST_NO_TYPEID )
-# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
-#elif defined(__GNUC__) \
- || defined(_AIX) \
- || ( defined(__sgi) && defined(__host_mips))
-# include <cstring>
-# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \
- (std::strcmp((X).name(),(Y).name()) == 0)
-# else
-# define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
-#endif
+#define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) (boost::typeind::type_index((X))==(Y))
#if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG)
# define BOOST_FUNCTION_TARGET_FIX(x) x
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index 68895fa..12a00db 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -21,6 +21,8 @@ import testing ;
:
[ run libs/function/test/function_test.cpp : : : : lib_function_test ]
+ [ run libs/function/test/function_test.cpp : : : <rtti>off : lib_function_test_no_rtti ]
+
[ run libs/function/test/function_n_test.cpp : : : : ]
[ run libs/function/test/allocator_test.cpp ../../../libs/test/build//boost_test_exec_monitor : : : : ]
--
1.8.5.3

View File

@ -1,58 +0,0 @@
From fcd4da81d14847272fa888f4e9a54930b48ee95b Mon Sep 17 00:00:00 2001
From: Antony Polukhin <antoshkka@gmail.com>
Date: Sat, 11 Jan 2014 19:19:20 +0400
Subject: [PATCH] Make Boost.Test work with RTTI disabled (fixes #9228)
---
include/boost/test/execution_monitor.hpp | 2 +-
include/boost/test/tree/test_case_template.hpp | 13 +++++++++++--
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/include/boost/test/execution_monitor.hpp b/include/boost/test/execution_monitor.hpp
index f6b7681..259f97c 100644
--- a/include/boost/test/execution_monitor.hpp
+++ b/include/boost/test/execution_monitor.hpp
@@ -261,7 +261,7 @@ public:
template<typename ExceptionType>
void erase_exception_translator( boost::type<ExceptionType>* = 0 )
{
- m_custom_translators = m_custom_translators->erase<ExceptionType>( m_custom_translators );
+ m_custom_translators = m_custom_translators->template erase<ExceptionType>( m_custom_translators );
}
private:
diff --git a/include/boost/test/tree/test_case_template.hpp b/include/boost/test/tree/test_case_template.hpp
index 9f7466a..b0fa634 100644
--- a/include/boost/test/tree/test_case_template.hpp
+++ b/include/boost/test/tree/test_case_template.hpp
@@ -34,8 +34,13 @@
#include <boost/type_traits/is_const.hpp>
#include <boost/function/function0.hpp>
-// STL
+#ifndef BOOST_NO_RTTI
#include <typeinfo> // for typeid
+#else
+#include <boost/current_function.hpp>
+#endif
+
+// STL
#include <string> // for std::string
#include <list> // for std::list
@@ -77,7 +82,11 @@ struct generate_test_case_4_type {
std::string full_name;
assign_op( full_name, m_test_case_name, 0 );
full_name += '<';
- full_name += typeid(TestType).name();
+#ifndef BOOST_NO_RTTI
+ full_name += typeid(TestType).name();
+#else
+ full_name += BOOST_CURRENT_FUNCTION;
+#endif
if( boost::is_const<TestType>::value )
full_name += " const";
full_name += '>';
--
1.8.5.3

View File

@ -1,70 +0,0 @@
From 21f31f2ceb6d5669ca4e0bcc7b62cf1836eb7002 Mon Sep 17 00:00:00 2001
From: Antony Polukhin <antoshkka@gmail.com>
Date: Thu, 20 Feb 2014 17:26:24 +0400
Subject: [PATCH] Boost.Variant not can work without RTTI support.
---
include/boost/variant/variant.hpp | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/include/boost/variant/variant.hpp b/include/boost/variant/variant.hpp
index 46c3ae3..8604ba9 100644
--- a/include/boost/variant/variant.hpp
+++ b/include/boost/variant/variant.hpp
@@ -18,9 +18,7 @@
#include <cstddef> // for std::size_t
#include <new> // for placement new
-#if !defined(BOOST_NO_TYPEID)
-#include <typeinfo> // for typeid, std::type_info
-#endif // BOOST_NO_TYPEID
+#include "boost/type_index.hpp"
#include "boost/variant/detail/config.hpp"
#include "boost/mpl/aux_/value_wknd.hpp"
@@ -829,24 +827,19 @@ private:
//
// Generic static visitor that performs a typeid on the value it visits.
//
-
-#if !defined(BOOST_NO_TYPEID)
-
class reflect
- : public static_visitor<const std::type_info&>
+ : public static_visitor<const boost::typeind::type_info&>
{
public: // visitor interfaces
template <typename T>
- const std::type_info& operator()(const T&) const BOOST_NOEXCEPT
+ const boost::typeind::type_info& operator()(const T&) const BOOST_NOEXCEPT
{
- return typeid(T);
+ return boost::typeind::type_id<T>().type_info();
}
};
-#endif // BOOST_NO_TYPEID
-
///////////////////////////////////////////////////////////////////////////////
// (detail) class comparer
//
@@ -2155,13 +2148,11 @@ public: // queries
return false;
}
-#if !defined(BOOST_NO_TYPEID)
- const std::type_info& type() const
+ const boost::typeind::type_info& type() const
{
detail::variant::reflect visitor;
return this->apply_visitor(visitor);
}
-#endif
public: // prevent comparison with foreign types
--
1.8.5.3

View File

@ -1,4 +1,4 @@
# Copyright (C) 2012-2014 Antony Polukhin
# Copyright 2012-2022 Antony Polukhin
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -8,22 +8,26 @@ import testing ;
import feature ;
import os ;
# Variable that contains all the stuff required for linking against -lboost_unit_test
tlib = /boost/test//boost_unit_test_framework/<link>static ;
# Variable that contains all the stuff required for linking together <rtti>on and <rtti>off
compat = <define>BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY ;
# Making own `nortti` that is link compatible
nortti = <toolset>gcc:<cxxflags>-fno-rtti <toolset>clang:<cxxflags>-fno-rtti <toolset>msvc:<cxxflags>/GR- ;
# Making own `nortti` that is link compatible.
# We explicitly define BOOST_NO_RTTI because it sometimes can not be detected by build system.
nortti = <toolset>gcc:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>clang:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>intel:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>darwin:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>msvc:<cxxflags>"/GR-" ;
norttidefines = <toolset>gcc:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>clang:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>intel:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>darwin:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>msvc:<cxxflags>"-DBOOST_NO_RTTI" ;
# Making libraries that CANNOT work between rtti-on/rtti-off modules
obj test_lib_nortti-obj : test_lib.cpp : <link>shared <rtti>off ;
lib test_lib_nortti : test_lib_nortti-obj : <link>shared <rtti>off ;
obj test_lib_nortti-obj : test_lib.cpp : <link>shared <rtti>off $(norttidefines) ;
obj test_lib_anonymous_nortti-obj : test_lib_anonymous.cpp : <link>shared <rtti>off $(norttidefines) ;
lib test_lib_nortti : test_lib_nortti-obj : <link>shared <rtti>off $(norttidefines) ;
lib test_lib_anonymous_nortti : test_lib_anonymous_nortti-obj : <link>shared <rtti>off $(norttidefines) ;
obj test_lib_rtti-obj : test_lib.cpp : <link>shared ;
obj test_lib_anonymous_rtti-obj : test_lib_anonymous.cpp : <link>shared ;
lib test_lib_rtti : test_lib_rtti-obj : <link>shared ;
lib test_lib_anonymous_rtti : test_lib_anonymous_rtti-obj : <link>shared ;
# Making libraries that can work between rtti-on/rtti-off modules
obj test_lib_nortti_compat-obj : test_lib.cpp : <link>shared $(nortti) $(compat) ;
@ -31,23 +35,34 @@ obj test_lib_rtti_compat-obj : test_lib.cpp : <link>shared $(nortti) $(compat) ;
lib test_lib_nortti_compat : test_lib_nortti_compat-obj : <link>shared $(nortti) $(compat) ;
lib test_lib_rtti_compat : test_lib_rtti_compat-obj : <link>shared $(nortti) $(compat) ;
exe testing_crossmodule_anonymous_no_rtti : testing_crossmodule_anonymous.cpp test_lib_anonymous_nortti : <rtti>off $(norttidefines) ;
test-suite type_index
:
[ run type_index_test.cpp $(tlib) ]
[ run type_index_test.cpp $(tlib) : : : <rtti>off : type_index_test_no_rtti ]
[ run testing_crossmodule.cpp test_lib_rtti $(tlib) ]
[ run testing_crossmodule.cpp test_lib_nortti $(tlib) : : : <rtti>off : testing_crossmodule_no_rtti ]
[ run type_index_test.cpp ]
[ run type_index_runtime_cast_test.cpp ]
[ run type_index_constexpr_test.cpp ]
[ run type_index_test.cpp : : : <rtti>off $(norttidefines) : type_index_test_no_rtti ]
[ run ctti_print_name.cpp : : : <test-info>always_show_run_output ]
[ run testing_crossmodule.cpp test_lib_rtti ]
[ run testing_crossmodule.cpp test_lib_nortti : : : <rtti>off $(norttidefines) : testing_crossmodule_no_rtti ]
[ run testing_crossmodule_anonymous.cpp test_lib_anonymous_rtti : : : <test-info>always_show_run_output ]
[ run compare_ctti_stl.cpp ]
[ run track_13621.cpp ]
[ compile-fail type_index_test_ctti_copy_fail.cpp ]
[ compile-fail type_index_test_ctti_construct_fail.cpp ]
[ compile type_index_test_ctti_alignment.cpp ]
# Mixing RTTI on and off
[ link-fail testing_crossmodule.cpp $(tlib) test_lib_rtti : $(nortti) : link_fail_nortti_rtti ]
# MSVC sometimes overrides the /GR-, that's why the following tests is disabled
#[ link-fail testing_crossmodule.cpp $(tlib) test_lib_nortti : : link_fail_rtti_nortti ]
[ run testing_crossmodule.cpp $(tlib) test_lib_rtti_compat : : : $(nortti) $(compat) : testing_crossmodule_nortti_rtti_compat ]
[ run testing_crossmodule.cpp $(tlib) test_lib_nortti_compat : : : $(compat) : testing_crossmodule_rtti_nortti_compat ]
# MSVC sometimes overrides the /GR-, without `detect_missmatch` this test may link.
# TODO: Disabled on MSVC. Enable again when there'll be an understanding of how to write this test correctly wor MSVC.
[ link-fail testing_crossmodule.cpp test_lib_rtti : $(nortti) <toolset>msvc:<build>no : link_fail_nortti_rtti ]
[ link-fail testing_crossmodule.cpp test_lib_nortti : <toolset>msvc:<build>no : link_fail_rtti_nortti ]
[ run testing_crossmodule.cpp test_lib_rtti_compat : : : $(nortti) $(compat) : testing_crossmodule_nortti_rtti_compat ]
[ run testing_crossmodule.cpp test_lib_nortti_compat : : : $(compat) : testing_crossmodule_rtti_nortti_compat ]
;
# Assuring that examples compile and run. Adding sources from `examples` directory to the `type_index` test suite.
@ -58,6 +73,9 @@ for local p in [ glob ../examples/*.cpp ]
# RTTI off
local target_name = $(p[1]:B)_no_rtti ;
type_index += [ run $(p) : : : <rtti>off : $(target_name) ] ;
if $(target_name) != "table_of_names_no_rtti"
{
type_index += [ run $(p) : : : <rtti>off $(norttidefines) : $(target_name) ] ;
}
}

90
test/appveyor.yml Normal file
View 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
View 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
View 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;
}

View File

@ -1,3 +1,11 @@
//
// Copyright 2012-2022 Antony Polukhin.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#define TEST_LIB_SOURCE
#include "test_lib.hpp"
@ -7,25 +15,26 @@ namespace user_defined_namespace {
namespace test_lib {
boost::typeind::type_index get_integer() {
return boost::typeind::type_id<int>();
boost::typeindex::type_index get_integer() {
return boost::typeindex::type_id<int>();
}
boost::typeind::type_index get_user_defined_class() {
return boost::typeind::type_id<user_defined_namespace::user_defined>();
boost::typeindex::type_index get_user_defined_class() {
return boost::typeindex::type_id<user_defined_namespace::user_defined>();
}
boost::typeind::type_index get_const_integer() {
return boost::typeind::type_id_with_cvr<const int>();
boost::typeindex::type_index get_const_integer() {
return boost::typeindex::type_id_with_cvr<const int>();
}
boost::typeind::type_index get_const_user_defined_class() {
return boost::typeind::type_id_with_cvr<const user_defined_namespace::user_defined>();
boost::typeindex::type_index get_const_user_defined_class() {
return boost::typeindex::type_id_with_cvr<const user_defined_namespace::user_defined>();
}
#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
// Just do nothing
void accept_typeindex(const boost::typeind::type_index&) {}
void accept_typeindex(const boost::typeindex::type_index&) {}
#endif
}

View File

@ -1,5 +1,5 @@
//
// Copyright (c) Antony Polukhin, 2012-2013.
// Copyright 2012-2022 Antony Polukhin.
//
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -25,14 +25,16 @@
namespace test_lib {
TEST_LIB_DECL boost::typeind::type_index get_integer();
TEST_LIB_DECL boost::typeind::type_index get_user_defined_class();
TEST_LIB_DECL boost::typeindex::type_index get_integer();
TEST_LIB_DECL boost::typeindex::type_index get_user_defined_class();
TEST_LIB_DECL boost::typeind::type_index get_const_integer();
TEST_LIB_DECL boost::typeind::type_index get_const_user_defined_class();
TEST_LIB_DECL boost::typeindex::type_index get_const_integer();
TEST_LIB_DECL boost::typeindex::type_index get_const_user_defined_class();
#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
// This is required for checking RTTI on/off linkage
TEST_LIB_DECL void accept_typeindex(const boost::typeind::type_index&);
TEST_LIB_DECL void accept_typeindex(const boost::typeindex::type_index&);
#endif
}

View 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>();
}
}

View 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

View File

@ -1,47 +1,57 @@
//
// Copyright Antony Polukhin, 2012-2013.
// Copyright 2012-2022 Antony Polukhin.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_TEST_MODULE testing_crossmodule_module
#include <boost/test/unit_test.hpp>
#include <boost/type_index.hpp>
#include "test_lib.hpp"
#include <boost/core/lightweight_test.hpp>
namespace user_defined_namespace {
class user_defined{};
}
BOOST_AUTO_TEST_CASE(comparing_types_between_modules)
void comparing_types_between_modules()
{
boost::typeind::type_index t_const_int = boost::typeind::type_id_with_cvr<const int>();
boost::typeind::type_index t_int = boost::typeind::type_id<int>();
boost::typeindex::type_index t_const_int = boost::typeindex::type_id_with_cvr<const int>();
boost::typeindex::type_index t_int = boost::typeindex::type_id<int>();
BOOST_CHECK_EQUAL(t_int, test_lib::get_integer());
BOOST_CHECK_EQUAL(t_const_int, test_lib::get_const_integer());
BOOST_CHECK_NE(t_const_int, test_lib::get_integer());
BOOST_CHECK_NE(t_int, test_lib::get_const_integer());
BOOST_TEST_EQ(t_int, test_lib::get_integer());
BOOST_TEST_EQ(t_const_int, test_lib::get_const_integer());
BOOST_TEST_NE(t_const_int, test_lib::get_integer());
BOOST_TEST_NE(t_int, test_lib::get_const_integer());
boost::typeind::type_index t_const_userdef
= boost::typeind::type_id_with_cvr<const user_defined_namespace::user_defined>();
boost::typeind::type_index t_userdef
= boost::typeind::type_id<user_defined_namespace::user_defined>();
boost::typeindex::type_index t_const_userdef
= boost::typeindex::type_id_with_cvr<const user_defined_namespace::user_defined>();
boost::typeindex::type_index t_userdef
= boost::typeindex::type_id<user_defined_namespace::user_defined>();
BOOST_CHECK_EQUAL(t_userdef, test_lib::get_user_defined_class());
BOOST_CHECK_EQUAL(t_const_userdef, test_lib::get_const_user_defined_class());
BOOST_CHECK_NE(t_const_userdef, test_lib::get_user_defined_class());
BOOST_CHECK_NE(t_userdef, test_lib::get_const_user_defined_class());
BOOST_TEST_EQ(t_userdef, test_lib::get_user_defined_class());
BOOST_TEST_EQ(t_const_userdef, test_lib::get_const_user_defined_class());
BOOST_TEST_NE(t_const_userdef, test_lib::get_user_defined_class());
BOOST_TEST_NE(t_userdef, test_lib::get_const_user_defined_class());
BOOST_CHECK_NE(t_userdef, test_lib::get_integer());
BOOST_CHECK_NE(t_const_userdef, test_lib::get_integer());
BOOST_CHECK_NE(t_int, test_lib::get_user_defined_class());
BOOST_CHECK_NE(t_const_int, test_lib::get_const_user_defined_class());
BOOST_TEST_NE(t_userdef, test_lib::get_integer());
BOOST_TEST_NE(t_const_userdef, test_lib::get_integer());
BOOST_TEST_NE(t_int, test_lib::get_user_defined_class());
BOOST_TEST_NE(t_const_int, test_lib::get_const_user_defined_class());
test_lib::accept_typeindex(t_int);
// MSVC supports detect_missmatch pragma, but /GR- silently switch disable the link time check.
// /GR- undefies the _CPPRTTI macro. Using it to detect working detect_missmatch pragma.
#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
test_lib::accept_typeindex(t_int);
#endif
}
int main() {
comparing_types_between_modules();
return boost::report_errors();
}

View 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
View 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();
}

View 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();
}

View 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();
}

View File

@ -1,18 +1,16 @@
//
// Copyright Antony Polukhin, 2012-2013.
// Copyright 2012-2022 Antony Polukhin.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_TEST_MODULE type_index_test_module
#include <boost/test/unit_test.hpp>
#include <boost/type_index.hpp>
#include <boost/functional/hash.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/core/lightweight_test.hpp>
namespace my_namespace1 {
class my_class{};
}
@ -23,116 +21,118 @@ namespace my_namespace2 {
}
BOOST_AUTO_TEST_CASE(names_matches_type_id)
void names_matches_type_id()
{
using namespace boost::typeind;
BOOST_CHECK_EQUAL(type_id<int>().pretty_name(), "int");
BOOST_CHECK_EQUAL(type_id<double>().pretty_name(), "double");
using namespace boost::typeindex;
BOOST_TEST_EQ(type_id<int>().pretty_name(), "int");
BOOST_TEST_EQ(type_id<double>().pretty_name(), "double");
BOOST_CHECK_EQUAL(type_id<int>().name(), type_id<int>().name());
BOOST_CHECK_NE(type_id<int>().name(), type_id<double>().name());
BOOST_CHECK_NE(type_id<double>().name(), type_id<int>().name());
BOOST_CHECK_EQUAL(type_id<double>().name(), type_id<double>().name());
BOOST_TEST_EQ(type_id<int>().name(), type_id<int>().name());
BOOST_TEST_NE(type_id<int>().name(), type_id<double>().name());
BOOST_TEST_NE(type_id<double>().name(), type_id<int>().name());
BOOST_TEST_EQ(type_id<double>().name(), type_id<double>().name());
}
BOOST_AUTO_TEST_CASE(default_construction)
void default_construction()
{
using namespace boost::typeind;
using namespace boost::typeindex;
type_index ti1, ti2;
BOOST_CHECK_EQUAL(ti1, ti2);
BOOST_CHECK_EQUAL(type_id<void>(), ti1);
BOOST_TEST_EQ(ti1, ti2);
BOOST_TEST_EQ(type_id<void>(), ti1);
BOOST_CHECK_EQUAL(type_id<void>().name(), ti1.name());
BOOST_CHECK_NE(type_id<int>(), ti1);
BOOST_TEST_EQ(type_id<void>().name(), ti1.name());
BOOST_TEST_NE(type_id<int>(), ti1);
}
BOOST_AUTO_TEST_CASE(copy_construction)
void copy_construction()
{
using namespace boost::typeind;
using namespace boost::typeindex;
type_index ti1, ti2 = type_id<int>();
BOOST_CHECK_NE(ti1, ti2);
BOOST_TEST_NE(ti1, ti2);
ti1 = ti2;
BOOST_CHECK_EQUAL(ti2, ti1);
BOOST_TEST_EQ(ti2, ti1);
const type_index ti3(ti1);
BOOST_CHECK_EQUAL(ti3, ti1);
BOOST_TEST_EQ(ti3, ti1);
}
BOOST_AUTO_TEST_CASE(comparators_type_id)
void comparators_type_id()
{
using namespace boost::typeind;
using namespace boost::typeindex;
type_index t_int = type_id<int>();
type_index t_double = type_id<double>();
BOOST_CHECK_EQUAL(t_int, t_int);
BOOST_CHECK_LE(t_int, t_int);
BOOST_CHECK_GE(t_int, t_int);
BOOST_CHECK_NE(t_int, t_double);
BOOST_TEST_EQ(t_int, t_int);
BOOST_TEST_LE(t_int, t_int);
BOOST_TEST_GE(t_int, t_int);
BOOST_TEST_NE(t_int, t_double);
BOOST_CHECK_LE(t_double, t_double);
BOOST_CHECK_GE(t_double, t_double);
BOOST_CHECK_NE(t_double, t_int);
BOOST_TEST_LE(t_double, t_double);
BOOST_TEST_GE(t_double, t_double);
BOOST_TEST_NE(t_double, t_int);
BOOST_CHECK(t_double < t_int || t_int < t_double);
BOOST_CHECK(t_double > t_int || t_int > t_double);
BOOST_TEST(t_double < t_int || t_int < t_double);
BOOST_TEST(t_double > t_int || t_int > t_double);
}
BOOST_AUTO_TEST_CASE(hash_code_type_id)
void hash_code_type_id()
{
using namespace boost::typeind;
using namespace boost::typeindex;
std::size_t t_int1 = type_id<int>().hash_code();
std::size_t t_double1 = type_id<double>().hash_code();
std::size_t t_int2 = type_id<int>().hash_code();
std::size_t t_double2 = type_id<double>().hash_code();
BOOST_CHECK_EQUAL(t_int1, t_int2);
BOOST_CHECK_NE(t_int1, t_double2);
BOOST_CHECK_LE(t_double1, t_double2);
BOOST_TEST_EQ(t_int1, t_int2);
BOOST_TEST_NE(t_int1, t_double2);
BOOST_TEST_LE(t_double1, t_double2);
}
template <class T1, class T2>
static void test_with_modofiers() {
using namespace boost::typeind;
using namespace boost::typeindex;
type_index t1 = type_id_with_cvr<T1>();
type_index t2 = type_id_with_cvr<T2>();
BOOST_CHECK_NE(t2, t1);
BOOST_CHECK(t2 != t1.type_info());
BOOST_CHECK(t2.type_info() != t1);
BOOST_TEST_NE(t2, t1);
BOOST_TEST(t2 != t1.type_info());
BOOST_TEST(t2.type_info() != t1);
BOOST_CHECK(t1 < t2 || t2 < t1);
BOOST_CHECK(t1 > t2 || t2 > t1);
BOOST_CHECK(t1.type_info() < t2 || t2.type_info() < t1);
BOOST_CHECK(t1.type_info() > t2 || t2.type_info() > t1);
BOOST_CHECK(t1 < t2.type_info() || t2 < t1.type_info());
BOOST_CHECK(t1 > t2.type_info() || t2 > t1.type_info());
BOOST_TEST(t1 < t2 || t2 < t1);
BOOST_TEST(t1 > t2 || t2 > t1);
BOOST_TEST(t1.type_info() < t2 || t2.type_info() < t1);
BOOST_TEST(t1.type_info() > t2 || t2.type_info() > t1);
BOOST_TEST(t1 < t2.type_info() || t2 < t1.type_info());
BOOST_TEST(t1 > t2.type_info() || t2 > t1.type_info());
// Chaecking that comparisom operators overloads compile
BOOST_CHECK(t1 <= t2 || t2 <= t1);
BOOST_CHECK(t1 >= t2 || t2 >= t1);
BOOST_CHECK(t1.type_info() <= t2 || t2.type_info() <= t1);
BOOST_CHECK(t1.type_info() >= t2 || t2.type_info() >= t1);
BOOST_CHECK(t1 <= t2.type_info() || t2 <= t1.type_info());
BOOST_CHECK(t1 >= t2.type_info() || t2 >= t1.type_info());
// Chaecking that comparison operators overloads compile
BOOST_TEST(t1 <= t2 || t2 <= t1);
BOOST_TEST(t1 >= t2 || t2 >= t1);
BOOST_TEST(t1.type_info() <= t2 || t2.type_info() <= t1);
BOOST_TEST(t1.type_info() >= t2 || t2.type_info() >= t1);
BOOST_TEST(t1 <= t2.type_info() || t2 <= t1.type_info());
BOOST_TEST(t1 >= t2.type_info() || t2 >= t1.type_info());
BOOST_CHECK_EQUAL(t1, type_id_with_cvr<T1>());
BOOST_CHECK_EQUAL(t2, type_id_with_cvr<T2>());
BOOST_CHECK(t1 == type_id_with_cvr<T1>().type_info());
BOOST_CHECK(t2 == type_id_with_cvr<T2>().type_info());
BOOST_CHECK(t1.type_info() == type_id_with_cvr<T1>());
BOOST_CHECK(t2.type_info() == type_id_with_cvr<T2>());
BOOST_TEST_EQ(t1, type_id_with_cvr<T1>());
BOOST_TEST_EQ(t2, type_id_with_cvr<T2>());
BOOST_TEST(t1 == type_id_with_cvr<T1>().type_info());
BOOST_TEST(t2 == type_id_with_cvr<T2>().type_info());
BOOST_TEST(t1.type_info() == type_id_with_cvr<T1>());
BOOST_TEST(t2.type_info() == type_id_with_cvr<T2>());
BOOST_CHECK_EQUAL(t1.hash_code(), type_id_with_cvr<T1>().hash_code());
BOOST_CHECK_EQUAL(t2.hash_code(), type_id_with_cvr<T2>().hash_code());
BOOST_TEST_EQ(t1.hash_code(), type_id_with_cvr<T1>().hash_code());
BOOST_TEST_EQ(t2.hash_code(), type_id_with_cvr<T2>().hash_code());
BOOST_CHECK_NE(t1.hash_code(), type_id_with_cvr<T2>().hash_code());
BOOST_CHECK_NE(t2.hash_code(), type_id_with_cvr<T1>().hash_code());
BOOST_TEST_NE(t1.hash_code(), type_id_with_cvr<T2>().hash_code());
BOOST_TEST_NE(t2.hash_code(), type_id_with_cvr<T1>().hash_code());
}
BOOST_AUTO_TEST_CASE(type_id_storing_modifiers)
void type_id_storing_modifiers()
{
test_with_modofiers<int, const int>();
test_with_modofiers<int, const int&>();
@ -182,88 +182,91 @@ BOOST_AUTO_TEST_CASE(type_id_storing_modifiers)
template <class T>
static void test_storing_nonstoring_modifiers_templ() {
using namespace boost::typeind;
using namespace boost::typeindex;
type_index t1 = type_id_with_cvr<T>();
type_index t2 = type_id<T>();
BOOST_CHECK_EQUAL(t2, t1);
BOOST_CHECK_EQUAL(t1, t2);
BOOST_CHECK(t1 <= t2);
BOOST_CHECK(t1 >= t2);
BOOST_CHECK(t2 <= t1);
BOOST_CHECK(t2 >= t1);
BOOST_TEST_EQ(t2, t1);
BOOST_TEST_EQ(t1, t2);
BOOST_TEST(t1 <= t2);
BOOST_TEST(t1 >= t2);
BOOST_TEST(t2 <= t1);
BOOST_TEST(t2 >= t1);
BOOST_CHECK_EQUAL(t2.pretty_name(), t1.pretty_name());
BOOST_TEST_EQ(t2.pretty_name(), t1.pretty_name());
}
BOOST_AUTO_TEST_CASE(type_id_storing_modifiers_vs_nonstoring)
void type_id_storing_modifiers_vs_nonstoring()
{
test_storing_nonstoring_modifiers_templ<int>();
test_storing_nonstoring_modifiers_templ<my_namespace1::my_class>();
test_storing_nonstoring_modifiers_templ<my_namespace2::my_class>();
boost::typeind::type_index t1 = boost::typeind::type_id_with_cvr<const int>();
boost::typeind::type_index t2 = boost::typeind::type_id<int>();
BOOST_CHECK_NE(t2, t1);
BOOST_CHECK(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
boost::typeindex::type_index t1 = boost::typeindex::type_id_with_cvr<const int>();
boost::typeindex::type_index t2 = boost::typeindex::type_id<int>();
BOOST_TEST_NE(t2, t1);
BOOST_TEST(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
}
BOOST_AUTO_TEST_CASE(type_index_stream_operator_via_lexical_cast_testing)
void type_index_stream_operator_via_lexical_cast_testing()
{
using namespace boost::typeind;
using namespace boost::typeindex;
std::string s_int2 = boost::lexical_cast<std::string>(type_id<int>());
BOOST_CHECK_EQUAL(s_int2, "int");
BOOST_TEST_EQ(s_int2, "int");
std::string s_double2 = boost::lexical_cast<std::string>(type_id<double>());
BOOST_CHECK_EQUAL(s_double2, "double");
BOOST_TEST_EQ(s_double2, "double");
}
BOOST_AUTO_TEST_CASE(type_index_stripping_cvr_test)
void type_index_stripping_cvr_test()
{
using namespace boost::typeind;
using namespace boost::typeindex;
BOOST_CHECK_EQUAL(type_id<int>(), type_id<const int>());
BOOST_CHECK_EQUAL(type_id<int>(), type_id<const volatile int>());
BOOST_CHECK_EQUAL(type_id<int>(), type_id<const volatile int&>());
BOOST_TEST_EQ(type_id<int>(), type_id<const int>());
BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int>());
BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int&>());
BOOST_CHECK_EQUAL(type_id<int>(), type_id<int&>());
BOOST_CHECK_EQUAL(type_id<int>(), type_id<volatile int>());
BOOST_CHECK_EQUAL(type_id<int>(), type_id<volatile int&>());
BOOST_TEST_EQ(type_id<int>(), type_id<int&>());
BOOST_TEST_EQ(type_id<int>(), type_id<volatile int>());
BOOST_TEST_EQ(type_id<int>(), type_id<volatile int&>());
BOOST_CHECK_EQUAL(type_id<double>(), type_id<const double>());
BOOST_CHECK_EQUAL(type_id<double>(), type_id<const volatile double>());
BOOST_CHECK_EQUAL(type_id<double>(), type_id<const volatile double&>());
BOOST_TEST_EQ(type_id<double>(), type_id<const double>());
BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double>());
BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double&>());
BOOST_CHECK_EQUAL(type_id<double>(), type_id<double&>());
BOOST_CHECK_EQUAL(type_id<double>(), type_id<volatile double>());
BOOST_CHECK_EQUAL(type_id<double>(), type_id<volatile double&>());
BOOST_TEST_EQ(type_id<double>(), type_id<double&>());
BOOST_TEST_EQ(type_id<double>(), type_id<volatile double>());
BOOST_TEST_EQ(type_id<double>(), type_id<volatile double&>());
}
BOOST_AUTO_TEST_CASE(type_index_user_defined_class_test)
void type_index_user_defined_class_test()
{
using namespace boost::typeind;
using namespace boost::typeindex;
BOOST_CHECK_EQUAL(type_id<my_namespace1::my_class>(), type_id<my_namespace1::my_class>());
BOOST_CHECK_EQUAL(type_id<my_namespace2::my_class>(), type_id<my_namespace2::my_class>());
BOOST_TEST_EQ(type_id<my_namespace1::my_class>(), type_id<my_namespace1::my_class>());
BOOST_TEST_EQ(type_id<my_namespace2::my_class>(), type_id<my_namespace2::my_class>());
#ifndef BOOST_NO_RTTI
BOOST_CHECK(type_id<my_namespace1::my_class>() == typeid(my_namespace1::my_class));
BOOST_CHECK(type_id<my_namespace2::my_class>() == typeid(my_namespace2::my_class));
BOOST_CHECK(typeid(my_namespace1::my_class) == type_id<my_namespace1::my_class>());
BOOST_CHECK(typeid(my_namespace2::my_class) == type_id<my_namespace2::my_class>());
BOOST_TEST(type_id<my_namespace1::my_class>() == typeid(my_namespace1::my_class));
BOOST_TEST(type_id<my_namespace2::my_class>() == typeid(my_namespace2::my_class));
BOOST_TEST(typeid(my_namespace1::my_class) == type_id<my_namespace1::my_class>());
BOOST_TEST(typeid(my_namespace2::my_class) == type_id<my_namespace2::my_class>());
#endif
BOOST_CHECK_NE(type_id<my_namespace1::my_class>(), type_id<my_namespace2::my_class>());
BOOST_CHECK_NE(
BOOST_TEST_NE(type_id<my_namespace1::my_class>(), type_id<my_namespace2::my_class>());
BOOST_TEST_NE(
type_id<my_namespace1::my_class>().pretty_name().find("my_namespace1::my_class"),
std::string::npos);
}
struct A {
public:
BOOST_TYPE_INDEX_REGISTER_CLASS
@ -278,7 +281,7 @@ struct C: public B {
BOOST_TYPE_INDEX_REGISTER_CLASS
};
BOOST_AUTO_TEST_CASE(comparators_type_id_runtime)
void comparators_type_id_runtime()
{
C c1;
B b1;
@ -288,90 +291,110 @@ BOOST_AUTO_TEST_CASE(comparators_type_id_runtime)
A& rb1 = b1;
#ifndef BOOST_NO_RTTI
BOOST_CHECK(typeid(rc1) == typeid(*pc1));
BOOST_CHECK(typeid(rb1) == typeid(*pb1));
BOOST_TEST(typeid(rc1) == typeid(*pc1));
BOOST_TEST(typeid(rb1) == typeid(*pb1));
BOOST_CHECK(typeid(rc1) != typeid(*pb1));
BOOST_CHECK(typeid(rb1) != typeid(*pc1));
BOOST_TEST(typeid(rc1) != typeid(*pb1));
BOOST_TEST(typeid(rb1) != typeid(*pc1));
BOOST_CHECK(typeid(&rc1) == typeid(pb1));
BOOST_CHECK(typeid(&rb1) == typeid(pc1));
BOOST_TEST(typeid(&rc1) == typeid(pb1));
BOOST_TEST(typeid(&rb1) == typeid(pc1));
#else
BOOST_CHECK(boost::typeind::type_index(pc1->type_id_runtime()).raw_name());
BOOST_TEST(boost::typeindex::type_index(pc1->boost_type_index_type_id_runtime_()).raw_name());
#endif
BOOST_CHECK_EQUAL(boost::typeind::type_id_runtime(rc1), boost::typeind::type_id_runtime(*pc1));
BOOST_CHECK_EQUAL(boost::typeind::type_id<C>(), boost::typeind::type_id_runtime(*pc1));
BOOST_CHECK_EQUAL(boost::typeind::type_id_runtime(rb1), boost::typeind::type_id_runtime(*pb1));
BOOST_CHECK_EQUAL(boost::typeind::type_id<B>(), boost::typeind::type_id_runtime(*pb1));
BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pc1));
BOOST_TEST_EQ(boost::typeindex::type_id<C>(), boost::typeindex::type_id_runtime(*pc1));
BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pb1));
BOOST_TEST_EQ(boost::typeindex::type_id<B>(), boost::typeindex::type_id_runtime(*pb1));
BOOST_CHECK_NE(boost::typeind::type_id_runtime(rc1), boost::typeind::type_id_runtime(*pb1));
BOOST_CHECK_NE(boost::typeind::type_id_runtime(rb1), boost::typeind::type_id_runtime(*pc1));
BOOST_TEST_NE(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pb1));
BOOST_TEST_NE(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pc1));
#ifndef BOOST_NO_RTTI
BOOST_CHECK_EQUAL(boost::typeind::type_id_runtime(&rc1), boost::typeind::type_id_runtime(pb1));
BOOST_CHECK_EQUAL(boost::typeind::type_id_runtime(&rb1), boost::typeind::type_id_runtime(pc1));
BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rc1), boost::typeindex::type_id_runtime(pb1));
BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rb1), boost::typeindex::type_id_runtime(pc1));
BOOST_CHECK(boost::typeind::type_id_runtime(rc1) == typeid(*pc1));
BOOST_CHECK(boost::typeind::type_id_runtime(rb1) == typeid(*pb1));
BOOST_TEST(boost::typeindex::type_id_runtime(rc1) == typeid(*pc1));
BOOST_TEST(boost::typeindex::type_id_runtime(rb1) == typeid(*pb1));
BOOST_CHECK(boost::typeind::type_id_runtime(rc1) != typeid(*pb1));
BOOST_CHECK(boost::typeind::type_id_runtime(rb1) != typeid(*pc1));
BOOST_CHECK(boost::typeind::type_id_runtime(&rc1) == typeid(pb1));
BOOST_CHECK(boost::typeind::type_id_runtime(&rb1) == typeid(pc1));
BOOST_TEST(boost::typeindex::type_id_runtime(rc1) != typeid(*pb1));
BOOST_TEST(boost::typeindex::type_id_runtime(rb1) != typeid(*pc1));
BOOST_TEST(boost::typeindex::type_id_runtime(&rc1) == typeid(pb1));
BOOST_TEST(boost::typeindex::type_id_runtime(&rb1) == typeid(pc1));
#endif
}
#ifndef BOOST_NO_RTTI
BOOST_AUTO_TEST_CASE(comparators_type_id_vs_type_info)
void comparators_type_id_vs_type_info()
{
using namespace boost::typeind;
using namespace boost::typeindex;
type_index t_int = type_id<int>();
BOOST_CHECK(t_int == typeid(int));
BOOST_CHECK(typeid(int) == t_int);
BOOST_CHECK(t_int <= typeid(int));
BOOST_CHECK(typeid(int) <= t_int);
BOOST_CHECK(t_int >= typeid(int));
BOOST_CHECK(typeid(int) >= t_int);
BOOST_TEST(t_int == typeid(int));
BOOST_TEST(typeid(int) == t_int);
BOOST_TEST(t_int <= typeid(int));
BOOST_TEST(typeid(int) <= t_int);
BOOST_TEST(t_int >= typeid(int));
BOOST_TEST(typeid(int) >= t_int);
type_index t_double = type_id<double>();
BOOST_CHECK(t_double == typeid(double));
BOOST_CHECK(typeid(double) == t_double);
BOOST_CHECK(t_double <= typeid(double));
BOOST_CHECK(typeid(double) <= t_double);
BOOST_CHECK(t_double >= typeid(double));
BOOST_CHECK(typeid(double) >= t_double);
BOOST_TEST(t_double == typeid(double));
BOOST_TEST(typeid(double) == t_double);
BOOST_TEST(t_double <= typeid(double));
BOOST_TEST(typeid(double) <= t_double);
BOOST_TEST(t_double >= typeid(double));
BOOST_TEST(typeid(double) >= t_double);
if (t_double < t_int) {
BOOST_CHECK(t_double < typeid(int));
BOOST_CHECK(typeid(double) < t_int);
BOOST_CHECK(typeid(int) > t_double);
BOOST_CHECK(t_int > typeid(double));
BOOST_TEST(t_double < typeid(int));
BOOST_TEST(typeid(double) < t_int);
BOOST_TEST(typeid(int) > t_double);
BOOST_TEST(t_int > typeid(double));
BOOST_CHECK(t_double <= typeid(int));
BOOST_CHECK(typeid(double) <= t_int);
BOOST_CHECK(typeid(int) >= t_double);
BOOST_CHECK(t_int >= typeid(double));
BOOST_TEST(t_double <= typeid(int));
BOOST_TEST(typeid(double) <= t_int);
BOOST_TEST(typeid(int) >= t_double);
BOOST_TEST(t_int >= typeid(double));
} else {
BOOST_CHECK(t_double > typeid(int));
BOOST_CHECK(typeid(double) > t_int);
BOOST_CHECK(typeid(int) < t_double);
BOOST_CHECK(t_int < typeid(double));
BOOST_TEST(t_double > typeid(int));
BOOST_TEST(typeid(double) > t_int);
BOOST_TEST(typeid(int) < t_double);
BOOST_TEST(t_int < typeid(double));
BOOST_CHECK(t_double >= typeid(int));
BOOST_CHECK(typeid(double) >= t_int);
BOOST_CHECK(typeid(int) <= t_double);
BOOST_CHECK(t_int <= typeid(double));
BOOST_TEST(t_double >= typeid(int));
BOOST_TEST(typeid(double) >= t_int);
BOOST_TEST(typeid(int) <= t_double);
BOOST_TEST(t_int <= typeid(double));
}
}
#endif // BOOST_NO_RTTI
int main() {
names_matches_type_id();
default_construction();
copy_construction();
comparators_type_id();
hash_code_type_id();
type_id_storing_modifiers();
type_id_storing_modifiers_vs_nonstoring();
type_index_stream_operator_via_lexical_cast_testing();
type_index_stripping_cvr_test();
type_index_user_defined_class_test();
comparators_type_id_runtime();
#ifndef BOOST_NO_RTTI
comparators_type_id_vs_type_info();
#endif
return boost::report_errors();
}

View File

@ -1,5 +1,5 @@
//
// Copyright Antony Polukhin, 2012-2013.
// Copyright 2012-2022 Antony Polukhin.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@ -10,8 +10,8 @@
int main() {
BOOST_STATIC_ASSERT_MSG(
boost::alignment_of<boost::typeind::detail::ctti_data>::value == boost::alignment_of<char>::value,
"Alignments of boost::typeind::detail::ctti_data and char differ. "
boost::alignment_of<boost::typeindex::detail::ctti_data>::value == boost::alignment_of<char>::value,
"Alignments of boost::typeindex::detail::ctti_data and char differ. "
"It is unsafe to reinterpret_cast between them."
);
}

View File

@ -1,5 +1,5 @@
//
// Copyright Antony Polukhin, 2012-2013.
// Copyright 2012-2022 Antony Polukhin.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@ -8,7 +8,7 @@
#include <boost/type_index/ctti_type_index.hpp>
int main() {
using namespace boost::typeind;
using namespace boost::typeindex;
ctti_type_index::type_info_t t;
(void)t;
}

View File

@ -1,5 +1,5 @@
//
// Copyright Antony Polukhin, 2012-2013.
// Copyright 2012-2022 Antony Polukhin.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@ -8,7 +8,7 @@
#include <boost/type_index/ctti_type_index.hpp>
int main() {
using namespace boost::typeind;
using namespace boost::typeindex;
ctti_type_index::type_info_t t = ctti_type_index::type_id<int>().type_info();
(void)t;
}