/***
*typeinfo.h - Defines the type_info structure and exceptions used for RTTI
*
*	Copyright (c) Microsoft Corporation. All rights reserved.
*	Modified January 1996 by P.J. Plauger
*
*Purpose:
*       Defines the type_info structure and exceptions used for
*       Runtime Type Identification.
*
*       [Public]
*
****/

#pragma once

#ifndef _TYPEINFO_
#define _TYPEINFO_
#ifndef RC_INVOKED
#include <xstddef>

 #if _HAS_CPP0X
 #include <string.h>	// for type_info::hash_code()
 #endif /* _HAS_CPP0X */

#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
#pragma push_macro("new")
#undef new
#pragma warning(disable: 4275)

 #ifndef __cplusplus
  #error This header requires a C++ compiler ...
 #endif

 #if !defined(_WIN32)
  #error ERROR: Only Win32 target supported!
 #endif

struct __type_info_node {
    void *_MemPtr;
    __type_info_node* _Next;
};

extern __type_info_node __type_info_root_node;

class type_info {
public:
 #if _HAS_CPP0X
	size_t hash_code() const _THROW0()
		{	// hash name() to size_t value by pseudorandomizing transform
		return (_STD _Hash_seq((const unsigned char *) name(),
			_CSTD strlen(name())));
		}
 #endif /* _HAS_CPP0X */

    #ifdef _M_CEE
    [System::Security::SecurityCritical]
    #endif
    virtual ~type_info() _NOEXCEPT;
    _CRTIMP_PURE bool __CLR_OR_THIS_CALL operator==(const type_info& _Rhs) const;
    _CRTIMP_PURE bool __CLR_OR_THIS_CALL operator!=(const type_info& _Rhs) const;
    _CRTIMP_PURE bool __CLR_OR_THIS_CALL before(const type_info& _Rhs) const;
    _CRTIMP_PURE const char* __CLR_OR_THIS_CALL name(__type_info_node* __ptype_info_node = &__type_info_root_node) const;
    _CRTIMP_PURE const char* __CLR_OR_THIS_CALL raw_name() const;
private:
    void *_M_data;
    char _M_d_name[1];
    __CLR_OR_THIS_CALL type_info(const type_info& _Rhs);
    type_info& __CLR_OR_THIS_CALL operator=(const type_info& _Rhs);
    _CRTIMP_PURE static const char *__CLRCALL_OR_CDECL _Name_base(const type_info *,__type_info_node* __ptype_info_node);
    _CRTIMP_PURE static void __CLRCALL_OR_CDECL _Type_info_dtor(type_info *);
};

 #if _HAS_EXCEPTIONS

 _STD_BEGIN

using ::type_info;

 _STD_END


// This include must occur below the definition of class type_info
#include <exception>

 _STD_BEGIN

class _CRTIMP_PURE bad_cast : public exception {
public:
#ifdef _M_CEE_PURE
    __CLR_OR_THIS_CALL bad_cast(const char * _Message = "bad cast")
        : exception(_Message)
    {}
    __CLR_OR_THIS_CALL bad_cast(const bad_cast &_That)
        : exception(_That)
    {}
    virtual __CLR_OR_THIS_CALL ~bad_cast() _NOEXCEPT
    {}
#else   /* _M_CEE_PURE */
    __CLR_OR_THIS_CALL bad_cast(const char * _Message = "bad cast");
    __CLR_OR_THIS_CALL bad_cast(const bad_cast &);
    virtual __CLR_OR_THIS_CALL ~bad_cast() _NOEXCEPT;
#endif  /* _M_CEE_PURE */
};

class _CRTIMP_PURE bad_typeid : public exception {
public:
#ifdef _M_CEE_PURE
    __CLR_OR_THIS_CALL bad_typeid(const char * _Message = "bad typeid")
        : exception(_Message)
    {}
    __CLR_OR_THIS_CALL bad_typeid(const bad_typeid &_That)
        : exception(_That)
    {}
    virtual __CLR_OR_THIS_CALL ~bad_typeid() _NOEXCEPT
    {}
#else  /* _M_CEE_PURE */
    __CLR_OR_THIS_CALL bad_typeid(const char * _Message = "bad typeid");
    __CLR_OR_THIS_CALL bad_typeid(const bad_typeid &);
    virtual __CLR_OR_THIS_CALL ~bad_typeid() _NOEXCEPT;
#endif /* _M_CEE_PURE */

};

class _CRTIMP_PURE __non_rtti_object : public bad_typeid {
public:
#ifdef _M_CEE_PURE
    __CLR_OR_THIS_CALL __non_rtti_object(const char * _Message)
        : bad_typeid(_Message)
    {}
    __CLR_OR_THIS_CALL __non_rtti_object(const __non_rtti_object &_That)
        : bad_typeid(_That)
    {}
    virtual __CLR_OR_THIS_CALL ~__non_rtti_object() _NOEXCEPT
    {}
#else  /* _M_CEE_PURE */
    __CLR_OR_THIS_CALL __non_rtti_object(const char * _Message);
    __CLR_OR_THIS_CALL __non_rtti_object(const __non_rtti_object &);
    virtual __CLR_OR_THIS_CALL ~__non_rtti_object() _NOEXCEPT;
#endif /* _M_CEE_PURE */
};

 _STD_END

 #else

 _STD_BEGIN

		// CLASS bad_cast
class _CRTIMP2 bad_cast
	: public exception
	{	// base of all bad cast exceptions
public:
	bad_cast(const char *_Message = "bad cast") _THROW0()
		: exception(_Message)
		{	// construct from message string
		}

	virtual ~bad_cast() _NOEXCEPT
		{	// destroy the object
		}

protected:
	virtual void _Doraise() const
		{	// perform class-specific exception handling
		_RAISE(*this);
		}
	};

		// CLASS bad_typeid
class _CRTIMP2 bad_typeid
	: public exception
	{	// base of all bad typeid exceptions
public:
	bad_typeid(const char *_Message = "bad typeid") _THROW0()
		: exception(_Message)
		{	// construct from message string
		}

	virtual ~bad_typeid() _NOEXCEPT
		{	// destroy the object
		}

protected:
	virtual void _Doraise() const
		{	// perform class-specific exception handling
		_RAISE(*this);
		}
	};

class _CRTIMP2 __non_rtti_object
	: public bad_typeid
	{	// report a non RTTI object
public:
    __non_rtti_object(const char *_Message)
		: bad_typeid(_Message)
		{	// construct from message string
		}
	};
 _STD_END
 #endif /* _HAS_EXCEPTIONS */

#endif /* RC_INVOKED */

#pragma pop_macro("new")
#pragma pack(pop)
#pragma warning(pop)

#endif // _TYPEINFO_

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Modified January 1996 by P.J. Plauger
 * Modified November 1998 by P.J. Plauger
 * Consult your license regarding permissions and restrictions.
 */
