/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks is distributed in the hope that it will be
    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

#ifndef __TBB_exception_H
#define __TBB_exception_H

#include "tbb_stddef.h"

#if !TBB_USE_EXCEPTIONS && _MSC_VER
    // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
    #pragma warning (push)
    #pragma warning (disable: 4530)
#endif

#include <stdexcept>

#if !TBB_USE_EXCEPTIONS && _MSC_VER
    #pragma warning (pop)
#endif

#if __SUNPRO_CC
#include <string> // required to construct std exception classes
#endif

namespace tbb {

//! Exception for concurrent containers
class bad_last_alloc : public std::bad_alloc {
public:
    /*override*/ const char* what() const noexcept;
#if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN
    /*override*/ ~bad_last_alloc() noexcept {}
#endif
};

//! Exception for PPL locks
class improper_lock : public std::exception {
public:
    /*override*/ const char* what() const noexcept;
};

//! Exception for missing wait on structured_task_group
class missing_wait : public std::exception {
public:
    /*override*/ const char* what() const noexcept;
};

//! Exception for repeated scheduling of the same task_handle 
class invalid_multiple_scheduling : public std::exception {
public:
    /*override*/ const char* what() const noexcept;
};

namespace internal {
//! Obsolete
void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4();

enum exception_id {
    eid_bad_alloc = 1,
    eid_bad_last_alloc,
    eid_nonpositive_step,
    eid_out_of_range,
    eid_segment_range_error,
    eid_index_range_error,
    eid_missing_wait,
    eid_invalid_multiple_scheduling,
    eid_improper_lock,
    eid_possible_deadlock,
    eid_operation_not_permitted,
    eid_condvar_wait_failed,
    eid_invalid_load_factor,
    eid_invalid_buckets_number,
    eid_invalid_swap,
    eid_reservation_length_error,
    eid_invalid_key,
    //! The last enumerator tracks the number of defined IDs. It must remain the last one.
    /** When adding new IDs, place them immediately _before_ this comment (that is
        _after_ all the existing IDs. NEVER insert new IDs between the existing ones. **/
    eid_max
};

//! Gathers all throw operators in one place.
/** Its purpose is to minimize code bloat that can be caused by throw operators 
    scattered in multiple places, especially in templates. **/
void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id );

//! Versionless convenience wrapper for throw_exception_v4()
inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }

} // namespace internal
} // namespace tbb

#if __TBB_TASK_GROUP_CONTEXT
#include "tbb_allocator.h"
#include <exception>
#include <typeinfo>
#include <new>

namespace tbb {

//! Interface to be implemented by all exceptions TBB recognizes and propagates across the threads.
/** If an unhandled exception of the type derived from tbb::tbb_exception is intercepted
    by the TBB scheduler in one of the worker threads, it is delivered to and re-thrown in
    the root thread. The root thread is the thread that has started the outermost algorithm 
    or root task sharing the same task_group_context with the guilty algorithm/task (the one
    that threw the exception first).
    
    Note: when documentation mentions workers with respect to exception handling, 
    masters are implied as well, because they are completely equivalent in this context.
    Consequently a root thread can be master or worker thread. 

    NOTE: In case of nested algorithms or complex task hierarchies when the nested 
    levels share (explicitly or by means of implicit inheritance) the task group 
    context of the outermost level, the exception may be (re-)thrown multiple times 
    (ultimately - in each worker on each nesting level) before reaching the root 
    thread at the outermost level. IMPORTANT: if you intercept an exception derived 
    from this class on a nested level, you must re-throw it in the catch block by means
    of the "throw;" operator. 
    
    TBB provides two implementations of this interface: tbb::captured_exception and 
    template class tbb::movable_exception. See their declarations for more info. **/
class tbb_exception : public std::exception
{
    /** No operator new is provided because the TBB usage model assumes dynamic 
        creation of the TBB exception objects only by means of applying move()
        operation on an exception thrown out of TBB scheduler. **/
    void* operator new ( size_t );

public:
    //! Creates and returns pointer to the deep copy of this exception object. 
    /** Move semantics is allowed. **/
    virtual tbb_exception* move () noexcept = 0;
    
    //! Destroys objects created by the move() method.
    /** Frees memory and calls destructor for this exception object. 
        Can and must be used only on objects created by the move method. **/
    virtual void destroy () noexcept = 0;

    //! Throws this exception object.
    /** Make sure that if you have several levels of derivation from this interface
        you implement or override this method on the most derived level. The implementation 
        is as simple as "throw *this;". Failure to do this will result in exception 
        of a base class type being thrown. **/
    virtual void throw_self () = 0;

    //! Returns RTTI name of the originally intercepted exception
    virtual const char* name() const noexcept = 0;

    //! Returns the result of originally intercepted exception's what() method.
    virtual const char* what() const noexcept = 0;

