Skip to content

Commit

Permalink
Improved dynamic capture tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zajo committed Dec 18, 2023
1 parent cd3ee4e commit 506eee7
Show file tree
Hide file tree
Showing 11 changed files with 416 additions and 163 deletions.
40 changes: 31 additions & 9 deletions include/boost/leaf/handle_errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,9 @@ namespace leaf_detail
using R = decltype(std::declval<TryBlock>()());
try
{
return std::forward<TryBlock>(try_block)();
auto r = std::forward<TryBlock>(try_block)();
unload_result(&r);
return std::move(r);
}
catch( std::exception & ex )
{
Expand Down Expand Up @@ -955,19 +957,39 @@ try_handle_some( TryBlock && try_block, H && ... h )
}

template <class TryBlock, class... H>
BOOST_LEAF_CONSTEXPR inline
inline
decltype(std::declval<TryBlock>()())
try_catch( TryBlock && try_block, H && ... h )
{
context_type_from_handlers<H...> ctx;
auto active_context = activate_context(ctx);
return leaf_detail::try_catch_(
ctx,
[&]
{
return std::forward<TryBlock>(try_block)();
},
std::forward<H>(h)...);
using R = decltype(std::declval<TryBlock>()());
try
{
return std::forward<TryBlock>(try_block)();
}
catch( std::exception & ex )
{
ctx.deactivate();
error_info e(&ex);
return leaf_detail::handle_error_<R>(ctx.tup(), e, std::forward<H>(h)...,
[&]() -> R
{
ctx.unload(e.error());
throw;
} );
}
catch(...)
{
ctx.deactivate();
error_info e(nullptr);
return leaf_detail::handle_error_<R>(ctx.tup(), e, std::forward<H>(h)...,
[&]() -> R
{
ctx.unload(e.error());
throw;
} );
}
}

#endif
Expand Down
7 changes: 2 additions & 5 deletions include/boost/leaf/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,14 +557,11 @@ class BOOST_LEAF_SYMBOL_VISIBLE result
return error_id(error()).load(std::forward<Item>(item)...);
}

void unload() noexcept
void unload()
{
#if BOOST_LEAF_CFG_CAPTURE
if( what_.kind() == result_discriminant::err_id_capture_list )
{
int err_id = what_.get_error_id().value();
cap_.unload( err_id );
}
cap_.unload(what_.get_error_id().value());
#endif
}

Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ if option_enable_unit_tests
'BOOST_LEAF_CHECK_test',
'capture_exception_async_test',
'capture_exception_result_async_test',
'capture_exception_result_unload_test',
'capture_exception_state_test',
'capture_exception_unload_test',
'capture_result_async_test',
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ run BOOST_LEAF_CHECK_test.cpp ;
run boost_exception_test.cpp ;
run capture_exception_async_test.cpp ;
run capture_exception_result_async_test.cpp ;
run capture_exception_result_unload_test.cpp ;
run capture_exception_state_test.cpp ;
run capture_exception_unload_test.cpp ;
run capture_result_async_test.cpp ;
Expand Down
40 changes: 17 additions & 23 deletions test/capture_exception_result_async_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,18 @@ std::vector<fut_info> launch_tasks( int task_count, F f )

