/***
*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)

 #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
		const char *_Keyval = name();
		size_t _Val = 2166136261U;
		size_t _First = 0;
		size_t _Last = _CSTD strlen(_Keyval);
		size_t _Stride = 1 + _Last / 10;

		for(; _First < _Last; _First += _Stride)
			_Val = 16777619U * _Val ^ (size_t)_Keyval[_First];
		return (_Val);
		}
 #endif /* _HAS_CPP0X */

#if defined(CRTDLL)
    _CRTIMP_PURE
#endif
    #ifdef _M_CEE
    [System::Security::SecurityCritical]
    #endif
    virtual ~type_info();
#if defined(_SYSCRT)
    _CRTIMP_PURE int __CLR_OR_THIS_CALL operator==(const type_info& _Rhs) const;
    _CRTIMP_PURE int __CLR_OR_THIS_CALL operator!=(const type_info& _Rhs) const;
#else
    _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;
#endif
    _CRTIMP_PURE int __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 *);
#ifndef _INTERNAL_IFSTRIP_
#if defined(_CRTBLD)
#if !defined(_SYSCRT)
    _CRTIMP_PURE static const char *__CLRCALL_OR_CDECL _Name_base_internal(const type_info *,__type_info_node* __ptype_info_node);
    _CRTIMP_PURE static void __CLRCALL_OR_CDECL _Type_info_dtor_internal(type_info *);

public:
    // CRT dll import libs alias non _internal to _internal. These method defintions are
    // only used within the crtdll to provide targets for aliasobj in the crt import lib.
    _CRTIMP_PURE void __CLR_OR_THIS_CALL _type_info_dtor_internal_method(void);
    _CRTIMP_PURE const char* __CLR_OR_THIS_CALL _name_internal_method(__type_info_node* __ptype_info_node) const;
#endif
#endif
#endif
};

 #if _HAS_EXCEPTIONS

 _STD_BEGIN

using ::type_info;

 _STD_END

#ifndef _TICORE

// 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()
    {}
#ifndef _INTERNAL_IFSTRIP_
#ifdef  CRTDLL
private:
    // This is aliased to public:bad_cast(const char * const &) to provide
    // the old, non-conformant constructor.
    __CLR_OR_THIS_CALL bad_cast(const char * const * _Message)
        : exception((const char *)_Message)
    { }
#endif  /* CRTDLL */
#endif  /* _INTERNAL_IFSTRIP_ */
#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();
#ifndef _INTERNAL_IFSTRIP_
#ifdef  CRTDLL
private:
    // This is aliased to public:bad_cast(const char * const &) to provide
    // the old, non-conformant constructor.
    __CLR_OR_THIS_CALL bad_cast(const char * const * _Message);
#endif  /* CRTDLL */
#endif  /* _INTERNAL_IFSTRIP_ */
#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()
    {}
#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();
#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()
    {}
#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();
#endif /* _M_CEE_PURE */
};

 _STD_END
 
#endif  //!_TICORE

 #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() _THROW0()
		{	// 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() _THROW0()
		{	// 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 pack(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.
 */
