// -*- C++ -*-
//===-------------------------- typeinfo ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef __LIBCPP_TYPEINFO
#define __LIBCPP_TYPEINFO

/*

    typeinfo synopsis

namespace std {

class type_info
{
public:
    virtual ~type_info();

    bool operator==(const type_info& rhs) const noexcept;
    bool operator!=(const type_info& rhs) const noexcept;

    bool before(const type_info& rhs) const noexcept;
    size_t hash_code() const noexcept;
    const char* name() const noexcept;

    type_info(const type_info& rhs) = delete;
    type_info& operator=(const type_info& rhs) = delete;
};

class bad_cast
    : public exception
{
public:
    bad_cast() noexcept;
    bad_cast(const bad_cast&) noexcept;
    bad_cast& operator=(const bad_cast&) noexcept;
    virtual const char* what() const noexcept;
};

class bad_typeid
    : public exception
{
public:
    bad_typeid() noexcept;
    bad_typeid(const bad_typeid&) noexcept;
    bad_typeid& operator=(const bad_typeid&) noexcept;
    virtual const char* what() const noexcept;
};

}  // std

*/

#include <__config>
#include <exception>
#include <cstddef>
#include <cstdint>
#ifdef _LIBCPP_NO_EXCEPTIONS
#include <cstdlib>
#endif

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)
#include <vcruntime_typeinfo.h>
#else

#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) && !defined(_LIBCPP_ABI_MICROSOFT)
#   define _LIBCPP_HAS_NONUNIQUE_TYPEINFO
#endif

namespace std  // purposefully not using versioning namespace
{

#if defined(_LIBCPP_ABI_MICROSOFT)

class _LIBCPP_EXCEPTION_ABI type_info
{
    type_info& operator=(const type_info&);
    type_info(const type_info&);

    mutable struct {
      const char *__undecorated_name;
      const char __decorated_name[1];
    } __data;

    int __compare(const type_info &__rhs) const _NOEXCEPT;

public:
    _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
    virtual ~type_info();

    const char *name() const _NOEXCEPT;

    _LIBCPP_INLINE_VISIBILITY
    bool before(const type_info& __arg) const _NOEXCEPT {
      return __compare(__arg) < 0;
    }

    size_t hash_code() const _NOEXCEPT;

    _LIBCPP_INLINE_VISIBILITY
    bool operator==(const type_info& __arg) const _NOEXCEPT {
      return __compare(__arg) == 0;
    }

    _LIBCPP_INLINE_VISIBILITY
    bool operator!=(const type_info& __arg) const _NOEXCEPT
    { return !operator==(__arg); }
};

#elif defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO)

// This implementation of type_info does not assume always a unique copy of
// the RTTI for a given type inside a program. It packs the pointer to the
// type name into a uintptr_t and reserves the high bit of that pointer (which
// is assumed to be free for use under the ABI in use) to represent whether
// that specific copy of the RTTI can be assumed unique inside the program.
// To implement equality-comparison of type_infos, we check whether BOTH
// type_infos are guaranteed unique, and if so, we simply compare the addresses
// of their type names instead of doing a deep string comparison, which is
// faster. If at least one of the type_infos can't guarantee uniqueness, we
// have no choice but to fall back to a deep string comparison.
//
// Note that the compiler is the one setting (or unsetting) the high bit of
// the pointer when it constructs the type_info, depending on whether it can
// guarantee uniqueness for that specific type_info.
class _LIBCPP_EXCEPTION_ABI type_info
{
    type_info& operator=(const type_info&);
    type_info(const type_info&);

    _LIBCPP_INLINE_VISIBILITY
    int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
    { return __builtin_strcmp(name(), __arg.name()); }

protected:
    uintptr_t __type_name;

    _LIBCPP_INLINE_VISIBILITY
    explicit type_info(const char* __n)
      : __type_name(reinterpret_cast<uintptr_t>(__n)) {}

public:
    _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
    virtual ~type_info();

    _LIBCPP_INLINE_VISIBILITY
    const char* name() const _NOEXCEPT
    {
      return reinterpret_cast<const char*>(__type_name &
                                           ~_LIBCPP_NONUNIQUE_RTTI_BIT);
    }

    _LIBCPP_INLINE_VISIBILITY
    bool before(const type_info& __arg) const _NOEXCEPT
    {
      if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
        return __type_name < __arg.__type_name;
      return __compare_nonunique_names(__arg) < 0;
    }

    _LIBCPP_INLINE_VISIBILITY
    size_t hash_code() const _NOEXCEPT
    {
      if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT))
        return __type_name;

      const char* __ptr = name();
      size_t __hash = 5381;
      while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
        __hash = (__hash * 33) ^ __c;
      return __hash;
    }

    _LIBCPP_INLINE_VISIBILITY
    bool operator==(const type_info& __arg) const _NOEXCEPT
    {
      if (__type_name == __arg.__type_name)
        return true;

      if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
        return false;
      return __compare_nonunique_names(__arg) == 0;
    }

    _LIBCPP_INLINE_VISIBILITY
    bool operator!=(const type_info& __arg) const _NOEXCEPT
    { return !operator==(__arg); }
};

#else // !_LIBCPP_ABI_MICROSOFT && !_LIBCPP_HAS_NONUNIQUE_TYPEINFO

// This implementation of type_info assumes a unique copy of the RTTI for a
// given type inside a program. This is a valid assumption when abiding to
// Itanium ABI (http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-components).
// Under this assumption, we can always compare the addresses of the type names
// to implement equality-comparison of type_infos instead of having to perform
// a deep string comparison.
class _LIBCPP_EXCEPTION_ABI type_info
{
    type_info& operator=(const type_info&);
    type_info(const type_info&);

protected:
    const char *__type_name;

    _LIBCPP_INLINE_VISIBILITY
    explicit type_info(const char* __n) : __type_name(__n) {}

public:
    _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
    virtual ~type_info();

    _LIBCPP_INLINE_VISIBILITY
    const char* name() const _NOEXCEPT
    { return __type_name; }

    _LIBCPP_INLINE_VISIBILITY
    bool before(const type_info& __arg) const _NOEXCEPT
    { return __type_name < __arg.__type_name; }

    _LIBCPP_INLINE_VISIBILITY
    size_t hash_code() const _NOEXCEPT
    { return reinterpret_cast<size_t>(__type_name); }

    _LIBCPP_INLINE_VISIBILITY
    bool operator==(const type_info& __arg) const _NOEXCEPT
    { return __type_name == __arg.__type_name; }

    _LIBCPP_INLINE_VISIBILITY
    bool operator!=(const type_info& __arg) const _NOEXCEPT
    { return !operator==(__arg); }
};

#endif

class _LIBCPP_EXCEPTION_ABI bad_cast
    : public exception
{
public:
    bad_cast() _NOEXCEPT;
    virtual ~bad_cast() _NOEXCEPT;
    virtual const char* what() const _NOEXCEPT;
};

class _LIBCPP_EXCEPTION_ABI bad_typeid
    : public exception
{
public:
    bad_typeid() _NOEXCEPT;
    virtual ~bad_typeid() _NOEXCEPT;
    virtual const char* what() const _NOEXCEPT;
};

}  // std

#endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME)

_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
void __throw_bad_cast()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    throw bad_cast();
#else
    _VSTD::abort();
#endif
}
_LIBCPP_END_NAMESPACE_STD

#endif  // __LIBCPP_TYPEINFO