    /** Operator delete is provided only to allow using existing smart pointers
        with TBB exception objects obtained as the result of applying move()
        operation on an exception thrown out of TBB scheduler. 
        
        When overriding method move() make sure to override operator delete as well
        if memory is allocated not by TBB's scalable allocator. **/
    void operator delete ( void* p ) {
        internal::deallocate_via_handler_v3(p);
    }
};

//! This class is used by TBB to propagate information about unhandled exceptions into the root thread.
/** Exception of this type is thrown by TBB in the root thread (thread that started a parallel 
    algorithm ) if an unhandled exception was intercepted during the algorithm execution in one 
    of the workers.
    \sa tbb::tbb_exception **/
class captured_exception : public tbb_exception
{
public:
    captured_exception ( const captured_exception& src )
        : tbb_exception(src), my_dynamic(false)
    {
        set(src.my_exception_name, src.my_exception_info);
    }

    captured_exception ( const char* name_, const char* info )
        : my_dynamic(false)
    {
        set(name_, info);
    }

    __TBB_EXPORTED_METHOD ~captured_exception () noexcept {
        clear();
    }

    captured_exception& operator= ( const captured_exception& src ) {
        if ( this != &src ) {
            clear();
            set(src.my_exception_name, src.my_exception_info);
        }
        return *this;
    }

    /*override*/ 
    captured_exception* __TBB_EXPORTED_METHOD move () noexcept;

    /*override*/ 
    void __TBB_EXPORTED_METHOD destroy () noexcept;

    /*override*/ 
    void throw_self () { __TBB_THROW(*this); }

    /*override*/ 
    const char* __TBB_EXPORTED_METHOD name() const noexcept;

    /*override*/ 
    const char* __TBB_EXPORTED_METHOD what() const noexcept;

    void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) noexcept;
    void __TBB_EXPORTED_METHOD clear () noexcept;

private:
    //! Used only by method clone().  
    captured_exception() {}

    //! Functionally equivalent to {captured_exception e(name,info); return e.clone();}
    static captured_exception* allocate ( const char* name, const char* info );

    bool my_dynamic;
    const char* my_exception_name;
    const char* my_exception_info;
};

//! Template that can be used to implement exception that transfers arbitrary ExceptionData to the root thread
/** Code using TBB can instantiate this template with an arbitrary ExceptionData type 
    and throw this exception object. Such exceptions are intercepted by the TBB scheduler
    and delivered to the root thread (). 
    \sa tbb::tbb_exception **/
template<typename ExceptionData>
class movable_exception : public tbb_exception
{
    typedef movable_exception<ExceptionData> self_type;

public:
    movable_exception ( const ExceptionData& data_ ) 
        : my_exception_data(data_)
        , my_dynamic(false)
        , my_exception_name(
#if TBB_USE_EXCEPTIONS
        typeid(self_type).name()
#else /* !TBB_USE_EXCEPTIONS */
        "movable_exception"
#endif /* !TBB_USE_EXCEPTIONS */
        )
    {}

    movable_exception ( const movable_exception& src ) throw () 
        : tbb_exception(src)
        , my_exception_data(src.my_exception_data)
        , my_dynamic(false)
        , my_exception_name(src.my_exception_name)
    {}

    ~movable_exception () noexcept {}

    const movable_exception& operator= ( const movable_exception& src ) {
        if ( this != &src ) {
            my_exception_data = src.my_exception_data;
            my_exception_name = src.my_exception_name;
        }
        return *this;
    }

    ExceptionData& data () noexcept { return my_exception_data; }

    const ExceptionData& data () const noexcept { return my_exception_data; }

    /*override*/ const char* name () const noexcept { return my_exception_name; }

    /*override*/ const char* what () const noexcept { return "tbb::movable_exception"; }

    /*override*/ 
    movable_exception* move () noexcept {
        void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
        if ( e ) {
            ::new (e) movable_exception(*this);
            ((movable_exception*)e)->my_dynamic = true;
        }
        return (movable_exception*)e;
    }
    /*override*/ 
    void destroy () noexcept {
        __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
        if ( my_dynamic ) {
            this->~movable_exception();
            internal::deallocate_via_handler_v3(this);
        }
    }
    /*override*/ 
    void throw_self () { __TBB_THROW( *this ); }

protected:
    //! User data
    ExceptionData  my_exception_data;

private:
    //! Flag specifying whether this object has been dynamically allocated (by the move method)
    bool my_dynamic;

    //! RTTI name of this class
    /** We rely on the fact that RTTI names are static string constants. **/
    const char* my_exception_name;
};

#if !TBB_USE_CAPTURED_EXCEPTION
namespace internal {

//! Exception container that preserves the exact copy of the original exception
/** This class can be used only when the appropriate runtime support (mandated 
    by C++0x) is present **/
class tbb_exception_ptr {
    std::exception_ptr  my_ptr;

public:
    static tbb_exception_ptr* allocate ();
    static tbb_exception_ptr* allocate ( const tbb_exception& tag );
    //! This overload uses move semantics (i.e. it empties src)
    static tbb_exception_ptr* allocate ( captured_exception& src );
    
    //! Destroys this objects
    /** Note that objects of this type can be created only by the allocate() method. **/
    void destroy () noexcept;

    //! Throws the contained exception .
    void throw_self () { std::rethrow_exception(my_ptr); }

private:
    tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
    tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
}; // class tbb::internal::tbb_exception_ptr

} // namespace internal
#endif /* !TBB_USE_CAPTURED_EXCEPTION */

} // namespace tbb

#endif /* __TBB_TASK_GROUP_CONTEXT */

#endif /* __TBB_exception_H */
