mirror of
https://github.com/boostorg/type_index.git
synced 2025-07-29 20:07:18 +02:00
Fixed notes mentioned by Klaim - Joël Lamotte during review
This commit is contained in:
@ -180,6 +180,9 @@ will be used.
|
||||
`BOOST_TYPE_INDEX_REGISTER_CLASS` macro is a helper macro that places some virtual helper functions or
|
||||
expands to nothing.
|
||||
|
||||
Issues with cross module type comparison on a bugged compilers are bypassed by directly comparing strings with type
|
||||
(latest versions of those compilers resolved that issue using exactly the same approach).
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Examples]
|
||||
@ -262,19 +265,23 @@ i
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Compiler support]
|
||||
[section RTTI emulation limitations]
|
||||
|
||||
TypeIndex has been tested and successfully work on MSVC2010, GCC-4.6, Clang-2.9. If your compiler is not
|
||||
in a list of tested compilers, you must correctly define `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`,
|
||||
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` macroses:
|
||||
TypeIndex has been tested and successfully work on many compilers.
|
||||
|
||||
If `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE` macro is not defined or
|
||||
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP`
|
||||
are defined to zero then you are using a compiler that was not tested with this library.
|
||||
In that case if you wish to use this library with RTTI off, you must correctly define
|
||||
`BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`, `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and
|
||||
`BOOST_TYPE_INDEX_CTTI_END_SKIP` macros:
|
||||
|
||||
# define `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE` to a compiler specific macro, that outputs the *whole*
|
||||
function signature, including template parameters
|
||||
# define `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `0`
|
||||
# get the output of `boost::template_id<int>().name()`
|
||||
# get the output of `boost::typeindex::ctti_type_index::type_id<int>().name()`
|
||||
# set `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` equal to characters count before last occurrence of `int` in output
|
||||
# set `BOOST_TYPE_INDEX_CTTI_END_SKIP` equal to characters count after last occurrence of `int` in output
|
||||
# check that `boost::template_id<int>().name_demangled()` returns "int"
|
||||
# check that `boost::typeindex::ctti_type_index::type_id<int>().name_demangled()` returns "int"
|
||||
# (optional, but highly recomended) [@http://www.boost.org/support/bugs.html create ticket] with
|
||||
feature request to add your compiler to supported compilers list. Include
|
||||
`BOOST_TYPE_INDEX_FUNCTION_SIGNATURE`, `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and
|
||||
@ -288,6 +295,25 @@ With `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` set
|
||||
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` to `sizeof("const char *__cdecl boost::detail::ctti<") - 1`
|
||||
and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `sizeof(">::n(void)") - 1`.
|
||||
|
||||
[warning
|
||||
With RTTI off classes with exactly the same names defined in different modules in anonymous namespaces may collapse:
|
||||
```
|
||||
// In A.cpp
|
||||
namespace { struct user_defined{}; }
|
||||
type_index foo_a() { return type_id<user_defined>(); }
|
||||
|
||||
// In B.cpp
|
||||
namespace { struct user_defined{}; }
|
||||
type_index foo_b() { return type_id<user_defined>(); }
|
||||
|
||||
// In main.cpp
|
||||
assert(foo_a() != foo_b()); // will fail on some compilers
|
||||
```
|
||||
|
||||
*Compilers that have that limitation:* GCC, CLANG.
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Mixing sources with RTTI on and RTTI off]
|
||||
|
@ -23,28 +23,54 @@ void foo(T) {
|
||||
|
||||
struct user_defined_type{};
|
||||
|
||||
namespace ns1 { namespace ns2 {
|
||||
struct user_defined_type{};
|
||||
}} // namespace ns1::ns2
|
||||
|
||||
namespace {
|
||||
struct in_anon_type{};
|
||||
} // anonymous namespace
|
||||
|
||||
int main() {
|
||||
// Call to
|
||||
foo(1);
|
||||
// will output something like this:
|
||||
//
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: i Short name: int]
|
||||
// Readable name: int Readable name: int
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: i Short name: int]
|
||||
// Readable name: int Readable name: int
|
||||
|
||||
user_defined_type t;
|
||||
foo(t);
|
||||
// Will output:
|
||||
//
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: 17user_defined_type user_defined_type]
|
||||
// Readable name: user_defined_type user_defined_type
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: 17user_defined_type user_defined_type]
|
||||
// Readable name: user_defined_type user_defined_type
|
||||
|
||||
ns1::ns2::user_defined_type t_in_ns;
|
||||
foo(t_in_ns);
|
||||
// Will output:
|
||||
//
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: N3ns13ns217user_defined_typeE ns1::ns2::user_defined_type]
|
||||
// Readable name: ns1::ns2::user_defined_type ns1::ns2::user_defined_type
|
||||
|
||||
in_anon_type anon_t;
|
||||
foo(anon_t);
|
||||
// Will output:
|
||||
//
|
||||
// (RTTI on) (RTTI off)
|
||||
// Short name: N12_GLOBAL__N_112in_anon_typeE {anonymous}::in_anon_type]
|
||||
// Readable name: (anonymous namespace)::in_anon_type {anonymous}::in_anon_type
|
||||
}
|
||||
|
||||
/*`
|
||||
Short names are very compiler dependant: some compiler will output `.H`, others `i`.
|
||||
|
||||
Readable names may also differ between compilers: `struct user_defined_type`, `user_defined_type`.
|
||||
|
||||
[warning With RTTI off different classes with same names in anonymous namespace may collapse. See 'RTTI emulation limitations'. ]
|
||||
*/
|
||||
|
||||
//] [/type_index_names_example]
|
||||
|
@ -70,7 +70,7 @@ inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
|
||||
|
||||
/// \class ctti_type_index
|
||||
/// This class is a wrapper that pretends to work exactly like stl_type_index, but does
|
||||
/// not require RTTI support. For description of functions see type_index_facade.
|
||||
/// not require RTTI support. \b For \b description \b of \b functions \b see type_index_facade.
|
||||
///
|
||||
/// This class produces slightly longer type names, so consider using stl_type_index
|
||||
/// in situations when typeid() is working.
|
||||
|
@ -62,7 +62,7 @@ namespace boost { namespace typeindex {
|
||||
|
||||
/// \class stl_type_index
|
||||
/// This class is a wrapper around std::type_info, that workarounds issues and provides
|
||||
/// much more rich interface. For description of functions see type_index_facade.
|
||||
/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
|
||||
///
|
||||
/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index.
|
||||
class stl_type_index
|
||||
|
@ -20,10 +20,14 @@ nortti = <toolset>gcc:<cxxflags>-fno-rtti <toolset>clang:<cxxflags>-fno-rtti <to
|
||||
|
||||
# Making libraries that CANNOT work between rtti-on/rtti-off modules
|
||||
obj test_lib_nortti-obj : test_lib.cpp : <link>shared <rtti>off ;
|
||||
obj test_lib_anonymous_nortti-obj : test_lib_anonymous.cpp : <link>shared <rtti>off ;
|
||||
lib test_lib_nortti : test_lib_nortti-obj : <link>shared <rtti>off ;
|
||||
lib test_lib_anonymous_nortti : test_lib_anonymous_nortti-obj : <link>shared <rtti>off ;
|
||||
|
||||
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) ;
|
||||
@ -38,6 +42,8 @@ test-suite type_index
|
||||
[ run type_index_test.cpp $(tlib) : : : <rtti>off : type_index_test_no_rtti ]
|
||||
[ run testing_crossmodule.cpp test_lib_rtti $(tlib) ]
|
||||
[ run testing_crossmodule.cpp test_lib_nortti $(tlib) : : : <rtti>off : testing_crossmodule_no_rtti ]
|
||||
[ run testing_crossmodule_anonymous.cpp test_lib_anonymous_rtti $(tlib) ]
|
||||
[ run testing_crossmodule_anonymous.cpp test_lib_anonymous_nortti $(tlib) : : : <rtti>off : testing_crossmodule_anonymous_no_rtti ]
|
||||
[ 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 ]
|
||||
|
19
test/test_lib_anonymous.cpp
Normal file
19
test/test_lib_anonymous.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#define TEST_LIB_SOURCE
|
||||
#include "test_lib_anonymous.hpp"
|
||||
|
||||
namespace {
|
||||
class user_defined{};
|
||||
} // anonymous namespace
|
||||
|
||||
namespace test_lib {
|
||||
|
||||
boost::typeindex::type_index get_anonymous_user_defined_class() {
|
||||
return boost::typeindex::type_id<user_defined>();
|
||||
}
|
||||
|
||||
boost::typeindex::type_index get_const_anonymous_user_defined_class() {
|
||||
return boost::typeindex::type_id_with_cvr<const user_defined>();
|
||||
}
|
||||
|
||||
}
|
||||
|
34
test/test_lib_anonymous.hpp
Normal file
34
test/test_lib_anonymous.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Copyright (c) Antony Polukhin, 2012-2014.
|
||||
//
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_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
|
||||
|
28
test/testing_crossmodule_anonymous.cpp
Normal file
28
test/testing_crossmodule_anonymous.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2014.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define BOOST_TEST_MODULE testing_crossmodule_anon_module
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include "test_lib_anonymous.hpp"
|
||||
|
||||
namespace {
|
||||
class user_defined{};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(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>();
|
||||
|
||||
BOOST_CHECK_NE(t_userdef, test_lib::get_anonymous_user_defined_class());
|
||||
BOOST_CHECK_NE(t_const_userdef, test_lib::get_const_anonymous_user_defined_class());
|
||||
BOOST_CHECK_NE(t_const_userdef, test_lib::get_anonymous_user_defined_class());
|
||||
BOOST_CHECK_NE(t_userdef, test_lib::get_const_anonymous_user_defined_class());
|
||||
}
|
||||
|
Reference in New Issue
Block a user