mirror of
https://github.com/boostorg/type_index.git
synced 2025-08-03 06:14:26 +02:00
Make code thread safe even on antique/broken compilers. Improve examples and add more tests
This commit is contained in:
@@ -49,15 +49,16 @@ namespace my_namespace { namespace detail {
|
||||
|
||||
// my_typeinfo structure is used to save type number
|
||||
struct my_typeinfo {
|
||||
// type_[0] will hold a type number
|
||||
// type_[1] will be '\0', to have a zero terminated raw type name
|
||||
char type_[2];
|
||||
const char* const type_;
|
||||
};
|
||||
|
||||
const my_typeinfo infos[5] = {
|
||||
{"void"}, {"my_class"}, {"my_struct"}, {"my_classes"}, {"my_string"}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline const my_typeinfo& my_typeinfo_construct() {
|
||||
static const my_typeinfo ret = {{ static_cast<char>(typenum<T>::value), '\0' }};
|
||||
return ret;
|
||||
return infos[typenum<T>::value];
|
||||
}
|
||||
}} // my_namespace::detail
|
||||
|
||||
@@ -97,13 +98,7 @@ public:
|
||||
}
|
||||
|
||||
inline std::string pretty_name() const {
|
||||
// Must be in sync with detail::typenum<T>::value
|
||||
static const char* names[] = {
|
||||
"void", "my_class", "my_struct", "my_classes", "my_string"
|
||||
};
|
||||
|
||||
const std::size_t indx = static_cast<std::size_t>(data_->type_[0]);
|
||||
return names[indx];
|
||||
return data_->type_;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
@@ -61,6 +61,8 @@ namespace boost { namespace typeind {
|
||||
///
|
||||
/// Could be a std::type_info, boost::typeind::detail::ctti_data or
|
||||
/// some user defined class.
|
||||
///
|
||||
/// type_info \b is \b not copyable or default constructible. It is \b not assignable too!
|
||||
typedef type_index::type_info_t type_info;
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
@@ -35,17 +35,25 @@ namespace boost { namespace typeind {
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct ctti_data {
|
||||
const char* typename_;
|
||||
};
|
||||
// That's the most trickiest part of the TypeIndex library:
|
||||
// 1) we do not whant to give user ability to manually construct and compare `struct-that-represents-type`
|
||||
// 2) we need to distinguish beteween `struct-that-represents-type` and `const char*`
|
||||
// 3) we need a thread-safe way to have references to instances `struct-that-represents-type`
|
||||
// 4) we need a compile-time control to make shure that user does not copy or
|
||||
// default construct `struct-that-represents-type`
|
||||
//
|
||||
// Solution would be a forward declared structure.
|
||||
struct ctti_data;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Helper method for getting detail::ctti_data of a tempalte patameter T.
|
||||
template <class T>
|
||||
inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
|
||||
static const detail::ctti_data result = { boost::detail::ctti<T>::n() };
|
||||
return result;
|
||||
// Standard C++11, 5.2.10 Reinterpret cast: Converting a prvalue of type “pointer to T1” to the
|
||||
// type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no
|
||||
// stricter than those of T1) and back to its original type yields the original pointer value.
|
||||
return *reinterpret_cast<const detail::ctti_data*>(boost::detail::ctti<T>::n());
|
||||
}
|
||||
|
||||
/// \class ctti_type_index
|
||||
@@ -111,7 +119,7 @@ inline ctti_type_index ctti_type_index::type_id_runtime(const T& variable) BOOST
|
||||
|
||||
|
||||
inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
|
||||
return data_->typename_;
|
||||
return reinterpret_cast<const char*>(data_);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -38,7 +38,9 @@ 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 ]
|
||||
|
||||
[ compile-fail type_index_test_ctti_copy_fail.cpp ]
|
||||
[ compile-fail type_index_test_ctti_construct_fail.cpp ]
|
||||
|
||||
# Mixing RTTI on and off
|
||||
[ link-fail testing_crossmodule.cpp $(tlib) test_lib_rtti : $(nortti) : link_fail_nortti_rtti ]
|
||||
# MSVC sometimes overrides the /GR-, that's why the following tests is disabled
|
||||
|
@@ -100,11 +100,30 @@ static void test_with_modofiers() {
|
||||
type_index t2 = type_id_with_cvr<T2>();
|
||||
|
||||
BOOST_CHECK_NE(t2, t1);
|
||||
BOOST_CHECK(t2 != t1.type_info());
|
||||
BOOST_CHECK(t2.type_info() != t1);
|
||||
|
||||
BOOST_CHECK(t1 < t2 || t2 < t1);
|
||||
BOOST_CHECK(t1 > t2 || t2 > t1);
|
||||
BOOST_CHECK(t1.type_info() < t2 || t2.type_info() < t1);
|
||||
BOOST_CHECK(t1.type_info() > t2 || t2.type_info() > t1);
|
||||
BOOST_CHECK(t1 < t2.type_info() || t2 < t1.type_info());
|
||||
BOOST_CHECK(t1 > t2.type_info() || t2 > t1.type_info());
|
||||
|
||||
// Chaecking that comparisom operators overloads compile
|
||||
BOOST_CHECK(t1 <= t2 || t2 <= t1);
|
||||
BOOST_CHECK(t1 >= t2 || t2 >= t1);
|
||||
BOOST_CHECK(t1.type_info() <= t2 || t2.type_info() <= t1);
|
||||
BOOST_CHECK(t1.type_info() >= t2 || t2.type_info() >= t1);
|
||||
BOOST_CHECK(t1 <= t2.type_info() || t2 <= t1.type_info());
|
||||
BOOST_CHECK(t1 >= t2.type_info() || t2 >= t1.type_info());
|
||||
|
||||
BOOST_CHECK_EQUAL(t1, type_id_with_cvr<T1>());
|
||||
BOOST_CHECK_EQUAL(t2, type_id_with_cvr<T2>());
|
||||
BOOST_CHECK(t1 == type_id_with_cvr<T1>().type_info());
|
||||
BOOST_CHECK(t2 == type_id_with_cvr<T2>().type_info());
|
||||
BOOST_CHECK(t1.type_info() == type_id_with_cvr<T1>());
|
||||
BOOST_CHECK(t2.type_info() == type_id_with_cvr<T2>());
|
||||
|
||||
BOOST_CHECK_EQUAL(t1.hash_code(), type_id_with_cvr<T1>().hash_code());
|
||||
BOOST_CHECK_EQUAL(t2.hash_code(), type_id_with_cvr<T2>().hash_code());
|
||||
|
15
test/type_index_test_ctti_construct_fail.cpp
Normal file
15
test/type_index_test_ctti_construct_fail.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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::typeind;
|
||||
ctti_type_index::type_info_t t;
|
||||
(void)t;
|
||||
}
|
||||
|
15
test/type_index_test_ctti_copy_fail.cpp
Normal file
15
test/type_index_test_ctti_copy_fail.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
//
|
||||
// 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::typeind;
|
||||
ctti_type_index::type_info_t t = ctti_type_index::type_id<int>().type_info();
|
||||
(void)t;
|
||||
}
|
||||
|
Reference in New Issue
Block a user