#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
