209 lines
6.3 KiB
C++
209 lines
6.3 KiB
C++
|
#ifndef BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
|
||
|
#define BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// Copyright 2002-2008 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
|
||
|
|
||
|
|
||
|
|
||
|
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
|