2
0
mirror of https://github.com/boostorg/leaf.git synced 2026-01-19 04:22:08 +00:00

Testing preload with non-LEAF exceptions

This commit is contained in:
Emil Dotchevski
2020-01-03 10:23:09 -08:00
parent e55f47fe33
commit 0d276db168
10 changed files with 355 additions and 86 deletions

9
.vscode/tasks.json vendored
View File

@@ -401,6 +401,15 @@
"command": "${workspaceRoot}/.vscode/msvc.bat && cd ${workspaceRoot}/bld/debug && meson test preload_basic_test"
}
},
{
"label": "preload_exception_test",
"type": "shell",
"command": "cd ${workspaceRoot}/bld/debug && meson test preload_exception_test",
"problemMatcher": { "base": "$gcc", "fileLocation": ["relative","${workspaceRoot}/bld/debug"] },
"windows": {
"command": "${workspaceRoot}/.vscode/msvc.bat && cd ${workspaceRoot}/bld/debug && meson test preload_exception_test"
}
},
{
"label": "preload_nested_error_exception_test",
"type": "shell",

View File

@@ -1552,8 +1552,6 @@ namespace boost { namespace leaf {
if( std::uncaught_exception() )
# endif
ctx_->propagate();
else
(void) leaf_detail::new_id();
#endif
}
};

View File

@@ -666,8 +666,6 @@ namespace boost { namespace leaf {
if( std::uncaught_exception() )
# endif
ctx_->propagate();
else
(void) leaf_detail::new_id();
#endif
}
};

View File

@@ -104,6 +104,7 @@ tests = [
'multiple_errors_test',
'optional_test',
'preload_basic_test',
'preload_exception_test',
'preload_nested_error_exception_test',
'preload_nested_error_result_test',
'preload_nested_new_error_exception_test',

View File

@@ -71,6 +71,7 @@ run is_error_type_test.cpp ;
run multiple_errors_test.cpp ;
run optional_test.cpp ;
run preload_basic_test.cpp ;
run preload_exception_test.cpp ;
run preload_nested_error_exception_test.cpp ;
run preload_nested_error_result_test.cpp ;
run preload_nested_new_error_exception_test.cpp ;

View File

@@ -63,7 +63,7 @@ int main()
auto error_handler = []( leaf::error_info const & err, int a, int b )
{
return leaf::remote_handle_exception( err,
[&]( info<1> const & x1, info<2> const & x2,info<4> const & x4 )
[&]( info<1> const & x1, info<2> const & x2, info<4> const & )
{
BOOST_TEST_EQ(x1.value, a);
BOOST_TEST_EQ(x2.value, b);
@@ -75,33 +75,79 @@ int main()
} );
};
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>(
42,
[]( int a, int b, int res )
{
if( res>=0 )
return res;
else
throw leaf::exception( std::exception(), info<1>{a}, info<2>{b}, info<3>{} );
} );
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_catch(
[&]
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>(
42,
[]( int a, int b, int res )
{
auto propagate = leaf::preload( info<4>{} );
return leaf::future_get(f.fut);
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
if( res >= 0 )
return res;
else
throw leaf::exception( std::exception(), info<1>{a}, info<2>{b}, info<3>{} );
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_catch(
[&]
{
auto propagate = leaf::preload( info<4>{} );
// Calling future_get is required in order to make the preload (above) work.
return leaf::future_get(f.fut);
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
}
}
{
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>(
42,
[]( int a, int b, int res )
{
if( res >= 0 )
return res;
else
throw leaf::exception( std::exception(), info<1>{a}, info<2>{b}, info<3>{} );
} );
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_catch(
[&]
{
auto propagate = leaf::preload( info<4>{} );
return leaf::try_catch(
[&]
{
// Not calling future_get, a preload in this scope won't work correctly.
// This is to verify that the preload in the outer scope (above) works.
return f.fut.get();
},
[]() -> int
{
throw;
} );
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
}
}
return boost::report_errors();

View File

@@ -63,7 +63,7 @@ int main()
auto error_handler = []( leaf::error_info const & err, int a, int b )
{
return leaf::remote_handle_exception( err,
[&]( info<1> const & x1, info<2> const & x2 )
[&]( info<1> const & x1, info<2> const & x2, info<4> const & )
{
BOOST_TEST_EQ(x1.value, a);
BOOST_TEST_EQ(x2.value, b);
@@ -75,31 +75,79 @@ int main()
} );
};
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>( 42,
[]( 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>{} );
} );
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_handle_all(
[&]
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>(
42,
[]( int a, int b, int res ) -> leaf::result<int>
{
return f.fut.get();
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
if( res >= 0 )
return res;
else
return leaf::new_error( info<1>{a}, info<2>{b}, info<3>{} );
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_handle_all(
[&]
{
auto propagate = leaf::preload( info<4>{} );
// Calling future_get is required in order to make the preload (above) work.
return leaf::future_get(f.fut);
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
}
}
{
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>(
42,
[]( 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>{} );
} );
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_handle_all(
[&]
{
auto propagate = leaf::preload( info<4>{} );
return leaf::try_handle_some(
[&]
{
// Not calling future_get, a preload in this scope won't work correctly.
// This is to verify that the preload in the outer scope (above) works.
return f.fut.get();
},
[]( leaf::error_info const & err )
{
return err.error();
} );
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
}
}
return boost::report_errors();

View File

@@ -75,33 +75,79 @@ int main()
} );
};
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>(
42,
[]( 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>{} );
} );
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_handle_all(
[&]
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>(
42,
[]( int a, int b, int res ) -> leaf::result<int>
{
auto propagate = leaf::preload( info<4>{} );
return leaf::future_get(f.fut);
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
if( res >= 0 )
return res;
else
return leaf::new_error( info<1>{a}, info<2>{b}, info<3>{} );
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_handle_all(
[&]
{
auto propagate = leaf::preload( info<4>{} );
// Calling future_get is required in order to make the preload (above) work.
return leaf::future_get(f.fut);
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
}
}
{
std::vector<fut_info> fut = launch_tasks<decltype(error_handler)>(
42,
[]( 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>{} );
} );
for( auto & f : fut )
{
f.fut.wait();
int r = leaf::remote_try_handle_all(
[&]
{
auto propagate = leaf::preload( info<4>{} );
return leaf::try_handle_some(
[&]
{
// Not calling future_get, a preload in this scope won't work correctly.
// This is to verify that the preload in the outer scope (above) works.
return f.fut.get();
},
[]( leaf::error_info const & err )
{
return err.error();
} );
},
[&]( leaf::error_info const & err )
{
return error_handler(err, f.a, f.b);
} );
if( f.result>=0 )
BOOST_TEST_EQ(r, f.result);
else
BOOST_TEST_EQ(r, -1);
}
}
return boost::report_errors();

View File

@@ -80,15 +80,6 @@ int main()
BOOST_TEST_NE(id, leaf::leaf_detail::current_id());
}
{
int const id = leaf::leaf_detail::current_id();
BOOST_TEST_EQ( 5, test( []
{
throw my_error();
} ) );
BOOST_TEST_NE(id, leaf::leaf_detail::current_id());
}
{
int const id = leaf::leaf_detail::current_id();
BOOST_TEST_EQ( 5, test( []
@@ -108,7 +99,6 @@ int main()
throw;
}
} ) );
BOOST_TEST_NE(id, leaf::leaf_detail::current_id());
}
BOOST_TEST_EQ( 5, test( [] { throw leaf::exception(my_error()); } ) );

View File

@@ -0,0 +1,132 @@
// Copyright (c) 2018-2019 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/preload.hpp>
#include <boost/leaf/handle_exception.hpp>
#include <boost/leaf/result.hpp>
#include "lightweight_test.hpp"
namespace leaf = boost::leaf;
template <int>
struct info
{
int value;
};
template <class Thrower>
void g1( Thrower th )
{
auto load = leaf::preload( info<1>{} );
th();
}
template <class Thrower>
void g2( Thrower th )
{
auto load = leaf::preload( info<2>{} );
th();
}
template <class Thrower>
void f1( Thrower th )
{
return g1(th);
}
template <class Thrower>
void f2( Thrower th )
{
return g2(th);
}
int main()
{
BOOST_TEST_EQ(1,
leaf::try_catch(
[]
{
f1( [] { throw leaf::exception(std::exception()); } );
return 0;
},
[]( leaf::error_info const & err, info<1> )
{
BOOST_TEST_EQ(err.error().value(), 1);
return 1;
},
[]( info<2> )
{
return 2;
},
[]( info<1>, info<2> )
{
return 3;
} ));
BOOST_TEST_EQ(2,
leaf::try_catch(
[]
{
f2( [] { throw leaf::exception(std::exception()); } );
return 0;
},
[]( info<1> )
{
return 1;
},
[]( leaf::error_info const & err, info<2> )
{
BOOST_TEST_EQ(err.error().value(), 5);
return 2;
},
[]( info<1>, info<2> )
{
return 3;
} ));
BOOST_TEST_EQ(1,
leaf::try_catch(
[]
{
f1( [] { throw std::exception(); } );
return 0;
},
[]( leaf::error_info const & err, info<1> )
{
BOOST_TEST_EQ(err.error().value(), 9);
return 1;
},
[]( info<2> )
{
return 2;
},
[]( info<1>, info<2> )
{
return 3;
} ) );
BOOST_TEST_EQ(2,
leaf::try_catch(
[]
{
f2( [] { throw std::exception(); } );
return 0;
},
[]( info<1> )
{
return 1;
},
[]( leaf::error_info const & err, info<2> )
{
BOOST_TEST_EQ(err.error().value(), 13);
return 2;
},
[]( info<1>, info<2> )
{
return 3;
} ));
return boost::report_errors();
}