summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/type_index
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/type_index')
-rw-r--r--src/boost/libs/type_index/CMakeLists.txt26
-rw-r--r--src/boost/libs/type_index/README.md18
-rw-r--r--src/boost/libs/type_index/examples/constexpr14_namespace_check.cpp97
-rw-r--r--src/boost/libs/type_index/examples/constexpr14_sort_check.cpp76
-rw-r--r--src/boost/libs/type_index/examples/demangled_names.cpp76
-rw-r--r--src/boost/libs/type_index/examples/exact_types_match.cpp74
-rw-r--r--src/boost/libs/type_index/examples/inheritance.cpp47
-rw-r--r--src/boost/libs/type_index/examples/registry.cpp53
-rw-r--r--src/boost/libs/type_index/examples/runtime_cast.cpp90
-rw-r--r--src/boost/libs/type_index/examples/table_of_names.cpp90
-rw-r--r--src/boost/libs/type_index/examples/user_defined_typeinfo.cpp72
-rw-r--r--src/boost/libs/type_index/examples/user_defined_typeinfo.hpp213
-rw-r--r--src/boost/libs/type_index/index.html35
-rw-r--r--src/boost/libs/type_index/meta/libraries.json14
-rw-r--r--src/boost/libs/type_index/patched/README.md9
-rw-r--r--src/boost/libs/type_index/patched/boost_detail_sp_typeinfo.patch151
-rw-r--r--src/boost/libs/type_index/patched/boost_exception.patch156
-rw-r--r--src/boost/libs/type_index/patched/boost_smart_ptr.patch26
-rw-r--r--src/boost/libs/type_index/test/Jamfile.v281
-rw-r--r--src/boost/libs/type_index/test/compare_ctti_stl.cpp67
-rw-r--r--src/boost/libs/type_index/test/ctti_print_name.cpp44
-rw-r--r--src/boost/libs/type_index/test/test_lib.cpp40
-rw-r--r--src/boost/libs/type_index/test/test_lib.hpp42
-rw-r--r--src/boost/libs/type_index/test/test_lib_anonymous.cpp27
-rw-r--r--src/boost/libs/type_index/test/test_lib_anonymous.hpp34
-rw-r--r--src/boost/libs/type_index/test/testing_crossmodule.cpp57
-rw-r--r--src/boost/libs/type_index/test/testing_crossmodule_anonymous.cpp48
-rw-r--r--src/boost/libs/type_index/test/track_13621.cpp23
-rw-r--r--src/boost/libs/type_index/test/type_index_constexpr_test.cpp157
-rw-r--r--src/boost/libs/type_index/test/type_index_runtime_cast_test.cpp296
-rw-r--r--src/boost/libs/type_index/test/type_index_test.cpp400
-rw-r--r--src/boost/libs/type_index/test/type_index_test_ctti_alignment.cpp18
-rw-r--r--src/boost/libs/type_index/test/type_index_test_ctti_construct_fail.cpp15
-rw-r--r--src/boost/libs/type_index/test/type_index_test_ctti_copy_fail.cpp15
34 files changed, 2687 insertions, 0 deletions
diff --git a/src/boost/libs/type_index/CMakeLists.txt b/src/boost/libs/type_index/CMakeLists.txt
new file mode 100644
index 000000000..e37950ac9
--- /dev/null
+++ b/src/boost/libs/type_index/CMakeLists.txt
@@ -0,0 +1,26 @@
+# 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
+#
+# NOTE: CMake support for Boost.TypeIndex is currently experimental at best
+# and the interface is likely to change in the future
+
+cmake_minimum_required(VERSION 3.5)
+project(Boost.TypeIndex)
+
+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
+)
diff --git a/src/boost/libs/type_index/README.md b/src/boost/libs/type_index/README.md
new file mode 100644
index 000000000..19db50381
--- /dev/null
+++ b/src/boost/libs/type_index/README.md
@@ -0,0 +1,18 @@
+# [Boost.TypeIndex](http://boost.org/libs/type_index)
+Boost.TypeIndex is a part of the [Boost C++ Libraries](http://github.com/boostorg). It is a runtime/compile time copyable type info.
+
+### Test results
+
+@ | Build | Tests coverage | More info
+----------------|-------------- | -------------- |-----------
+Develop branch: | [![Build Status](https://travis-ci.org/apolukhin/type_index.svg?branch=develop)](https://travis-ci.org/apolukhin/type_index) [![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...](http://www.boost.org/development/tests/develop/developer/type_index.html)
+Master branch: | [![Build Status](https://travis-ci.org/apolukhin/type_index.svg?branch=master)](https://travis-ci.org/apolukhin/type_index) [![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...](http://www.boost.org/development/tests/master/developer/type_index.html)
+
+
+[Open Issues](https://svn.boost.org/trac/boost/query?status=!closed&component=type_index)
+
+[Latest developer documentation](http://boostorg.github.com/type_index/index.html)
+
+### License
+
+Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
diff --git a/src/boost/libs/type_index/examples/constexpr14_namespace_check.cpp b/src/boost/libs/type_index/examples/constexpr14_namespace_check.cpp
new file mode 100644
index 000000000..09fc4a6d5
--- /dev/null
+++ b/src/boost/libs/type_index/examples/constexpr14_namespace_check.cpp
@@ -0,0 +1,97 @@
+// Copyright 2013-2020 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>
+
+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
+
diff --git a/src/boost/libs/type_index/examples/constexpr14_sort_check.cpp b/src/boost/libs/type_index/examples/constexpr14_sort_check.cpp
new file mode 100644
index 000000000..c89b7e3bd
--- /dev/null
+++ b/src/boost/libs/type_index/examples/constexpr14_sort_check.cpp
@@ -0,0 +1,76 @@
+// Copyright 2013-2020 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
+
diff --git a/src/boost/libs/type_index/examples/demangled_names.cpp b/src/boost/libs/type_index/examples/demangled_names.cpp
new file mode 100644
index 000000000..c0589a91b
--- /dev/null
+++ b/src/boost/libs/type_index/examples/demangled_names.cpp
@@ -0,0 +1,76 @@
+// Copyright 2013-2020 Antony Polukhin
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See the accompanying file LICENSE_1_0.txt
+// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
+
+
+//[type_index_names_example
+/*`
+ The following example shows how short (mangled) and human readable type names could be obtained from a type.
+ Works with and without RTTI.
+*/
+
+
+#include <boost/type_index.hpp>
+#include <iostream>
+
+template <class T>
+void foo(T) {
+ std::cout << "\n Short name: " << boost::typeindex::type_id<T>().raw_name();
+ std::cout << "\n Readable name: " << boost::typeindex::type_id<T>().pretty_name();
+}
+
+struct user_defined_type{};
+
+namespace ns1 { namespace ns2 {
+ struct user_defined_type{};
+}} // namespace ns1::ns2
+
+namespace {
+ struct in_anon_type{};
+} // anonymous namespace
+
+int main() {
+ // Call to
+ foo(1);
+ // will output something like this:
+ //
+ // (RTTI on) (RTTI off)
+ // Short name: i Short name: int]
+ // Readable name: int Readable name: int
+
+ user_defined_type t;
+ foo(t);
+ // Will output:
+ //
+ // (RTTI on) (RTTI off)
+ // Short name: 17user_defined_type user_defined_type]
+ // Readable name: user_defined_type user_defined_type
+
+ ns1::ns2::user_defined_type t_in_ns;
+ foo(t_in_ns);
+ // Will output:
+ //
+ // (RTTI on) (RTTI off)
+ // Short name: N3ns13ns217user_defined_typeE ns1::ns2::user_defined_type]
+ // Readable name: ns1::ns2::user_defined_type ns1::ns2::user_defined_type
+
+ in_anon_type anon_t;
+ foo(anon_t);
+ // Will output:
+ //
+ // (RTTI on) (RTTI off)
+ // Short name: N12_GLOBAL__N_112in_anon_typeE {anonymous}::in_anon_type]
+ // Readable name: (anonymous namespace)::in_anon_type {anonymous}::in_anon_type
+}
+
+/*`
+ Short names are very compiler dependant: some compiler will output `.H`, others `i`.
+
+ Readable names may also differ between compilers: `struct user_defined_type`, `user_defined_type`.
+
+ [warning With RTTI off different classes with same names in anonymous namespace may collapse. See 'RTTI emulation limitations'. ]
+*/
+
+//] [/type_index_names_example]
diff --git a/src/boost/libs/type_index/examples/exact_types_match.cpp b/src/boost/libs/type_index/examples/exact_types_match.cpp
new file mode 100644
index 000000000..bf3a44b96
--- /dev/null
+++ b/src/boost/libs/type_index/examples/exact_types_match.cpp
@@ -0,0 +1,74 @@
+// Copyright 2013-2020 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_exact_type_match_example
+/*`
+ 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 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.
+#ifdef assert
+# undef assert
+#endif
+#define assert(X) if (!(X)) std::exit(__LINE__)
+ /* !Comment block is not closed intentionaly!
+//->
+#include <cassert>
+//<-
+ !Closing comment block! */
+//->
+
+class type_erased_unary_function {
+ void* function_ptr_;
+ boost::typeindex::type_index exact_param_t_;
+
+public:
+ template <class ParamT>
+ type_erased_unary_function(void(*ptr)(ParamT))
+ : function_ptr_(reinterpret_cast<void*>(ptr)) // ptr - is a pointer to function returning `void` and accepting parameter of type `ParamT`
+ , exact_param_t_(boost::typeindex::type_id_with_cvr<ParamT>())
+ {}
+
+ template <class ParamT>
+ void call(ParamT v) {
+ if (exact_param_t_ != boost::typeindex::type_id_with_cvr<ParamT>()) {
+ throw std::runtime_error("Incorrect `ParamT`");
+ }
+
+ return (reinterpret_cast<void(*)(ParamT)>(function_ptr_))(v);
+ }
+};
+
+void foo(int){}
+
+int main() {
+ type_erased_unary_function func(&foo);
+ func.call(100); // OK, `100` has type `int`
+
+ try {
+ 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` mismatch
+
+ assert(false);
+ } catch (const std::runtime_error& /*e*/) {}
+}
+
+//] [/type_index_exact_type_match_example]
diff --git a/src/boost/libs/type_index/examples/inheritance.cpp b/src/boost/libs/type_index/examples/inheritance.cpp
new file mode 100644
index 000000000..199937895
--- /dev/null
+++ b/src/boost/libs/type_index/examples/inheritance.cpp
@@ -0,0 +1,47 @@
+// Copyright 2013-2020 Antony Polukhin
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See the accompanying file LICENSE_1_0.txt
+// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
+
+//[type_index_derived_example
+/*`
+ The following example shows that `type_info` is able to store the real type, successfully getting through
+ all the inheritances.
+
+ Example works with and without RTTI."
+*/
+
+#include <boost/type_index.hpp>
+#include <boost/type_index/runtime_cast/register_runtime_class.hpp>
+#include <iostream>
+
+struct A {
+ BOOST_TYPE_INDEX_REGISTER_CLASS
+ virtual ~A(){}
+};
+struct B: public A { BOOST_TYPE_INDEX_REGISTER_CLASS };
+struct C: public B { BOOST_TYPE_INDEX_REGISTER_CLASS };
+struct D: public C { BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS) };
+
+void print_real_type(const A& a) {
+ std::cout << boost::typeindex::type_id_runtime(a).pretty_name() << '\n';
+}
+
+int main() {
+ C c;
+ const A& c_as_a = c;
+ print_real_type(c_as_a); // Outputs `struct C`
+ print_real_type(B()); // Outputs `struct B`
+
+/*`
+ It's also possible to use type_id_runtime with the BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS, which adds additional
+ information for runtime_cast to work.
+*/
+ D d;
+ const A& d_as_a = d;
+ print_real_type(d_as_a); // Outputs `struct D`
+
+}
+
+//] [/type_index_derived_example]
diff --git a/src/boost/libs/type_index/examples/registry.cpp b/src/boost/libs/type_index/examples/registry.cpp
new file mode 100644
index 000000000..28f216825
--- /dev/null
+++ b/src/boost/libs/type_index/examples/registry.cpp
@@ -0,0 +1,53 @@
+// Copyright 2013-2020 Antony Polukhin
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See the accompanying file LICENSE_1_0.txt
+// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
+
+//[type_index_registry_example
+/*`
+ The following example shows how an information about a type could be stored.
+ Example works with and without RTTI.
+*/
+
+#include <boost/type_index.hpp>
+#include <boost/unordered/unordered_set.hpp>
+//<-
+// Making `#include <cassert>` visible in docs, while actually using `BOOST_TEST`
+// instead of `assert`. This is required to verify correct behavior even if NDEBUG
+// is defined and to avoid `unused local variable` warnings with defined NDEBUG.
+#include <boost/core/lightweight_test.hpp>
+#ifdef assert
+# undef assert
+#endif
+#define assert(X) BOOST_TEST(X)
+ /* !Comment block is not closed intentionaly!
+//->
+#include <cassert>
+//<-
+ !Closing comment block! */
+//->
+
+int main() {
+ boost::unordered_set<boost::typeindex::type_index> types;
+
+ // Storing some `boost::type_info`s
+ types.insert(boost::typeindex::type_id<int>());
+ types.insert(boost::typeindex::type_id<float>());
+
+ // `types` variable contains two `boost::type_index`es:
+ assert(types.size() == 2);
+
+ // Const, volatile and reference will be striped from the type:
+ bool is_inserted = types.insert(boost::typeindex::type_id<const int>()).second;
+ assert(!is_inserted);
+ assert(types.erase(boost::typeindex::type_id<float&>()) == 1);
+
+ // We have erased the `float` type, only `int` remains
+ assert(*types.begin() == boost::typeindex::type_id<int>());
+//<-
+ return boost::report_errors();
+//->
+}
+
+//] [/type_index_registry_example]
diff --git a/src/boost/libs/type_index/examples/runtime_cast.cpp b/src/boost/libs/type_index/examples/runtime_cast.cpp
new file mode 100644
index 000000000..43e7aa70f
--- /dev/null
+++ b/src/boost/libs/type_index/examples/runtime_cast.cpp
@@ -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]
diff --git a/src/boost/libs/type_index/examples/table_of_names.cpp b/src/boost/libs/type_index/examples/table_of_names.cpp
new file mode 100644
index 000000000..d51487d78
--- /dev/null
+++ b/src/boost/libs/type_index/examples/table_of_names.cpp
@@ -0,0 +1,90 @@
+// Copyright 2013-2020 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]
diff --git a/src/boost/libs/type_index/examples/user_defined_typeinfo.cpp b/src/boost/libs/type_index/examples/user_defined_typeinfo.cpp
new file mode 100644
index 000000000..ba6e01e22
--- /dev/null
+++ b/src/boost/libs/type_index/examples/user_defined_typeinfo.cpp
@@ -0,0 +1,72 @@
+// Copyright 2013-2020 Antony Polukhin
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See the accompanying file LICENSE_1_0.txt
+// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
+
+
+//[type_index_my_type_index_worldwide_macro
+/*`
+ There is an easy way to force `boost::typeindex::type_id` to use your own type_index class.
+
+ All we need to do is just define `BOOST_TYPE_INDEX_USER_TYPEINDEX` to the full path to header file
+ of your type index class:
+*/
+
+// BOOST_TYPE_INDEX_USER_TYPEINDEX must be defined *BEFORE* first inclusion of <boost/type_index.hpp>
+#define BOOST_TYPE_INDEX_USER_TYPEINDEX <boost/../libs/type_index/examples/user_defined_typeinfo.hpp>
+#include <boost/type_index.hpp>
+//] [/type_index_my_type_index_worldwide_macro]
+
+#include <boost/core/lightweight_test.hpp>
+#ifdef assert
+# undef assert
+#endif
+#define assert(X) BOOST_TEST(X)
+
+
+using namespace my_namespace;
+
+int main() {
+//[type_index_my_type_index_usage
+/*`
+ Finally we can use the my_type_index class for getting type indexes:
+*/
+
+ my_type_index
+ cl1 = my_type_index::type_id<my_class>(),
+ st1 = my_type_index::type_id<my_struct>(),
+ st2 = my_type_index::type_id<my_struct>(),
+ vec = my_type_index::type_id<my_classes>()
+ ;
+
+ assert(cl1 != st1);
+ assert(st2 == st1);
+ assert(vec.pretty_name() == "my_classes");
+ assert(cl1.pretty_name() == "my_class");
+
+//] [/type_index_my_type_index_usage]
+
+//[type_index_my_type_index_type_id_runtime_test
+/*`
+ Now the following example will compile and work.
+*/
+ my_struct str;
+ my_class& reference = str;
+ assert(my_type_index::type_id<my_struct>() == my_type_index::type_id_runtime(reference));
+//][/type_index_my_type_index_type_id_runtime_test]
+
+//[type_index_my_type_index_worldwide_usage
+/*`
+ That's it! Now all TypeIndex global methods and typedefs will be using your class:
+*/
+ boost::typeindex::type_index worldwide = boost::typeindex::type_id<my_classes>();
+ assert(worldwide.pretty_name() == "my_classes");
+ assert(worldwide == my_type_index::type_id<my_classes>());
+//][/type_index_my_type_index_worldwide_usage]
+//<-
+ return boost::report_errors();
+//->
+}
+
+
diff --git a/src/boost/libs/type_index/examples/user_defined_typeinfo.hpp b/src/boost/libs/type_index/examples/user_defined_typeinfo.hpp
new file mode 100644
index 000000000..1bc020e82
--- /dev/null
+++ b/src/boost/libs/type_index/examples/user_defined_typeinfo.hpp
@@ -0,0 +1,213 @@
+// Copyright 2013-2020 Antony Polukhin
+
+// Distributed under the Boost Software License, Version 1.0.
+// (See the accompanying file LICENSE_1_0.txt
+// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
+
+#ifndef USER_DEFINED_TYPEINFO_HPP
+#define USER_DEFINED_TYPEINFO_HPP
+
+//[type_index_userdefined_usertypes
+/*`
+ The following example shows how a user defined type_info can be created and used.
+ Example works with and without RTTI.
+
+ Consider situation when user uses only those types in `typeid()`:
+*/
+
+#include <vector>
+#include <string>
+
+namespace my_namespace {
+
+class my_class;
+struct my_struct;
+
+typedef std::vector<my_class> my_classes;
+typedef std::string my_string;
+
+} // namespace my_namespace
+
+//] [/type_index_userdefined_usertypes]
+
+
+//[type_index_userdefined_enum
+/*`
+ In that case user may wish to save space in binary and create it's own type system.
+ For that case `detail::typenum<>` meta function is added. Depending on the input type T
+ this function will return different numeric values.
+*/
+#include <boost/type_index/type_index_facade.hpp>
+
+namespace my_namespace { namespace detail {
+ template <class T> struct typenum;
+ template <> struct typenum<void>{ enum {value = 0}; };
+ template <> struct typenum<my_class>{ enum {value = 1}; };
+ template <> struct typenum<my_struct>{ enum {value = 2}; };
+ template <> struct typenum<my_classes>{ enum {value = 3}; };
+ template <> struct typenum<my_string>{ enum {value = 4}; };
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4510 4512 4610) // non-copyable non-constructable type
+#endif
+
+ // my_typeinfo structure is used to save type number
+ struct my_typeinfo {
+ const char* const type_;
+ };
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+ const my_typeinfo infos[5] = {
+ {"void"}, {"my_class"}, {"my_struct"}, {"my_classes"}, {"my_string"}
+ };
+
+ template <class T>
+ inline const my_typeinfo& my_typeinfo_construct() {
+ return infos[typenum<T>::value];
+ }
+}} // my_namespace::detail
+
+//] [/type_index_userdefined_usertypes]
+
+
+//[type_index_my_type_index
+/*`
+ `my_type_index` is a user created type_index class. If in doubt during this phase, you can always
+ take a look at the `<boost/type_index/ctti_type_index.hpp>` or `<boost/type_index/stl_type_index.hpp>`
+ files. Documentation for `type_index_facade` could be also useful.
+*/
+
+/*`
+ Since we are not going to override `type_index_facade::hash_code()` we must additionally include
+ `<boost/container_hash/hash.hpp>`.
+*/
+#include <boost/container_hash/hash.hpp>
+
+/*`
+ See implementation of `my_type_index`:
+*/
+namespace my_namespace {
+
+class my_type_index: public boost::typeindex::type_index_facade<my_type_index, detail::my_typeinfo> {
+ const detail::my_typeinfo* data_;
+
+public:
+ typedef detail::my_typeinfo type_info_t;
+
+ inline my_type_index() BOOST_NOEXCEPT
+ : data_(&detail::my_typeinfo_construct<void>())
+ {}
+
+ inline my_type_index(const type_info_t& data) BOOST_NOEXCEPT
+ : data_(&data)
+ {}
+
+ inline const type_info_t& type_info() const BOOST_NOEXCEPT {
+ return *data_;
+ }
+
+ inline const char* raw_name() const BOOST_NOEXCEPT {
+ return data_->type_;
+ }
+
+ inline std::string pretty_name() const {
+ return data_->type_;
+ }
+
+ template <class T>
+ inline static my_type_index type_id() BOOST_NOEXCEPT {
+ return detail::my_typeinfo_construct<T>();
+ }
+
+ template <class T>
+ inline static my_type_index type_id_with_cvr() BOOST_NOEXCEPT {
+ return detail::my_typeinfo_construct<T>();
+ }
+
+ template <class T>
+ inline static my_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
+};
+
+} // namespace my_namespace
+
+/*`
+ Note that we have used the boost::typeindex::type_index_facade class as base.
+ That class took care about all the helper function and operators (comparison, hashing, ostreaming and others).
+*/
+
+//] [/type_index_my_type_index]
+
+//[type_index_my_type_index_register_class
+/*`
+ Usually to allow runtime type info we need to register class with some macro.
+ Let's see how a `MY_TYPEINDEX_REGISTER_CLASS` macro could be implemented for our `my_type_index` class:
+*/
+namespace my_namespace { namespace detail {
+
+ template <class T>
+ inline const my_typeinfo& my_typeinfo_construct_ref(const T*) {
+ return my_typeinfo_construct<T>();
+ }
+
+#define MY_TYPEINDEX_REGISTER_CLASS \
+ virtual const my_namespace::detail::my_typeinfo& type_id_runtime() const { \
+ return my_namespace::detail::my_typeinfo_construct_ref(this); \
+ }
+
+}} // namespace my_namespace::detail
+
+//] [/type_index_my_type_index_register_class]
+
+//[type_index_my_type_index_type_id_runtime_implmentation
+/*`
+ Now when we have a MY_TYPEINDEX_REGISTER_CLASS, let's implement a `my_type_index::type_id_runtime` method:
+*/
+namespace my_namespace {
+ template <class T>
+ my_type_index my_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
+ // Classes that were marked with `MY_TYPEINDEX_REGISTER_CLASS` will have a
+ // `type_id_runtime()` method.
+ return variable.type_id_runtime();
+ }
+}
+//] [/type_index_my_type_index_type_id_runtime_implmentation]
+
+//[type_index_my_type_index_type_id_runtime_classes
+/*`
+ Consider the situation, when `my_class` and `my_struct` are polymorphic classes:
+*/
+
+namespace my_namespace {
+
+class my_class {
+public:
+ MY_TYPEINDEX_REGISTER_CLASS
+ virtual ~my_class() {}
+};
+
+struct my_struct: public my_class {
+ MY_TYPEINDEX_REGISTER_CLASS
+};
+
+} // namespace my_namespace
+
+//] [/type_index_my_type_index_type_id_runtime_classes]
+
+
+//[type_index_my_type_index_worldwide_typedefs
+/*`
+ You'll also need to add some typedefs and macro to your "user_defined_typeinfo.hpp" header file:
+*/
+#define BOOST_TYPE_INDEX_REGISTER_CLASS MY_TYPEINDEX_REGISTER_CLASS
+namespace boost { namespace typeindex {
+ typedef my_namespace::my_type_index type_index;
+}}
+//] [/type_index_my_type_index_worldwide_typedefs]
+
+
+#endif // USER_DEFINED_TYPEINFO_HPP
+
diff --git a/src/boost/libs/type_index/index.html b/src/boost/libs/type_index/index.html
new file mode 100644
index 000000000..845e62cc4
--- /dev/null
+++ b/src/boost/libs/type_index/index.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ Copyright 2014 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=../../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="../../doc/html/boost_typeindex.html">../../doc/html/boost_typeindex.html</a>
+ </p>
+ <p>
+ &copy; 2014 Antony Polukhin
+ </p>
+</body>
+</html>
diff --git a/src/boost/libs/type_index/meta/libraries.json b/src/boost/libs/type_index/meta/libraries.json
new file mode 100644
index 000000000..5fff00aaf
--- /dev/null
+++ b/src/boost/libs/type_index/meta/libraries.json
@@ -0,0 +1,14 @@
+{
+ "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"
+ ]
+}
diff --git a/src/boost/libs/type_index/patched/README.md b/src/boost/libs/type_index/patched/README.md
new file mode 100644
index 000000000..4dab0d690
--- /dev/null
+++ b/src/boost/libs/type_index/patched/README.md
@@ -0,0 +1,9 @@
+patches for Boost libraries to work without RTTI
+==========
+
+Here are the patches that are TESTED and work well with RTTI disabled and enabled.
+Patches add tests for some of the libraries to make sure that library compile and work without RTTI.
+
+Patches remove duplicate code, improve output, allow compilation with RTTI off...
+
+Libraries Boost.Graph, Boost.XPressive, Boost.PropertyMap and others may also benefit from TypeIndex library.
diff --git a/src/boost/libs/type_index/patched/boost_detail_sp_typeinfo.patch b/src/boost/libs/type_index/patched/boost_detail_sp_typeinfo.patch
new file mode 100644
index 000000000..b0649e0d3
--- /dev/null
+++ b/src/boost/libs/type_index/patched/boost_detail_sp_typeinfo.patch
@@ -0,0 +1,151 @@
+From b77c0af6af8bc4797defc3627878acc3cf7a6f39 Mon Sep 17 00:00:00 2001
+From: Antony Polukhin <antoshkka@gmail.com>
+Date: Thu, 20 Feb 2014 17:57:24 +0400
+Subject: [PATCH] detail/sp_typeinfo.hpp now uses TypeIndex
+
+---
+ include/boost/detail/sp_typeinfo.hpp | 123 +++--------------------------------
+ 1 file changed, 8 insertions(+), 115 deletions(-)
+
+diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp
+index 43fae78..fbdf86d 100644
+--- a/include/boost/detail/sp_typeinfo.hpp
++++ b/include/boost/detail/sp_typeinfo.hpp
+@@ -10,126 +10,19 @@
+ // detail/sp_typeinfo.hpp
+ //
+ // Copyright 2007 Peter Dimov
++// Copyright 2014 Antony Polukhin
+ //
+ // Distributed under the Boost Software License, Version 1.0.
+ // See accompanying file LICENSE_1_0.txt or copy at
+ // http://www.boost.org/LICENSE_1_0.txt)
+
+-#include <boost/config.hpp>
++#include <boost/type_index.hpp>
++namespace boost { namespace detail {
++
++typedef boost::typeind::type_info sp_typeinfo;
++
++}} // namespace boost::detail
+
+-#if defined( BOOST_NO_TYPEID )
+-
+-#include <boost/current_function.hpp>
+-#include <functional>
+-
+-namespace boost
+-{
+-
+-namespace detail
+-{
+-
+-class sp_typeinfo
+-{
+-private:
+-
+- sp_typeinfo( sp_typeinfo const& );
+- sp_typeinfo& operator=( sp_typeinfo const& );
+-
+- char const * name_;
+-
+-public:
+-
+- explicit sp_typeinfo( char const * name ): name_( name )
+- {
+- }
+-
+- bool operator==( sp_typeinfo const& rhs ) const
+- {
+- return this == &rhs;
+- }
+-
+- bool operator!=( sp_typeinfo const& rhs ) const
+- {
+- return this != &rhs;
+- }
+-
+- bool before( sp_typeinfo const& rhs ) const
+- {
+- return std::less< sp_typeinfo const* >()( this, &rhs );
+- }
+-
+- char const* name() const
+- {
+- return name_;
+- }
+-};
+-
+-template<class T> struct sp_typeid_
+-{
+- static sp_typeinfo ti_;
+-
+- static char const * name()
+- {
+- return BOOST_CURRENT_FUNCTION;
+- }
+-};
+-
+-#if defined(__SUNPRO_CC)
+-// see #4199, the Sun Studio compiler gets confused about static initialization
+-// constructor arguments. But an assignment works just fine.
+-template<class T> sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name();
+-#else
+-template<class T> sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name());
+-#endif
+-
+-template<class T> struct sp_typeid_< T & >: sp_typeid_< T >
+-{
+-};
+-
+-template<class T> struct sp_typeid_< T const >: sp_typeid_< T >
+-{
+-};
+-
+-template<class T> struct sp_typeid_< T volatile >: sp_typeid_< T >
+-{
+-};
+-
+-template<class T> struct sp_typeid_< T const volatile >: sp_typeid_< T >
+-{
+-};
+-
+-} // namespace detail
+-
+-} // namespace boost
+-
+-#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_<T>::ti_)
+-
+-#else
+-
+-#include <typeinfo>
+-
+-namespace boost
+-{
+-
+-namespace detail
+-{
+-
+-#if defined( BOOST_NO_STD_TYPEINFO )
+-
+-typedef ::type_info sp_typeinfo;
+-
+-#else
+-
+-typedef std::type_info sp_typeinfo;
+-
+-#endif
+-
+-} // namespace detail
+-
+-} // namespace boost
+-
+-#define BOOST_SP_TYPEID(T) typeid(T)
+-
+-#endif
++#define BOOST_SP_TYPEID(T) (boost::typeind::type_id<T>().type_info())
+
+ #endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
+--
+1.8.5.3
+
diff --git a/src/boost/libs/type_index/patched/boost_exception.patch b/src/boost/libs/type_index/patched/boost_exception.patch
new file mode 100644
index 000000000..9b3643e05
--- /dev/null
+++ b/src/boost/libs/type_index/patched/boost_exception.patch
@@ -0,0 +1,156 @@
+From 8f57d59bfbc978673a2493a90b4f3e7e54ddbf18 Mon Sep 17 00:00:00 2001
+From: Antony Polukhin <antoshkka@gmail.com>
+Date: Thu, 20 Feb 2014 18:30:11 +0400
+Subject: [PATCH] Boost.Exception now uses TypeIndex to reduce duplicate code
+ and simplify name demanglings
+
+---
+ include/boost/exception/detail/type_info.hpp | 43 +++-------------------
+ include/boost/exception/diagnostic_information.hpp | 2 +-
+ include/boost/exception/exception.hpp | 3 +-
+ include/boost/exception/info.hpp | 2 +-
+ test/Jamfile.v2 | 2 +
+ 5 files changed, 12 insertions(+), 40 deletions(-)
+
+diff --git a/include/boost/exception/detail/type_info.hpp b/include/boost/exception/detail/type_info.hpp
+index 6e5942d..a247b71 100644
+--- a/include/boost/exception/detail/type_info.hpp
++++ b/include/boost/exception/detail/type_info.hpp
+@@ -12,13 +12,7 @@
+ #pragma warning(push,1)
+ #endif
+
+-#include <boost/detail/sp_typeinfo.hpp>
+-#include <boost/current_function.hpp>
+-#include <boost/config.hpp>
+-//#ifndef BOOST_NO_TYPEID
+-//#include <boost/units/detail/utility.hpp>
+-//#endif
+-#include <string>
++#include <boost/type_index.hpp>
+
+ namespace
+ boost
+@@ -28,11 +22,7 @@ boost
+ std::string
+ tag_type_name()
+ {
+-#ifdef BOOST_NO_TYPEID
+- return BOOST_CURRENT_FUNCTION;
+-#else
+- return /*units::detail::demangle*/(typeid(T*).name());
+-#endif
++ return boost::typeind::type_id<T*>().pretty_name();
+ }
+
+ template <class T>
+@@ -40,41 +30,20 @@ boost
+ std::string
+ type_name()
+ {
+-#ifdef BOOST_NO_TYPEID
+- return BOOST_CURRENT_FUNCTION;
+-#else
+- return /*units::detail::demangle*/(typeid(T).name());
+-#endif
++ return boost::typeind::type_id<T>().pretty_name();
+ }
+
+ namespace
+ exception_detail
+ {
+- struct
+- type_info_
+- {
+- detail::sp_typeinfo const * type_;
+-
+- explicit
+- type_info_( detail::sp_typeinfo const & type ):
+- type_(&type)
+- {
+- }
+-
+- friend
+- bool
+- operator<( type_info_ const & a, type_info_ const & b )
+- {
+- return 0!=(a.type_->before(*b.type_));
+- }
+- };
++ typedef boost::typeind::type_index type_info_;
+ }
+ }
+
+-#define BOOST_EXCEPTION_STATIC_TYPEID(T) ::boost::exception_detail::type_info_(BOOST_SP_TYPEID(T))
++#define BOOST_EXCEPTION_STATIC_TYPEID(T) ::boost::typeind::type_id<T>()
+
+ #ifndef BOOST_NO_RTTI
+-#define BOOST_EXCEPTION_DYNAMIC_TYPEID(x) ::boost::exception_detail::type_info_(typeid(x))
++#define BOOST_EXCEPTION_DYNAMIC_TYPEID(x) ::boost::typeind::type_id_runtime(x)
+ #endif
+
+ #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
+diff --git a/include/boost/exception/diagnostic_information.hpp b/include/boost/exception/diagnostic_information.hpp
+index 2f5cb88..0f8b5e8 100644
+--- a/include/boost/exception/diagnostic_information.hpp
++++ b/include/boost/exception/diagnostic_information.hpp
+@@ -151,7 +151,7 @@ boost
+ #ifndef BOOST_NO_RTTI
+ if ( verbose )
+ tmp << std::string("Dynamic exception type: ") <<
+- /*units::detail::demangle*/((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n';
++ /*units::detail::demangle*/((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se)))) << '\n';
+ #endif
+ if( with_what && se && verbose )
+ tmp << "std::exception::what: " << wh << '\n';
+diff --git a/include/boost/exception/exception.hpp b/include/boost/exception/exception.hpp
+index 9f20a04..53c341f 100644
+--- a/include/boost/exception/exception.hpp
++++ b/include/boost/exception/exception.hpp
+@@ -12,6 +12,8 @@
+ #pragma warning(push,1)
+ #endif
+
++#include <boost/exception/detail/type_info.hpp>
++
+ namespace
+ boost
+ {
+@@ -151,7 +153,6 @@ boost
+ exception_detail
+ {
+ class error_info_base;
+- struct type_info_;
+
+ struct
+ error_info_container
+diff --git a/include/boost/exception/info.hpp b/include/boost/exception/info.hpp
+index edbf058..e0f4950 100644
+--- a/include/boost/exception/info.hpp
++++ b/include/boost/exception/info.hpp
+@@ -96,7 +96,7 @@ boost
+ {
+ shared_ptr<error_info_base> const & p = i->second;
+ #ifndef BOOST_NO_RTTI
+- BOOST_ASSERT( *BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==*ti.type_ );
++ BOOST_ASSERT(BOOST_EXCEPTION_DYNAMIC_TYPEID(*p)==ti );
+ #endif
+ return p;
+ }
+diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
+index d2dfcd6..5bd076d 100644
+--- a/test/Jamfile.v2
++++ b/test/Jamfile.v2
+@@ -35,7 +35,9 @@ run enable_error_info_test.cpp helper1.cpp ;
+ run throw_exception_test.cpp helper2.cpp ;
+ run errno_test.cpp ;
+ run error_info_test.cpp ;
++run error_info_test.cpp : : : <rtti>off : error_info_test_rtti ;
+ run diagnostic_information_test.cpp ;
++run diagnostic_information_test.cpp : : : <rtti>off : diagnostic_information_test_rtti ;
+ run refcount_ptr_test.cpp ;
+ run current_exception_cast_test.cpp ;
+ run no_exceptions_test.cpp : : : <exception-handling>off ;
+--
+1.8.5.3
+
diff --git a/src/boost/libs/type_index/patched/boost_smart_ptr.patch b/src/boost/libs/type_index/patched/boost_smart_ptr.patch
new file mode 100644
index 000000000..5120199ce
--- /dev/null
+++ b/src/boost/libs/type_index/patched/boost_smart_ptr.patch
@@ -0,0 +1,26 @@
+From 03194eefcb9c3314054855d28bd9a90d3188768d Mon Sep 17 00:00:00 2001
+From: Antony Polukhin <antoshkka@gmail.com>
+Date: Thu, 20 Feb 2014 18:50:10 +0400
+Subject: [PATCH] Use TypeIndex features in Boost.SharedPtr to avoid type_info
+ related bugs
+
+---
+ include/boost/smart_ptr/detail/sp_counted_impl.hpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/boost/smart_ptr/detail/sp_counted_impl.hpp b/include/boost/smart_ptr/detail/sp_counted_impl.hpp
+index a7b43ae..5955036 100644
+--- a/include/boost/smart_ptr/detail/sp_counted_impl.hpp
++++ b/include/boost/smart_ptr/detail/sp_counted_impl.hpp
+@@ -155,7 +155,7 @@ public:
+
+ virtual void * get_deleter( detail::sp_typeinfo const & ti )
+ {
+- return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
++ return ti == boost::typeind::type_id<D>()? &reinterpret_cast<char&>( del ): 0;
+ }
+
+ virtual void * get_untyped_deleter()
+--
+1.8.5.3
+
diff --git a/src/boost/libs/type_index/test/Jamfile.v2 b/src/boost/libs/type_index/test/Jamfile.v2
new file mode 100644
index 000000000..22779cbce
--- /dev/null
+++ b/src/boost/libs/type_index/test/Jamfile.v2
@@ -0,0 +1,81 @@
+# Copyright 2012-2020 Antony Polukhin
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import testing ;
+import feature ;
+import os ;
+
+# Variable that contains all the stuff required for linking together <rtti>on and <rtti>off
+compat = <define>BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY ;
+
+# Making own `nortti` that is link compatible.
+# We explicitly define BOOST_NO_RTTI because it sometimes can not be detected by build system.
+nortti = <toolset>gcc:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>clang:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>intel:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>darwin:<cxxflags>"-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>msvc:<cxxflags>"/GR-" ;
+
+norttidefines = <toolset>gcc:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>clang:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>intel:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>darwin:<cxxflags>"-DBOOST_NO_RTTI -DBOOST_NO_TYPEID" <toolset>msvc:<cxxflags>"-DBOOST_NO_RTTI" ;
+
+
+# Making libraries that CANNOT work between rtti-on/rtti-off modules
+obj test_lib_nortti-obj : test_lib.cpp : <link>shared <rtti>off $(norttidefines) ;
+obj test_lib_anonymous_nortti-obj : test_lib_anonymous.cpp : <link>shared <rtti>off $(norttidefines) ;
+lib test_lib_nortti : test_lib_nortti-obj : <link>shared <rtti>off $(norttidefines) ;
+lib test_lib_anonymous_nortti : test_lib_anonymous_nortti-obj : <link>shared <rtti>off $(norttidefines) ;
+
+obj test_lib_rtti-obj : test_lib.cpp : <link>shared ;
+obj test_lib_anonymous_rtti-obj : test_lib_anonymous.cpp : <link>shared ;
+lib test_lib_rtti : test_lib_rtti-obj : <link>shared ;
+lib test_lib_anonymous_rtti : test_lib_anonymous_rtti-obj : <link>shared ;
+
+# Making libraries that can work between rtti-on/rtti-off modules
+obj test_lib_nortti_compat-obj : test_lib.cpp : <link>shared $(nortti) $(compat) ;
+obj test_lib_rtti_compat-obj : test_lib.cpp : <link>shared $(nortti) $(compat) ;
+lib test_lib_nortti_compat : test_lib_nortti_compat-obj : <link>shared $(nortti) $(compat) ;
+lib test_lib_rtti_compat : test_lib_rtti_compat-obj : <link>shared $(nortti) $(compat) ;
+
+exe testing_crossmodule_anonymous_no_rtti : testing_crossmodule_anonymous.cpp test_lib_anonymous_nortti : <rtti>off $(norttidefines) ;
+
+test-suite type_index
+ :
+ [ run type_index_test.cpp ]
+ [ run type_index_runtime_cast_test.cpp ]
+ [ run type_index_constexpr_test.cpp ]
+ [ run type_index_test.cpp : : : <rtti>off $(norttidefines) : type_index_test_no_rtti ]
+ [ run ctti_print_name.cpp : : : <test-info>always_show_run_output ]
+ [ run testing_crossmodule.cpp test_lib_rtti ]
+ [ run testing_crossmodule.cpp test_lib_nortti : : : <rtti>off $(norttidefines) : testing_crossmodule_no_rtti ]
+ [ run testing_crossmodule_anonymous.cpp test_lib_anonymous_rtti : : : <test-info>always_show_run_output ]
+ [ run compare_ctti_stl.cpp ]
+ [ run track_13621.cpp ]
+
+ [ compile-fail type_index_test_ctti_copy_fail.cpp ]
+ [ compile-fail type_index_test_ctti_construct_fail.cpp ]
+ [ compile type_index_test_ctti_alignment.cpp ]
+
+ # Mixing RTTI on and off
+
+ # MSVC sometimes overrides the /GR-, without `detect_missmatch` this test may link.
+ # TODO: Disabled on MSVC. Enable again when there'll be an understanding of how to write this test correctly wor MSVC.
+ [ link-fail testing_crossmodule.cpp test_lib_rtti : $(nortti) <toolset>msvc:<build>no : link_fail_nortti_rtti ]
+ [ link-fail testing_crossmodule.cpp test_lib_nortti : <toolset>msvc:<build>no : link_fail_rtti_nortti ]
+
+ [ run testing_crossmodule.cpp test_lib_rtti_compat : : : $(nortti) $(compat) : testing_crossmodule_nortti_rtti_compat ]
+ [ run testing_crossmodule.cpp test_lib_nortti_compat : : : $(compat) : testing_crossmodule_rtti_nortti_compat ]
+ ;
+
+# Assuring that examples compile and run. Adding sources from `examples` directory to the `type_index` test suite.
+for local p in [ glob ../examples/*.cpp ]
+{
+ # RTTI on
+ type_index += [ run $(p) ] ;
+
+ # RTTI off
+ local target_name = $(p[1]:B)_no_rtti ;
+ if $(target_name) != "table_of_names_no_rtti"
+ {
+ type_index += [ run $(p) : : : <rtti>off $(norttidefines) : $(target_name) ] ;
+ }
+}
+
diff --git a/src/boost/libs/type_index/test/compare_ctti_stl.cpp b/src/boost/libs/type_index/test/compare_ctti_stl.cpp
new file mode 100644
index 000000000..c7f2ec30d
--- /dev/null
+++ b/src/boost/libs/type_index/test/compare_ctti_stl.cpp
@@ -0,0 +1,67 @@
+// Copyright Klemens Morgenstern, 2012-2015.
+// Copyright 2019-2020 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
+
diff --git a/src/boost/libs/type_index/test/ctti_print_name.cpp b/src/boost/libs/type_index/test/ctti_print_name.cpp
new file mode 100644
index 000000000..c16c8b465
--- /dev/null
+++ b/src/boost/libs/type_index/test/ctti_print_name.cpp
@@ -0,0 +1,44 @@
+//
+// Copyright 2012-2020 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;
+}
+
diff --git a/src/boost/libs/type_index/test/test_lib.cpp b/src/boost/libs/type_index/test/test_lib.cpp
new file mode 100644
index 000000000..174a7fecf
--- /dev/null
+++ b/src/boost/libs/type_index/test/test_lib.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright 2012-2020 Antony Polukhin.
+//
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#define TEST_LIB_SOURCE
+#include "test_lib.hpp"
+
+namespace user_defined_namespace {
+ class user_defined{};
+}
+
+namespace test_lib {
+
+boost::typeindex::type_index get_integer() {
+ return boost::typeindex::type_id<int>();
+}
+
+boost::typeindex::type_index get_user_defined_class() {
+ return boost::typeindex::type_id<user_defined_namespace::user_defined>();
+}
+
+boost::typeindex::type_index get_const_integer() {
+ return boost::typeindex::type_id_with_cvr<const int>();
+}
+
+boost::typeindex::type_index get_const_user_defined_class() {
+ return boost::typeindex::type_id_with_cvr<const user_defined_namespace::user_defined>();
+}
+
+#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
+// Just do nothing
+void accept_typeindex(const boost::typeindex::type_index&) {}
+#endif
+
+}
+
diff --git a/src/boost/libs/type_index/test/test_lib.hpp b/src/boost/libs/type_index/test/test_lib.hpp
new file mode 100644
index 000000000..7619008fe
--- /dev/null
+++ b/src/boost/libs/type_index/test/test_lib.hpp
@@ -0,0 +1,42 @@
+//
+// Copyright 2012-2020 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_HPP
+#define BOOST_TYPE_INDEX_TESTS_TEST_LIB_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_integer();
+TEST_LIB_DECL boost::typeindex::type_index get_user_defined_class();
+
+TEST_LIB_DECL boost::typeindex::type_index get_const_integer();
+TEST_LIB_DECL boost::typeindex::type_index get_const_user_defined_class();
+
+#if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
+// This is required for checking RTTI on/off linkage
+TEST_LIB_DECL void accept_typeindex(const boost::typeindex::type_index&);
+#endif
+
+}
+
+#endif // BOOST_TYPE_INDEX_TESTS_LIB1_HPP
+
diff --git a/src/boost/libs/type_index/test/test_lib_anonymous.cpp b/src/boost/libs/type_index/test/test_lib_anonymous.cpp
new file mode 100644
index 000000000..53f4307d4
--- /dev/null
+++ b/src/boost/libs/type_index/test/test_lib_anonymous.cpp
@@ -0,0 +1,27 @@
+//
+// Copyright 2012-2020 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>();
+}
+
+}
+
diff --git a/src/boost/libs/type_index/test/test_lib_anonymous.hpp b/src/boost/libs/type_index/test/test_lib_anonymous.hpp
new file mode 100644
index 000000000..15165eb1b
--- /dev/null
+++ b/src/boost/libs/type_index/test/test_lib_anonymous.hpp
@@ -0,0 +1,34 @@
+//
+// Copyright 2012-2020 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
+
diff --git a/src/boost/libs/type_index/test/testing_crossmodule.cpp b/src/boost/libs/type_index/test/testing_crossmodule.cpp
new file mode 100644
index 000000000..fa9017d96
--- /dev/null
+++ b/src/boost/libs/type_index/test/testing_crossmodule.cpp
@@ -0,0 +1,57 @@
+//
+// Copyright 2012-2020 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/type_index.hpp>
+#include "test_lib.hpp"
+
+#include <boost/core/lightweight_test.hpp>
+
+namespace user_defined_namespace {
+ class user_defined{};
+}
+
+void comparing_types_between_modules()
+{
+ boost::typeindex::type_index t_const_int = boost::typeindex::type_id_with_cvr<const int>();
+ boost::typeindex::type_index t_int = boost::typeindex::type_id<int>();
+
+ BOOST_TEST_EQ(t_int, test_lib::get_integer());
+ BOOST_TEST_EQ(t_const_int, test_lib::get_const_integer());
+ BOOST_TEST_NE(t_const_int, test_lib::get_integer());
+ BOOST_TEST_NE(t_int, test_lib::get_const_integer());
+
+
+ boost::typeindex::type_index t_const_userdef
+ = boost::typeindex::type_id_with_cvr<const user_defined_namespace::user_defined>();
+ boost::typeindex::type_index t_userdef
+ = boost::typeindex::type_id<user_defined_namespace::user_defined>();
+
+ BOOST_TEST_EQ(t_userdef, test_lib::get_user_defined_class());
+ BOOST_TEST_EQ(t_const_userdef, test_lib::get_const_user_defined_class());
+ BOOST_TEST_NE(t_const_userdef, test_lib::get_user_defined_class());
+ BOOST_TEST_NE(t_userdef, test_lib::get_const_user_defined_class());
+
+
+ BOOST_TEST_NE(t_userdef, test_lib::get_integer());
+ BOOST_TEST_NE(t_const_userdef, test_lib::get_integer());
+ BOOST_TEST_NE(t_int, test_lib::get_user_defined_class());
+ BOOST_TEST_NE(t_const_int, test_lib::get_const_user_defined_class());
+
+ // MSVC supports detect_missmatch pragma, but /GR- silently switch disable the link time check.
+ // /GR- undefies the _CPPRTTI macro. Using it to detect working detect_missmatch pragma.
+ #if !defined(BOOST_HAS_PRAGMA_DETECT_MISMATCH) || !defined(_CPPRTTI)
+ test_lib::accept_typeindex(t_int);
+ #endif
+}
+
+
+int main() {
+ comparing_types_between_modules();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/type_index/test/testing_crossmodule_anonymous.cpp b/src/boost/libs/type_index/test/testing_crossmodule_anonymous.cpp
new file mode 100644
index 000000000..f32a69596
--- /dev/null
+++ b/src/boost/libs/type_index/test/testing_crossmodule_anonymous.cpp
@@ -0,0 +1,48 @@
+//
+// Copyright 2012-2020 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();
+}
+
diff --git a/src/boost/libs/type_index/test/track_13621.cpp b/src/boost/libs/type_index/test/track_13621.cpp
new file mode 100644
index 000000000..31d4c53f6
--- /dev/null
+++ b/src/boost/libs/type_index/test/track_13621.cpp
@@ -0,0 +1,23 @@
+//
+// Copyright 2018-2020 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();
+}
+
diff --git a/src/boost/libs/type_index/test/type_index_constexpr_test.cpp b/src/boost/libs/type_index/test/type_index_constexpr_test.cpp
new file mode 100644
index 000000000..e9b84eaa6
--- /dev/null
+++ b/src/boost/libs/type_index/test/type_index_constexpr_test.cpp
@@ -0,0 +1,157 @@
+//
+// Copyright 2015-2020 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();
+}
+
diff --git a/src/boost/libs/type_index/test/type_index_runtime_cast_test.cpp b/src/boost/libs/type_index/test/type_index_runtime_cast_test.cpp
new file mode 100644
index 000000000..1f5344ef5
--- /dev/null
+++ b/src/boost/libs/type_index/test/type_index_runtime_cast_test.cpp
@@ -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();
+}
diff --git a/src/boost/libs/type_index/test/type_index_test.cpp b/src/boost/libs/type_index/test/type_index_test.cpp
new file mode 100644
index 000000000..9a4c73c5a
--- /dev/null
+++ b/src/boost/libs/type_index/test/type_index_test.cpp
@@ -0,0 +1,400 @@
+//
+// Copyright 2012-2020 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/type_index.hpp>
+
+#include <boost/lexical_cast.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+namespace my_namespace1 {
+ class my_class{};
+}
+
+
+namespace my_namespace2 {
+ class my_class{};
+}
+
+
+void names_matches_type_id()
+{
+ using namespace boost::typeindex;
+ BOOST_TEST_EQ(type_id<int>().pretty_name(), "int");
+ BOOST_TEST_EQ(type_id<double>().pretty_name(), "double");
+
+ BOOST_TEST_EQ(type_id<int>().name(), type_id<int>().name());
+ BOOST_TEST_NE(type_id<int>().name(), type_id<double>().name());
+ BOOST_TEST_NE(type_id<double>().name(), type_id<int>().name());
+ BOOST_TEST_EQ(type_id<double>().name(), type_id<double>().name());
+}
+
+void default_construction()
+{
+ using namespace boost::typeindex;
+ type_index ti1, ti2;
+ BOOST_TEST_EQ(ti1, ti2);
+ BOOST_TEST_EQ(type_id<void>(), ti1);
+
+ BOOST_TEST_EQ(type_id<void>().name(), ti1.name());
+ BOOST_TEST_NE(type_id<int>(), ti1);
+}
+
+
+void copy_construction()
+{
+ using namespace boost::typeindex;
+ type_index ti1, ti2 = type_id<int>();
+ BOOST_TEST_NE(ti1, ti2);
+ ti1 = ti2;
+ BOOST_TEST_EQ(ti2, ti1);
+
+ const type_index ti3(ti1);
+ BOOST_TEST_EQ(ti3, ti1);
+}
+
+void comparators_type_id()
+{
+ using namespace boost::typeindex;
+ type_index t_int = type_id<int>();
+ type_index t_double = type_id<double>();
+
+ BOOST_TEST_EQ(t_int, t_int);
+ BOOST_TEST_LE(t_int, t_int);
+ BOOST_TEST_GE(t_int, t_int);
+ BOOST_TEST_NE(t_int, t_double);
+
+ BOOST_TEST_LE(t_double, t_double);
+ BOOST_TEST_GE(t_double, t_double);
+ BOOST_TEST_NE(t_double, t_int);
+
+ BOOST_TEST(t_double < t_int || t_int < t_double);
+ BOOST_TEST(t_double > t_int || t_int > t_double);
+}
+
+void hash_code_type_id()
+{
+ using namespace boost::typeindex;
+ std::size_t t_int1 = type_id<int>().hash_code();
+ std::size_t t_double1 = type_id<double>().hash_code();
+
+ std::size_t t_int2 = type_id<int>().hash_code();
+ std::size_t t_double2 = type_id<double>().hash_code();
+
+ BOOST_TEST_EQ(t_int1, t_int2);
+ BOOST_TEST_NE(t_int1, t_double2);
+ BOOST_TEST_LE(t_double1, t_double2);
+}
+
+
+
+template <class T1, class T2>
+static void test_with_modofiers() {
+ using namespace boost::typeindex;
+
+ type_index t1 = type_id_with_cvr<T1>();
+ type_index t2 = type_id_with_cvr<T2>();
+
+ BOOST_TEST_NE(t2, t1);
+ BOOST_TEST(t2 != t1.type_info());
+ BOOST_TEST(t2.type_info() != t1);
+
+ BOOST_TEST(t1 < t2 || t2 < t1);
+ BOOST_TEST(t1 > t2 || t2 > t1);
+ BOOST_TEST(t1.type_info() < t2 || t2.type_info() < t1);
+ BOOST_TEST(t1.type_info() > t2 || t2.type_info() > t1);
+ BOOST_TEST(t1 < t2.type_info() || t2 < t1.type_info());
+ BOOST_TEST(t1 > t2.type_info() || t2 > t1.type_info());
+
+ // Chaecking that comparison operators overloads compile
+ BOOST_TEST(t1 <= t2 || t2 <= t1);
+ BOOST_TEST(t1 >= t2 || t2 >= t1);
+ BOOST_TEST(t1.type_info() <= t2 || t2.type_info() <= t1);
+ BOOST_TEST(t1.type_info() >= t2 || t2.type_info() >= t1);
+ BOOST_TEST(t1 <= t2.type_info() || t2 <= t1.type_info());
+ BOOST_TEST(t1 >= t2.type_info() || t2 >= t1.type_info());
+
+ BOOST_TEST_EQ(t1, type_id_with_cvr<T1>());
+ BOOST_TEST_EQ(t2, type_id_with_cvr<T2>());
+ BOOST_TEST(t1 == type_id_with_cvr<T1>().type_info());
+ BOOST_TEST(t2 == type_id_with_cvr<T2>().type_info());
+ BOOST_TEST(t1.type_info() == type_id_with_cvr<T1>());
+ BOOST_TEST(t2.type_info() == type_id_with_cvr<T2>());
+
+ BOOST_TEST_EQ(t1.hash_code(), type_id_with_cvr<T1>().hash_code());
+ BOOST_TEST_EQ(t2.hash_code(), type_id_with_cvr<T2>().hash_code());
+
+ BOOST_TEST_NE(t1.hash_code(), type_id_with_cvr<T2>().hash_code());
+ BOOST_TEST_NE(t2.hash_code(), type_id_with_cvr<T1>().hash_code());
+}
+
+void type_id_storing_modifiers()
+{
+ test_with_modofiers<int, const int>();
+ test_with_modofiers<int, const int&>();
+ test_with_modofiers<int, int&>();
+ test_with_modofiers<int, volatile int>();
+ test_with_modofiers<int, volatile int&>();
+ test_with_modofiers<int, const volatile int>();
+ test_with_modofiers<int, const volatile int&>();
+
+ test_with_modofiers<const int, int>();
+ test_with_modofiers<const int, const int&>();
+ test_with_modofiers<const int, int&>();
+ test_with_modofiers<const int, volatile int>();
+ test_with_modofiers<const int, volatile int&>();
+ test_with_modofiers<const int, const volatile int>();
+ test_with_modofiers<const int, const volatile int&>();
+
+ test_with_modofiers<const int&, int>();
+ test_with_modofiers<const int&, const int>();
+ test_with_modofiers<const int&, int&>();
+ test_with_modofiers<const int&, volatile int>();
+ test_with_modofiers<const int&, volatile int&>();
+ test_with_modofiers<const int&, const volatile int>();
+ test_with_modofiers<const int&, const volatile int&>();
+
+ test_with_modofiers<int&, const int>();
+ test_with_modofiers<int&, const int&>();
+ test_with_modofiers<int&, int>();
+ test_with_modofiers<int&, volatile int>();
+ test_with_modofiers<int&, volatile int&>();
+ test_with_modofiers<int&, const volatile int>();
+ test_with_modofiers<int&, const volatile int&>();
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ test_with_modofiers<int&&, const int>();
+ test_with_modofiers<int&&, const int&>();
+ test_with_modofiers<int&&, const int&&>();
+ test_with_modofiers<int&&, int>();
+ test_with_modofiers<int&&, volatile int>();
+ test_with_modofiers<int&&, volatile int&>();
+ test_with_modofiers<int&&, volatile int&&>();
+ test_with_modofiers<int&&, const volatile int>();
+ test_with_modofiers<int&&, const volatile int&>();
+ test_with_modofiers<int&&, const volatile int&&>();
+#endif
+}
+
+template <class T>
+static void test_storing_nonstoring_modifiers_templ() {
+ using namespace boost::typeindex;
+
+ type_index t1 = type_id_with_cvr<T>();
+ type_index t2 = type_id<T>();
+
+ BOOST_TEST_EQ(t2, t1);
+ BOOST_TEST_EQ(t1, t2);
+ BOOST_TEST(t1 <= t2);
+ BOOST_TEST(t1 >= t2);
+ BOOST_TEST(t2 <= t1);
+ BOOST_TEST(t2 >= t1);
+
+ BOOST_TEST_EQ(t2.pretty_name(), t1.pretty_name());
+}
+
+void type_id_storing_modifiers_vs_nonstoring()
+{
+ test_storing_nonstoring_modifiers_templ<int>();
+ test_storing_nonstoring_modifiers_templ<my_namespace1::my_class>();
+ test_storing_nonstoring_modifiers_templ<my_namespace2::my_class>();
+
+ boost::typeindex::type_index t1 = boost::typeindex::type_id_with_cvr<const int>();
+ boost::typeindex::type_index t2 = boost::typeindex::type_id<int>();
+ BOOST_TEST_NE(t2, t1);
+ BOOST_TEST(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
+}
+
+void type_index_stream_operator_via_lexical_cast_testing()
+{
+ using namespace boost::typeindex;
+
+ std::string s_int2 = boost::lexical_cast<std::string>(type_id<int>());
+ BOOST_TEST_EQ(s_int2, "int");
+
+ std::string s_double2 = boost::lexical_cast<std::string>(type_id<double>());
+ BOOST_TEST_EQ(s_double2, "double");
+}
+
+void type_index_stripping_cvr_test()
+{
+ using namespace boost::typeindex;
+
+ BOOST_TEST_EQ(type_id<int>(), type_id<const int>());
+ BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int>());
+ BOOST_TEST_EQ(type_id<int>(), type_id<const volatile int&>());
+
+ BOOST_TEST_EQ(type_id<int>(), type_id<int&>());
+ BOOST_TEST_EQ(type_id<int>(), type_id<volatile int>());
+ BOOST_TEST_EQ(type_id<int>(), type_id<volatile int&>());
+
+
+ BOOST_TEST_EQ(type_id<double>(), type_id<const double>());
+ BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double>());
+ BOOST_TEST_EQ(type_id<double>(), type_id<const volatile double&>());
+
+ BOOST_TEST_EQ(type_id<double>(), type_id<double&>());
+ BOOST_TEST_EQ(type_id<double>(), type_id<volatile double>());
+ BOOST_TEST_EQ(type_id<double>(), type_id<volatile double&>());
+}
+
+
+void type_index_user_defined_class_test()
+{
+ using namespace boost::typeindex;
+
+ BOOST_TEST_EQ(type_id<my_namespace1::my_class>(), type_id<my_namespace1::my_class>());
+ BOOST_TEST_EQ(type_id<my_namespace2::my_class>(), type_id<my_namespace2::my_class>());
+
+#ifndef BOOST_NO_RTTI
+ BOOST_TEST(type_id<my_namespace1::my_class>() == typeid(my_namespace1::my_class));
+ BOOST_TEST(type_id<my_namespace2::my_class>() == typeid(my_namespace2::my_class));
+ BOOST_TEST(typeid(my_namespace1::my_class) == type_id<my_namespace1::my_class>());
+ BOOST_TEST(typeid(my_namespace2::my_class) == type_id<my_namespace2::my_class>());
+#endif
+
+ BOOST_TEST_NE(type_id<my_namespace1::my_class>(), type_id<my_namespace2::my_class>());
+ BOOST_TEST_NE(
+ type_id<my_namespace1::my_class>().pretty_name().find("my_namespace1::my_class"),
+ std::string::npos);
+}
+
+
+
+
+
+struct A {
+public:
+ BOOST_TYPE_INDEX_REGISTER_CLASS
+ virtual ~A(){}
+};
+
+struct B: public A {
+ BOOST_TYPE_INDEX_REGISTER_CLASS
+};
+
+struct C: public B {
+ BOOST_TYPE_INDEX_REGISTER_CLASS
+};
+
+void comparators_type_id_runtime()
+{
+ C c1;
+ B b1;
+ A* pc1 = &c1;
+ A& rc1 = c1;
+ A* pb1 = &b1;
+ A& rb1 = b1;
+
+#ifndef BOOST_NO_RTTI
+ BOOST_TEST(typeid(rc1) == typeid(*pc1));
+ BOOST_TEST(typeid(rb1) == typeid(*pb1));
+
+ BOOST_TEST(typeid(rc1) != typeid(*pb1));
+ BOOST_TEST(typeid(rb1) != typeid(*pc1));
+
+ BOOST_TEST(typeid(&rc1) == typeid(pb1));
+ BOOST_TEST(typeid(&rb1) == typeid(pc1));
+#else
+ BOOST_TEST(boost::typeindex::type_index(pc1->boost_type_index_type_id_runtime_()).raw_name());
+#endif
+
+ BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pc1));
+ BOOST_TEST_EQ(boost::typeindex::type_id<C>(), boost::typeindex::type_id_runtime(*pc1));
+ BOOST_TEST_EQ(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pb1));
+ BOOST_TEST_EQ(boost::typeindex::type_id<B>(), boost::typeindex::type_id_runtime(*pb1));
+
+ BOOST_TEST_NE(boost::typeindex::type_id_runtime(rc1), boost::typeindex::type_id_runtime(*pb1));
+ BOOST_TEST_NE(boost::typeindex::type_id_runtime(rb1), boost::typeindex::type_id_runtime(*pc1));
+
+#ifndef BOOST_NO_RTTI
+ BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rc1), boost::typeindex::type_id_runtime(pb1));
+ BOOST_TEST_EQ(boost::typeindex::type_id_runtime(&rb1), boost::typeindex::type_id_runtime(pc1));
+
+ BOOST_TEST(boost::typeindex::type_id_runtime(rc1) == typeid(*pc1));
+ BOOST_TEST(boost::typeindex::type_id_runtime(rb1) == typeid(*pb1));
+
+ BOOST_TEST(boost::typeindex::type_id_runtime(rc1) != typeid(*pb1));
+ BOOST_TEST(boost::typeindex::type_id_runtime(rb1) != typeid(*pc1));
+ BOOST_TEST(boost::typeindex::type_id_runtime(&rc1) == typeid(pb1));
+ BOOST_TEST(boost::typeindex::type_id_runtime(&rb1) == typeid(pc1));
+#endif
+}
+
+
+#ifndef BOOST_NO_RTTI
+
+void comparators_type_id_vs_type_info()
+{
+ using namespace boost::typeindex;
+ type_index t_int = type_id<int>();
+
+ BOOST_TEST(t_int == typeid(int));
+ BOOST_TEST(typeid(int) == t_int);
+ BOOST_TEST(t_int <= typeid(int));
+ BOOST_TEST(typeid(int) <= t_int);
+ BOOST_TEST(t_int >= typeid(int));
+ BOOST_TEST(typeid(int) >= t_int);
+
+ type_index t_double = type_id<double>();
+
+ BOOST_TEST(t_double == typeid(double));
+ BOOST_TEST(typeid(double) == t_double);
+ BOOST_TEST(t_double <= typeid(double));
+ BOOST_TEST(typeid(double) <= t_double);
+ BOOST_TEST(t_double >= typeid(double));
+ BOOST_TEST(typeid(double) >= t_double);
+
+ if (t_double < t_int) {
+ BOOST_TEST(t_double < typeid(int));
+ BOOST_TEST(typeid(double) < t_int);
+ BOOST_TEST(typeid(int) > t_double);
+ BOOST_TEST(t_int > typeid(double));
+
+
+ BOOST_TEST(t_double <= typeid(int));
+ BOOST_TEST(typeid(double) <= t_int);
+ BOOST_TEST(typeid(int) >= t_double);
+ BOOST_TEST(t_int >= typeid(double));
+ } else {
+ BOOST_TEST(t_double > typeid(int));
+ BOOST_TEST(typeid(double) > t_int);
+ BOOST_TEST(typeid(int) < t_double);
+ BOOST_TEST(t_int < typeid(double));
+
+
+ BOOST_TEST(t_double >= typeid(int));
+ BOOST_TEST(typeid(double) >= t_int);
+ BOOST_TEST(typeid(int) <= t_double);
+ BOOST_TEST(t_int <= typeid(double));
+ }
+
+}
+
+#endif // BOOST_NO_RTTI
+
+int main() {
+ names_matches_type_id();
+ default_construction();
+ copy_construction();
+ comparators_type_id();
+ hash_code_type_id();
+
+ type_id_storing_modifiers();
+ type_id_storing_modifiers_vs_nonstoring();
+ type_index_stream_operator_via_lexical_cast_testing();
+ type_index_stripping_cvr_test();
+ type_index_user_defined_class_test();
+
+ comparators_type_id_runtime();
+#ifndef BOOST_NO_RTTI
+ comparators_type_id_vs_type_info();
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/type_index/test/type_index_test_ctti_alignment.cpp b/src/boost/libs/type_index/test/type_index_test_ctti_alignment.cpp
new file mode 100644
index 000000000..95b25d718
--- /dev/null
+++ b/src/boost/libs/type_index/test/type_index_test_ctti_alignment.cpp
@@ -0,0 +1,18 @@
+//
+// Copyright 2012-2020 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/type_index/ctti_type_index.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+
+int main() {
+ BOOST_STATIC_ASSERT_MSG(
+ boost::alignment_of<boost::typeindex::detail::ctti_data>::value == boost::alignment_of<char>::value,
+ "Alignments of boost::typeindex::detail::ctti_data and char differ. "
+ "It is unsafe to reinterpret_cast between them."
+ );
+}
+
diff --git a/src/boost/libs/type_index/test/type_index_test_ctti_construct_fail.cpp b/src/boost/libs/type_index/test/type_index_test_ctti_construct_fail.cpp
new file mode 100644
index 000000000..ce3c3a890
--- /dev/null
+++ b/src/boost/libs/type_index/test/type_index_test_ctti_construct_fail.cpp
@@ -0,0 +1,15 @@
+//
+// Copyright 2012-2020 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/type_index/ctti_type_index.hpp>
+
+int main() {
+ using namespace boost::typeindex;
+ ctti_type_index::type_info_t t;
+ (void)t;
+}
+
diff --git a/src/boost/libs/type_index/test/type_index_test_ctti_copy_fail.cpp b/src/boost/libs/type_index/test/type_index_test_ctti_copy_fail.cpp
new file mode 100644
index 000000000..fad7fa487
--- /dev/null
+++ b/src/boost/libs/type_index/test/type_index_test_ctti_copy_fail.cpp
@@ -0,0 +1,15 @@
+//
+// Copyright 2012-2020 Antony Polukhin.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/type_index/ctti_type_index.hpp>
+
+int main() {
+ using namespace boost::typeindex;
+ ctti_type_index::type_info_t t = ctti_type_index::type_id<int>().type_info();
+ (void)t;
+}
+