//-----------------------------------------------------------------------------

// boost variant/detail/forced_return.hpp header file

// See http://www.boost.org for updates, documentation, and revision history.

//-----------------------------------------------------------------------------

//

// Copyright (c) 2003

// Eric Friedman

//

// Distributed under the Boost Software License, Version 1.0. (See

// accompanying file LICENSE_1_0.txt or copy at

// http://www.boost.org/LICENSE_1_0.txt)



#ifndef BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP

#define BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP



#include "boost/config.hpp"

#include "boost/variant/detail/generic_result_type.hpp"

#include "boost/assert.hpp"



#if !defined(BOOST_MSVC) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

#   include "boost/type_traits/remove_reference.hpp"

#endif



namespace boost {

namespace detail { namespace variant {



///////////////////////////////////////////////////////////////////////////////

// (detail) function template forced_return

//

// Logical error to permit invocation at runtime, but (artificially) satisfies

// compile-time requirement of returning a result value.

//



#if !defined(BOOST_MSVC)                                \

 && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)  \

 && !defined(BOOST_NO_VOID_RETURNS)



// "standard" implementation:



template <typename T>

inline T forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )

{

    // logical error: should never be here! (see above)

    BOOST_ASSERT(false);



    typedef typename boost::remove_reference<T>::type basic_type;

    basic_type* dummy = 0;

    return *static_cast< basic_type* >(dummy);

}



template <>

inline void forced_return<void>( BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(void) )

{

    // logical error: should never be here! (see above)

    BOOST_ASSERT(false);

}



#elif !defined(BOOST_MSVC)



// workaround implementation

//

// TODO: Determine the most efficient way to handle this -- as below? by

// throwing? by recursive call to forced_return itself? etc.

//



template <typename T>

inline

    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)

forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )

{

    // logical error: should never be here! (see above)

    BOOST_ASSERT(false);



    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T) (*dummy)() = 0;

    return dummy();

}



#else // defined(BOOST_MSVC)



// msvc-specific implementation

//

// Leverages __declspec(noreturn) for optimized implementation.

//



__declspec(noreturn)

inline void forced_return_no_return() {};



template <typename T>

inline

    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)

forced_return( BOOST_EXPLICIT_TEMPLATE_TYPE(T) )

{

    // logical error: should never be here! (see above)

    BOOST_ASSERT(false);



    forced_return_no_return();

}



#endif // BOOST_MSVC optimization



}} // namespace detail::variant

} // namespace boost



#endif // BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP

