📄 rtti_policy.hpp
字号:
#ifndef BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
#define BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
//////////////////////////////////////////////////////////////////////////////
// Copyright 2002-2006 Andreas Huber Doenni
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//////////////////////////////////////////////////////////////////////////////
#include <boost/assert.hpp>
#include <boost/config.hpp> // BOOST_MSVC
#include <boost/detail/workaround.hpp>
#include <typeinfo> // std::type_info
#ifdef BOOST_MSVC
// We permanently turn off the following level 4 warnings because users will
// have to do so themselves anyway if we turn them back on
# pragma warning( disable: 4511 ) // copy constructor could not be generated
# pragma warning( disable: 4512 ) // assignment operator could not be generated
#endif
namespace boost
{
namespace statechart
{
namespace detail
{
//////////////////////////////////////////////////////////////////////////////
struct id_provider
{
const void * pCustomId_;
#if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
const std::type_info * pCustomIdType_;
#endif
};
template< class MostDerived >
struct id_holder
{
static id_provider idProvider_;
};
template< class MostDerived >
id_provider id_holder< MostDerived >::idProvider_;
//////////////////////////////////////////////////////////////////////////////
struct rtti_policy
{
#ifdef BOOST_STATECHART_USE_NATIVE_RTTI
class id_type
{
public:
////////////////////////////////////////////////////////////////////////
explicit id_type( const std::type_info & id ) : id_( id ) {}
bool operator==( id_type right ) const
{
return id_ == right.id_ != 0;
}
bool operator!=( id_type right ) const { return !( *this == right ); }
bool operator<( id_type right ) const
{
return id_.before( right.id_ ) != 0;
}
bool operator>( id_type right ) const { return right < *this; }
bool operator>=( id_type right ) const { return !( *this < right ); }
bool operator<=( id_type right ) const { return !( right < *this ); }
private:
////////////////////////////////////////////////////////////////////////
const std::type_info & id_;
};
typedef bool id_provider_type; // dummy
#else
typedef const void * id_type;
typedef const id_provider & id_provider_type;
#endif
////////////////////////////////////////////////////////////////////////////
template< class Base >
class rtti_base_type : public Base
{
public:
////////////////////////////////////////////////////////////////////////
typedef rtti_policy::id_type id_type;
id_type dynamic_type() const
{
#ifdef BOOST_STATECHART_USE_NATIVE_RTTI
return id_type( typeid( *this ) );
#else
return &idProvider_;
#endif
}
#ifndef BOOST_STATECHART_USE_NATIVE_RTTI
template< typename CustomId >
const CustomId * custom_dynamic_type_ptr() const
{
BOOST_ASSERT(
( idProvider_.pCustomId_ == 0 ) ||
( *idProvider_.pCustomIdType_ == typeid( CustomId ) ) );
return static_cast< const CustomId * >( idProvider_.pCustomId_ );
}
#endif
protected:
#ifdef BOOST_STATECHART_USE_NATIVE_RTTI
rtti_base_type( id_provider_type ) {}
////////////////////////////////////////////////////////////////////////
#if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT( 4 ) )
// We make the destructor virtual for GCC because with this compiler
// there is currently no way to disable the "has virtual functions but
// non-virtual destructor" warning on a class by class basis. Although
// it can be done on the compiler command line with
// -Wno-non-virtual-dtor, this is undesirable as this would also
// suppress legitimate warnings for types that are not states.
virtual ~rtti_base_type() {}
#else
~rtti_base_type() {}
#endif
private:
////////////////////////////////////////////////////////////////////////
// For typeid( *this ) to return a value that corresponds to the most-
// derived type, we need to have a vptr. Since this type does not
// contain any virtual functions we need to artificially declare one so.
virtual void dummy() {}
#else
rtti_base_type(
id_provider_type idProvider
) :
idProvider_( idProvider )
{
}
~rtti_base_type() {}
private:
////////////////////////////////////////////////////////////////////////
id_provider_type idProvider_;
#endif
};
////////////////////////////////////////////////////////////////////////////
template< class MostDerived, class Base >
class rtti_derived_type : public Base
{
public:
////////////////////////////////////////////////////////////////////////
static id_type static_type()
{
#ifdef BOOST_STATECHART_USE_NATIVE_RTTI
return id_type( typeid( const MostDerived ) );
#else
return &id_holder< MostDerived >::idProvider_;
#endif
}
#ifndef BOOST_STATECHART_USE_NATIVE_RTTI
template< class CustomId >
static const CustomId * custom_static_type_ptr()
{
BOOST_ASSERT(
( id_holder< MostDerived >::idProvider_.pCustomId_ == 0 ) ||
( *id_holder< MostDerived >::idProvider_.pCustomIdType_ ==
typeid( CustomId ) ) );
return static_cast< const CustomId * >(
id_holder< MostDerived >::idProvider_.pCustomId_ );
}
template< class CustomId >
static void custom_static_type_ptr( const CustomId * pCustomId )
{
#if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
id_holder< MostDerived >::idProvider_.pCustomIdType_ =
&typeid( CustomId );
#endif
id_holder< MostDerived >::idProvider_.pCustomId_ = pCustomId;
}
#endif
protected:
////////////////////////////////////////////////////////////////////////
~rtti_derived_type() {}
#ifdef BOOST_STATECHART_USE_NATIVE_RTTI
rtti_derived_type() : Base( false ) {}
#else
rtti_derived_type() : Base( id_holder< MostDerived >::idProvider_ ) {}
#endif
};
};
} // namespace detail
} // namespace statechart
} // namespace boost
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -