// typeinfo standard header

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#pragma once

#ifndef _TYPEINFO_
#define _TYPEINFO_
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR
#include <exception>

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

#pragma warning(disable : 4275) // non dll-interface class 'X' used as base for dll-interface class 'Y'

#include <vcruntime_typeinfo.h>

_EXPORT_STD extern "C++" class type_info; // for typeid, MSVC looks for type_info in the global namespace

_STD_BEGIN

// size in pointers of std::function and std::any (roughly 3 pointers larger than std::string when building debug)
_INLINE_VAR constexpr int _Small_object_num_ptrs = 6 + 16 / sizeof(void*);

_EXPORT_STD using ::type_info;

#if _HAS_EXCEPTIONS
_EXPORT_STD class bad_cast;
_EXPORT_STD class bad_typeid;
#else // ^^^ _HAS_EXCEPTIONS / !_HAS_EXCEPTIONS vvv
_EXPORT_STD class bad_cast : public exception { // base of all bad cast exceptions
public:
    bad_cast(const char* _Message = "bad cast") noexcept : exception(_Message) {}

    ~bad_cast() noexcept override {}

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

_EXPORT_STD class bad_typeid : public exception { // base of all bad typeid exceptions
public:
    bad_typeid(const char* _Message = "bad typeid") noexcept : exception(_Message) {}

    ~bad_typeid() noexcept override {}

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

class __non_rtti_object : public bad_typeid { // report a non-RTTI object
public:
    __non_rtti_object(const char* _Message) : bad_typeid(_Message) {}
};
#endif // !_HAS_EXCEPTIONS

[[noreturn]] inline void _Throw_bad_cast() {
    _THROW(bad_cast{});
}

_STD_END

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma pack(pop)
#pragma warning(pop)
#endif // _STL_COMPILER_PREPROCESSOR
#endif // _TYPEINFO_
