Squashed 'third_party/boostorg/type_index/' content from commit c2caa34

Change-Id: I76e1c1099cbf17522d18a78a42581be067301ca4
git-subtree-dir: third_party/boostorg/type_index
git-subtree-split: c2caa340ab9d9d834c5ffafb3f267b3c46c8c821
diff --git a/examples/constexpr14_namespace_check.cpp b/examples/constexpr14_namespace_check.cpp
new file mode 100644
index 0000000..98a5e40
--- /dev/null
+++ b/examples/constexpr14_namespace_check.cpp
@@ -0,0 +1,97 @@
+// Copyright 2013-2017 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/examples/constexpr14_sort_check.cpp b/examples/constexpr14_sort_check.cpp
new file mode 100644
index 0000000..54a8435
--- /dev/null
+++ b/examples/constexpr14_sort_check.cpp
@@ -0,0 +1,76 @@
+// Copyright 2013-2017 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)
+
+//[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)
+
+int main() {}
+
+#endif
+
diff --git a/examples/demangled_names.cpp b/examples/demangled_names.cpp
new file mode 100644
index 0000000..d148b5d
--- /dev/null
+++ b/examples/demangled_names.cpp
@@ -0,0 +1,76 @@
+// Copyright 2013-2014 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/examples/exact_types_match.cpp b/examples/exact_types_match.cpp
new file mode 100644
index 0000000..498d662
--- /dev/null
+++ b/examples/exact_types_match.cpp
@@ -0,0 +1,74 @@
+// Copyright 2013-2015 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/examples/inheritance.cpp b/examples/inheritance.cpp
new file mode 100644
index 0000000..3da7527
--- /dev/null
+++ b/examples/inheritance.cpp
@@ -0,0 +1,47 @@
+// Copyright 2013-2014 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/examples/registry.cpp b/examples/registry.cpp
new file mode 100644
index 0000000..64a97ca
--- /dev/null
+++ b/examples/registry.cpp
@@ -0,0 +1,50 @@
+// Copyright 2013-2017 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_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>());
+}
+
+//] [/type_index_registry_example]
diff --git a/examples/runtime_cast.cpp b/examples/runtime_cast.cpp
new file mode 100644
index 0000000..43e7aa7
--- /dev/null
+++ b/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/examples/table_of_names.cpp b/examples/table_of_names.cpp
new file mode 100644
index 0000000..262e5f4
--- /dev/null
+++ b/examples/table_of_names.cpp
@@ -0,0 +1,90 @@
+// Copyright 2013-2014 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/examples/user_defined_typeinfo.cpp b/examples/user_defined_typeinfo.cpp
new file mode 100644
index 0000000..b4fd076
--- /dev/null
+++ b/examples/user_defined_typeinfo.cpp
@@ -0,0 +1,69 @@
+// Copyright 2013-2015 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]
+}
+
+
diff --git a/examples/user_defined_typeinfo.hpp b/examples/user_defined_typeinfo.hpp
new file mode 100644
index 0000000..946be17
--- /dev/null
+++ b/examples/user_defined_typeinfo.hpp
@@ -0,0 +1,213 @@
+// Copyright 2013-2018 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
+