// -*- C++ -*-
//===-------------------------- exception ---------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_EXCEPTION
#define _LIBCPP_EXCEPTION

/*
    exception synopsis

namespace std
{

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

class bad_exception
    : public exception
{
public:
    bad_exception() throw();
    bad_exception(const bad_exception&) throw();
    bad_exception& operator=(const bad_exception&) throw();
    virtual ~bad_exception() throw();
    virtual const char* what() const throw();
};

typedef void (*unexpected_handler)();
unexpected_handler set_unexpected(unexpected_handler  f ) throw();
void unexpected [[noreturn]] ();

typedef void (*terminate_handler)();
terminate_handler set_terminate(terminate_handler  f ) throw();
void terminate [[noreturn]] ();

bool uncaught_exception() throw();

typedef unspecified exception_ptr;

exception_ptr current_exception();
void rethrow_exception [[noreturn]] (exception_ptr p);
template<class E> exception_ptr make_exception_ptr(E e);

class nested_exception
{
public:
    nested_exception() throw();
    nested_exception(const nested_exception&) throw() = default;
    nested_exception& operator=(const nested_exception&) throw() = default;
    virtual ~nested_exception() = default;

    // access functions
    void rethrow_nested [[noreturn]] () const;
    exception_ptr nested_ptr() const;
};

template <class T> void throw_with_nested [[noreturn]] (T&& t);
template <class E> void rethrow_if_nested(const E& e);

}  // std

*/

#include <__config>
#include <cstddef>
#include <type_traits>

#pragma GCC system_header

namespace std  // purposefully not using versioning namespace
{

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

class _LIBCPP_EXCEPTION_ABI bad_exception
    : public exception
{
public:
    _LIBCPP_INLINE_VISIBILITY bad_exception() throw() {}
    virtual ~bad_exception() throw();
    virtual const char* what() const throw();
};

typedef void (*unexpected_handler)();
_LIBCPP_VISIBLE unexpected_handler set_unexpected(unexpected_handler) throw();
_LIBCPP_VISIBLE void unexpected();

typedef void (*terminate_handler)();
_LIBCPP_VISIBLE terminate_handler set_terminate(terminate_handler) throw();
_LIBCPP_VISIBLE void terminate() __attribute__((__noreturn__));

_LIBCPP_VISIBLE bool uncaught_exception() throw();

class exception_ptr;

exception_ptr current_exception();
void rethrow_exception(exception_ptr);  // noreturn

class exception_ptr
{
    void* __ptr_;
public:
    exception_ptr()  : __ptr_() {}
    exception_ptr(nullptr_t) : __ptr_() {}
    exception_ptr(const exception_ptr&);
    exception_ptr& operator=(const exception_ptr&);
    ~exception_ptr();

    // explicit
        operator bool() const {return __ptr_ != nullptr;}

    friend bool operator==(const exception_ptr& __x, const exception_ptr& __y)
        {return __x.__ptr_ == __y.__ptr_;}
    friend bool operator!=(const exception_ptr& __x, const exception_ptr& __y)
        {return !(__x == __y);}

    friend exception_ptr current_exception();
    friend void rethrow_exception(exception_ptr);  // noreturn
};

template<class _E>
exception_ptr
make_exception_ptr(_E __e)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    try
    {
        throw __e;
    }
    catch (...)
    {
        return current_exception();
    }
#endif  // _LIBCPP_NO_EXCEPTIONS
}

// nested_exception

class _LIBCPP_EXCEPTION_ABI nested_exception
{
    exception_ptr __ptr_;
public:
    nested_exception();
//     nested_exception(const nested_exception&) throw() = default;
//     nested_exception& operator=(const nested_exception&) throw() = default;
    virtual ~nested_exception();

    // access functions
    void rethrow_nested /*[[noreturn]]*/ () const;
    exception_ptr nested_ptr() const {return __ptr_;}
};

template <class _Tp>
struct __nested
    : public _Tp,
      public nested_exception
{
    explicit __nested(const _Tp& __t) : _Tp(__t) {}
};

template <class _Tp>
void
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
throw_with_nested /*[[noreturn]]*/ (_Tp&& __t, typename enable_if<
                  is_class<typename remove_reference<_Tp>::type>::value &&
                  !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
                                    >::type* = 0)
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
throw_with_nested (_Tp& __t, typename enable_if<
                  is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value
                                    >::type* = 0)
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    throw __nested<typename remove_reference<_Tp>::type>(_STD::forward<_Tp>(__t));
#endif
}

template <class _Tp>
void
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
throw_with_nested /*[[noreturn]]*/ (_Tp&& __t, typename enable_if<
                  !is_class<typename remove_reference<_Tp>::type>::value ||
                  is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
                                    >::type* = 0)
#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
throw_with_nested (_Tp& __t, typename enable_if<
                  !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value
                                    >::type* = 0)
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    throw _STD::forward<_Tp>(__t);
#endif
}

template <class _E>
inline
void
rethrow_if_nested(const _E& __e, typename enable_if<
                                   is_polymorphic<_E>::value
                                                   >::type* = 0)
{
    const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e);
    if (__nep)
        __nep->rethrow_nested();
}

template <class _E>
inline
void
rethrow_if_nested(const _E& __e, typename enable_if<
                                   !is_polymorphic<_E>::value
                                                   >::type* = 0)
{
}

}  // std

#endif  // _LIBCPP_EXCEPTION
