Fixed notes mentioned by Klaim - Joël Lamotte during review

This commit is contained in:
Antony Polukhin
2014-05-04 20:28:45 +04:00
parent 5ed8543025
commit 6af608a827
8 changed files with 154 additions and 15 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

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

View 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

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