mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-06 07:27:50 +00:00
Added thirdparty: boost library
This commit is contained in:
+283
@@ -0,0 +1,283 @@
|
||||
#ifndef BOOST_LEAF_EXCEPTION_HPP_INCLUDED
|
||||
#define BOOST_LEAF_EXCEPTION_HPP_INCLUDED
|
||||
|
||||
// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc.
|
||||
|
||||
// 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)
|
||||
|
||||
#include <boost/leaf/config.hpp>
|
||||
#include <boost/leaf/error.hpp>
|
||||
#include <exception>
|
||||
|
||||
#ifdef BOOST_LEAF_NO_EXCEPTIONS
|
||||
|
||||
namespace boost
|
||||
{
|
||||
[[noreturn]] void throw_exception( std::exception const & ); // user defined
|
||||
}
|
||||
|
||||
namespace boost { namespace leaf {
|
||||
|
||||
namespace leaf_detail
|
||||
{
|
||||
template <class T>
|
||||
[[noreturn]] void throw_exception_impl( T && e )
|
||||
{
|
||||
::boost::throw_exception(std::move(e));
|
||||
}
|
||||
|
||||
class BOOST_LEAF_SYMBOL_VISIBLE exception_base
|
||||
{
|
||||
public:
|
||||
|
||||
virtual error_id get_error_id() const noexcept = 0;
|
||||
|
||||
protected:
|
||||
|
||||
exception_base() noexcept { }
|
||||
~exception_base() noexcept { }
|
||||
};
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#else
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace boost { namespace leaf {
|
||||
|
||||
namespace leaf_detail
|
||||
{
|
||||
template <class T>
|
||||
[[noreturn]] void throw_exception_impl( T && e )
|
||||
{
|
||||
throw std::move(e);
|
||||
}
|
||||
|
||||
class BOOST_LEAF_SYMBOL_VISIBLE exception_base
|
||||
{
|
||||
std::shared_ptr<void const> auto_id_bump_;
|
||||
|
||||
public:
|
||||
|
||||
virtual error_id get_error_id() const noexcept = 0;
|
||||
|
||||
protected:
|
||||
|
||||
exception_base():
|
||||
auto_id_bump_(nullptr, [](void const *) { (void) new_id(); })
|
||||
{
|
||||
}
|
||||
|
||||
~exception_base() noexcept { }
|
||||
};
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
#define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::leaf_detail::make_exception
|
||||
|
||||
namespace boost { namespace leaf {
|
||||
|
||||
namespace leaf_detail
|
||||
{
|
||||
struct throw_with_loc
|
||||
{
|
||||
char const * const file;
|
||||
int const line;
|
||||
char const * const fn;
|
||||
|
||||
template <class Ex>
|
||||
[[noreturn]] friend void operator+( throw_with_loc loc, Ex && ex )
|
||||
{
|
||||
ex.load_source_location_(loc.file, loc.line, loc.fn);
|
||||
::boost::leaf::leaf_detail::throw_exception_impl(std::move(ex));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
namespace boost { namespace leaf {
|
||||
|
||||
namespace leaf_detail
|
||||
{
|
||||
inline void enforce_std_exception( std::exception const & ) noexcept { }
|
||||
|
||||
template <class Ex>
|
||||
class BOOST_LEAF_SYMBOL_VISIBLE exception:
|
||||
public Ex,
|
||||
public exception_base,
|
||||
public error_id
|
||||
{
|
||||
error_id get_error_id() const noexcept final override
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
exception( exception const & ) = default;
|
||||
exception( exception && ) = default;
|
||||
|
||||
BOOST_LEAF_CONSTEXPR exception( error_id id, Ex const & ex ) noexcept:
|
||||
Ex(ex),
|
||||
error_id(id)
|
||||
{
|
||||
enforce_std_exception(*this);
|
||||
}
|
||||
|
||||
BOOST_LEAF_CONSTEXPR exception( error_id id, Ex && ex ) noexcept:
|
||||
Ex(std::move(ex)),
|
||||
error_id(id)
|
||||
{
|
||||
enforce_std_exception(*this);
|
||||
}
|
||||
|
||||
explicit BOOST_LEAF_CONSTEXPR exception( error_id id ) noexcept:
|
||||
error_id(id)
|
||||
{
|
||||
enforce_std_exception(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template <class... T>
|
||||
struct at_least_one_derives_from_std_exception;
|
||||
|
||||
template <>
|
||||
struct at_least_one_derives_from_std_exception<>: std::false_type { };
|
||||
|
||||
template <class T, class... Rest>
|
||||
struct at_least_one_derives_from_std_exception<T, Rest...>
|
||||
{
|
||||
constexpr static const bool value = std::is_base_of<std::exception,typename std::remove_reference<T>::type>::value || at_least_one_derives_from_std_exception<Rest...>::value;
|
||||
};
|
||||
|
||||
template <class Ex, class... E>
|
||||
inline
|
||||
typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, exception<typename std::remove_reference<Ex>::type>>::type
|
||||
make_exception( error_id err, Ex && ex, E && ... e ) noexcept
|
||||
{
|
||||
static_assert(!at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
|
||||
return exception<typename std::remove_reference<Ex>::type>( err.load(std::forward<E>(e)...), std::forward<Ex>(ex) );
|
||||
}
|
||||
|
||||
template <class E1, class... E>
|
||||
inline
|
||||
typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1>::type>::value, exception<std::exception>>::type
|
||||
make_exception( error_id err, E1 && car, E && ... cdr ) noexcept
|
||||
{
|
||||
static_assert(!at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
|
||||
return exception<std::exception>( err.load(std::forward<E1>(car), std::forward<E>(cdr)...) );
|
||||
}
|
||||
|
||||
inline exception<std::exception> make_exception( error_id err ) noexcept
|
||||
{
|
||||
return exception<std::exception>(err);
|
||||
}
|
||||
|
||||
template <class Ex, class... E>
|
||||
inline
|
||||
typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, exception<typename std::remove_reference<Ex>::type>>::type
|
||||
make_exception( Ex && ex, E && ... e ) noexcept
|
||||
{
|
||||
static_assert(!at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
|
||||
return exception<typename std::remove_reference<Ex>::type>( new_error().load(std::forward<E>(e)...), std::forward<Ex>(ex) );
|
||||
}
|
||||
|
||||
template <class E1, class... E>
|
||||
inline
|
||||
typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1>::type>::value, exception<std::exception>>::type
|
||||
make_exception( E1 && car, E && ... cdr ) noexcept
|
||||
{
|
||||
static_assert(!at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
|
||||
return exception<std::exception>( new_error().load(std::forward<E1>(car), std::forward<E>(cdr)...) );
|
||||
}
|
||||
|
||||
inline exception<std::exception> make_exception() noexcept
|
||||
{
|
||||
return exception<std::exception>(leaf::new_error());
|
||||
}
|
||||
}
|
||||
|
||||
template <class... E>
|
||||
[[noreturn]] void throw_exception( E && ... e )
|
||||
{
|
||||
// Warning: setting a breakpoint here will not intercept exceptions thrown
|
||||
// via BOOST_LEAF_THROW_EXCEPTION or originating in the few other throw
|
||||
// points elsewhere in LEAF. To intercept all of those exceptions as well,
|
||||
// set a breakpoint inside boost::leaf::leaf_detail::throw_exception_impl.
|
||||
leaf_detail::throw_exception_impl(leaf_detail::make_exception(std::forward<E>(e)...));
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_LEAF_NO_EXCEPTIONS
|
||||
|
||||
template <class T>
|
||||
class result;
|
||||
|
||||
namespace leaf_detail
|
||||
{
|
||||
inline error_id catch_exceptions_helper( std::exception const &, leaf_detail_mp11::mp_list<> )
|
||||
{
|
||||
return leaf::new_error(std::current_exception());
|
||||
}
|
||||
|
||||
template <class Ex1, class... Ex>
|
||||
inline error_id catch_exceptions_helper( std::exception const & ex, leaf_detail_mp11::mp_list<Ex1,Ex...> )
|
||||
{
|
||||
if( Ex1 const * p = dynamic_cast<Ex1 const *>(&ex) )
|
||||
return catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>{ }).load(*p);
|
||||
else
|
||||
return catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>{ });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct deduce_exception_to_result_return_type_impl
|
||||
{
|
||||
using type = result<T>;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct deduce_exception_to_result_return_type_impl<result<T>>
|
||||
{
|
||||
using type = result<T>;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
using deduce_exception_to_result_return_type = typename deduce_exception_to_result_return_type_impl<T>::type;
|
||||
}
|
||||
|
||||
template <class... Ex, class F>
|
||||
inline
|
||||
leaf_detail::deduce_exception_to_result_return_type<leaf_detail::fn_return_type<F>>
|
||||
exception_to_result( F && f ) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
return std::forward<F>(f)();
|
||||
}
|
||||
catch( std::exception const & ex )
|
||||
{
|
||||
return leaf_detail::catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return leaf::new_error(std::current_exception());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user