From 35295d2ca0c683fbd1bab35acf8a88d7d9b1558d Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 21 Nov 2021 00:11:09 -0800 Subject: [PATCH] Issue #33 --- include/boost/leaf/exception.hpp | 21 ++++++++++++++------- test/Jamfile.v2 | 2 ++ test/_compile-fail-exception_1.cpp | 12 ++++++++++++ test/_compile-fail-exception_2.cpp | 12 ++++++++++++ test/exception_test.cpp | 28 ++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 test/_compile-fail-exception_1.cpp create mode 100644 test/_compile-fail-exception_2.cpp diff --git a/include/boost/leaf/exception.hpp b/include/boost/leaf/exception.hpp index 35240be1..621d60ef 100644 --- a/include/boost/leaf/exception.hpp +++ b/include/boost/leaf/exception.hpp @@ -86,6 +86,13 @@ namespace leaf_detail 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) @@ -109,22 +116,22 @@ namespace leaf_detail template struct at_least_one_derives_from_std_exception { - constexpr static const bool value = std::is_base_of::value || at_least_one_derives_from_std_exception::value; + constexpr static const bool value = std::is_base_of::type>::value || at_least_one_derives_from_std_exception::value; }; } template inline -typename std::enable_if::value, leaf_detail::exception>::type +typename std::enable_if::type>::value, leaf_detail::exception::type>>::type exception( error_id err, Ex && ex, E && ... e ) noexcept { static_assert(!leaf_detail::at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); - return leaf_detail::exception( err.load(std::forward(e)...), std::forward(ex) ); + return leaf_detail::exception::type>( err.load(std::forward(e)...), std::forward(ex) ); } template inline -typename std::enable_if::value, leaf_detail::exception>::type +typename std::enable_if::type>::value, leaf_detail::exception>::type exception( error_id err, E1 && car, E && ... cdr ) noexcept { static_assert(!leaf_detail::at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); @@ -138,16 +145,16 @@ inline leaf_detail::exception exception( error_id err ) noexcept template inline -typename std::enable_if::value, leaf_detail::exception>::type +typename std::enable_if::type>::value, leaf_detail::exception::type>>::type exception( Ex && ex, E && ... e ) noexcept { static_assert(!leaf_detail::at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); - return leaf_detail::exception( new_error().load(std::forward(e)...), std::forward(ex) ); + return leaf_detail::exception::type>( new_error().load(std::forward(e)...), std::forward(ex) ); } template inline -typename std::enable_if::value, leaf_detail::exception>::type +typename std::enable_if::type>::value, leaf_detail::exception>::type exception( E1 && car, E && ... cdr ) noexcept { static_assert(!leaf_detail::at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d16c701a..4cbe2c4e 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -115,6 +115,8 @@ compile-fail _compile-fail-BOOST_LEAF_ASSIGN.cpp ; compile-fail _compile-fail-BOOST_LEAF_AUTO.cpp ; compile-fail _compile-fail-diagnostic_info.cpp ; compile-fail _compile-fail-error_info.cpp ; +compile-fail _compile-fail-exception_1.cpp ; +compile-fail _compile-fail-exception_2.cpp ; compile-fail _compile-fail-new_error.cpp ; compile-fail _compile-fail-result_1.cpp ; compile-fail _compile-fail-result_2.cpp ; diff --git a/test/_compile-fail-exception_1.cpp b/test/_compile-fail-exception_1.cpp new file mode 100644 index 00000000..cddb4ef1 --- /dev/null +++ b/test/_compile-fail-exception_1.cpp @@ -0,0 +1,12 @@ +// Copyright (c) 2018-2021 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 + +namespace leaf = boost::leaf; + +struct test: std::exception { }; + +auto e = leaf::exception(std::exception(), test()); diff --git a/test/_compile-fail-exception_2.cpp b/test/_compile-fail-exception_2.cpp new file mode 100644 index 00000000..87669920 --- /dev/null +++ b/test/_compile-fail-exception_2.cpp @@ -0,0 +1,12 @@ +// Copyright (c) 2018-2021 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 + +namespace leaf = boost::leaf; + +struct test: std::exception { }; + +auto e = leaf::exception(42, test()); diff --git a/test/exception_test.cpp b/test/exception_test.cpp index 83bcf984..8ed80a8c 100644 --- a/test/exception_test.cpp +++ b/test/exception_test.cpp @@ -100,20 +100,30 @@ int main() BOOST_TEST_EQ(20, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(20, test>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test>([]{ throw leaf::exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test>([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test>([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); BOOST_TEST_EQ(22, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(22, test>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test>([]{ throw leaf::exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test>([]{ my_exception exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test>([]{ my_exception const exc(42); throw leaf::exception(exc); })); BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(20, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ throw leaf::exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(22, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ throw leaf::exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); BOOST_TEST_EQ(40, test([]{ throw BOOST_LEAF_EXCEPTION(info{42}); })); BOOST_TEST_EQ(41, test([]{ throw leaf::exception(info{42}); })); + BOOST_TEST_EQ(41, test([]{ info inf{42}; throw leaf::exception(inf); })); + BOOST_TEST_EQ(41, test([]{ info const inf{42}; throw leaf::exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); BOOST_TEST_EQ(42, test([]{ throw BOOST_LEAF_EXCEPTION(); })); BOOST_TEST_EQ(43, test([]{ throw leaf::exception(); })); @@ -121,13 +131,19 @@ int main() BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(20, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ throw leaf::exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(22, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ throw leaf::exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); BOOST_TEST_EQ(40, test([]{ throw BOOST_LEAF_EXCEPTION(info{42}); })); BOOST_TEST_EQ(41, test([]{ throw leaf::exception(info{42}); })); + BOOST_TEST_EQ(41, test([]{ info inf{42}; throw leaf::exception(inf); })); + BOOST_TEST_EQ(41, test([]{ info const inf{42}; throw leaf::exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); BOOST_TEST_EQ(42, test([]{ throw BOOST_LEAF_EXCEPTION(); })); BOOST_TEST_EQ(43, test([]{ throw leaf::exception(); })); @@ -135,13 +151,19 @@ int main() BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(20, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ throw leaf::exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(22, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ throw leaf::exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); BOOST_TEST_EQ(40, test([]{ throw BOOST_LEAF_EXCEPTION(info{42}); })); BOOST_TEST_EQ(41, test([]{ throw leaf::exception(info{42}); })); + BOOST_TEST_EQ(41, test([]{ info inf{42}; throw leaf::exception(inf); })); + BOOST_TEST_EQ(41, test([]{ info const inf{42}; throw leaf::exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); BOOST_TEST_EQ(42, test([]{ throw BOOST_LEAF_EXCEPTION(); })); BOOST_TEST_EQ(43, test([]{ throw leaf::exception(); })); @@ -149,13 +171,19 @@ int main() BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(20, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); BOOST_TEST_EQ(21, test([]{ throw leaf::exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(22, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); BOOST_TEST_EQ(23, test([]{ throw leaf::exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); BOOST_TEST_EQ(40, test([]{ throw BOOST_LEAF_EXCEPTION(info{42}); })); BOOST_TEST_EQ(41, test([]{ throw leaf::exception(info{42}); })); + BOOST_TEST_EQ(41, test([]{ info inf{42}; throw leaf::exception(inf); })); + BOOST_TEST_EQ(41, test([]{ info const inf{42}; throw leaf::exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); BOOST_TEST_EQ(42, test([]{ throw BOOST_LEAF_EXCEPTION(); })); BOOST_TEST_EQ(43, test([]{ throw leaf::exception(); }));