int main()
{
int const task_count = 1;
int const task_count = 100;
int received_a, received_b;

auto task =
[]( int a, int b, int res ) -> leaf::result<int>
{
if( res >= 0 )
return res;
else
return leaf::new_error( info<1>{a}, info<2>{b}, info<3>{} );
};

auto error_handlers = std::make_tuple(
[&]( info<1> const & x1, info<2> const & x2, info<4> const & )
{
Expand All @@ -88,15 +98,7 @@ int main()
} );

{
std::vector<fut_info> fut = launch_tasks(
task_count,
[]( int a, int b, int res ) -> leaf::result<int>
{
if( res >= 0 )
return res;
else
return leaf::new_error( info<1>{a}, info<2>{b}, info<3>{} );
} );
std::vector<fut_info> fut = launch_tasks(task_count, task);

for( auto & f : fut )
{
Expand All @@ -114,22 +116,14 @@ int main()
else
{
BOOST_TEST_EQ(r, -1);
BOOST_TEST_EQ(received_a, f.a);
BOOST_TEST_EQ(received_b, f.b);
BOOST_TEST_EQ(f.a, received_a);
BOOST_TEST_EQ(f.b, received_b);
}
}
}

{
std::vector<fut_info> fut = launch_tasks(
task_count,
[]( int a, int b, int res ) -> leaf::result<int>
{
if( res >= 0 )
return res;
else
return leaf::new_error( info<1>{a}, info<2>{b}, info<3>{} );
} );
std::vector<fut_info> fut = launch_tasks(task_count, task);

for( auto & f : fut )
{
Expand All @@ -156,8 +150,8 @@ int main()
else
{
BOOST_TEST_EQ(r, -1);
BOOST_TEST_EQ(received_a, f.a);
BOOST_TEST_EQ(received_b, f.b);
BOOST_TEST_EQ(f.a, received_a);
BOOST_TEST_EQ(f.b, received_b);
}
}
}
Expand Down
213 changes: 213 additions & 0 deletions test/capture_exception_result_unload_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
// 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>

#if defined(BOOST_LEAF_NO_EXCEPTIONS) || !BOOST_LEAF_CFG_CAPTURE

#include <iostream>

int main()
{
std::cout << "Unit test not applicable." << std::endl;
return 0;
}

#else

#ifdef BOOST_LEAF_TEST_SINGLE_HEADER
# include "leaf.hpp"
#else
# include <boost/leaf/result.hpp>
# include <boost/leaf/handle_errors.hpp>
# include <boost/leaf/on_error.hpp>
# include <boost/leaf/exception.hpp>
#endif

#include "_test_ec.hpp"
#include "lightweight_test.hpp"

namespace leaf = boost::leaf;

template <int> struct info { int value; };

template <class F>
void test( F f )
{
{
int c=0;
auto r = f();
leaf::try_handle_all(
[&r]() -> leaf::result<void>
{
BOOST_LEAF_CHECK(std::move(r));
return { };
},
[&c]( info<1> const & x )
{
BOOST_TEST_EQ(x.value, 1);
BOOST_TEST_EQ(c, 0);
c = 1;
},
[&c]
{
BOOST_TEST_EQ(c, 0);
c = 2;
} );
BOOST_TEST_EQ(c, 1);
}

{
int c=0;
auto r = f();
leaf::try_handle_all(
[&r]() -> leaf::result<void>
{
BOOST_LEAF_CHECK(std::move(r));
return { };
},
[&c]( info<2> const & x )
{
BOOST_TEST_EQ(x.value, 2);
BOOST_TEST_EQ(c, 0);
c = 1;
},
[&c]
{
BOOST_TEST_EQ(c, 0);
c = 2;
} );
BOOST_TEST_EQ(c, 2);
}

{
auto r = f();
int what = leaf::try_handle_all(
[&r]() -> leaf::result<int>
{
BOOST_LEAF_CHECK(std::move(r));
return 0;
},
[]( info<1> const & x )
{
BOOST_TEST_EQ(x.value, 1);
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(what, 1);
}

{
auto r = f();
int what = leaf::try_handle_all(
[&r]() -> leaf::result<int>
{
BOOST_LEAF_CHECK(std::move(r));
return 0;
},
[]( info<2> const & x )
{
BOOST_TEST_EQ(x.value, 2);
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(what, 2);
}
}

int main()
{
test( []
{
return leaf::try_catch(
[]() -> leaf::result<int>
{
leaf::throw_exception(errc_a::a0, info<1>{1}, info<3>{3});
},
[]( leaf::dynamic_capture const & cap ) -> leaf::result<int>
{
return cap;
} );
} );

test( []
{
return leaf::try_catch(
[]() -> leaf::result<void>
{
leaf::throw_exception(errc_a::a0, info<1>{1}, info<3>{3});
},
[]( leaf::dynamic_capture const & cap ) -> leaf::result<void>
{
return cap;
} );
} );

test( []
{
return leaf::try_catch(
[]() -> leaf::result<int>
{
auto load = leaf::on_error(errc_a::a0, info<1>{1}, info<3>{3});
leaf::throw_exception();
},
[]( leaf::dynamic_capture const & cap ) -> leaf::result<int>
{
return cap;
} );
} );

test( []
{
return leaf::try_catch(
[]() -> leaf::result<void>
{
auto load = leaf::on_error(errc_a::a0, info<1>{1}, info<3>{3});
leaf::throw_exception();
},
[]( leaf::dynamic_capture const & cap ) -> leaf::result<void>
{
return cap;
} );
} );

test( []
{
return leaf::try_catch(
[]() -> leaf::result<int>
{
auto load = leaf::on_error(errc_a::a0, info<1>{1}, info<3>{3});
throw std::exception();
},
[]( leaf::dynamic_capture const & cap ) -> leaf::result<int>
{
return cap;
} );
} );

test( []
{
return leaf::try_catch(
[]() -> leaf::result<void>
{
auto load = leaf::on_error(errc_a::a0, info<1>{1}, info<3>{3});
throw std::exception();
},
[]( leaf::dynamic_capture const & cap ) -> leaf::result<void>
{
return cap;
} );
} );

return boost::report_errors();
}

#endif
Loading

0 comments on commit 506eee7

Please sign in to comment.