mirror of
https://github.com/boostorg/leaf.git
synced 2026-01-19 04:22:08 +00:00
faster to compile tuple handlers implementation
This commit is contained in:
9
.vscode/tasks.json
vendored
9
.vscode/tasks.json
vendored
@@ -311,15 +311,6 @@
|
||||
"command": "${workspaceRoot}/.vscode/msvc.bat && cd ${workspaceRoot}/bld/debug && meson test exception_to_result_test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "flatten_tuple_test",
|
||||
"type": "shell",
|
||||
"command": "cd ${workspaceRoot}/bld/debug && meson test flatten_tuple_test",
|
||||
"problemMatcher": { "base": "$gcc", "fileLocation": ["relative","${workspaceRoot}/bld/debug"] },
|
||||
"windows": {
|
||||
"command": "${workspaceRoot}/.vscode/msvc.bat && cd ${workspaceRoot}/bld/debug && meson test flatten_tuple_test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "function_traits_test",
|
||||
"type": "shell",
|
||||
|
||||
@@ -3589,66 +3589,68 @@ namespace boost { namespace leaf {
|
||||
}
|
||||
};
|
||||
|
||||
template <class R, class Tup, class F>
|
||||
LEAF_CONSTEXPR inline R handle_error_using_handlers_list_( Tup & e_objects, error_info const & ei, F && f )
|
||||
template <class T>
|
||||
struct is_tuple: std::false_type { };
|
||||
|
||||
template <class T>
|
||||
struct is_tuple<T &>: is_tuple<T> { };
|
||||
|
||||
template <class... T>
|
||||
struct is_tuple<std::tuple<T...>>: std::true_type { };
|
||||
|
||||
template <class R, class Tup, class H>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<!is_tuple<H>::value, R>::type handle_error_( Tup & tup, error_info const & ei, H && h )
|
||||
{
|
||||
static_assert( handler_matches_any_error<fn_mp_args<F>>::value, "The last handler passed to handle_all must match any error." );
|
||||
return handler_caller<R, F>::call( e_objects, ei, std::forward<F>(f), fn_mp_args<F>{ } );
|
||||
static_assert( handler_matches_any_error<fn_mp_args<H>>::value, "The last handler passed to handle_all must match any error." );
|
||||
return handler_caller<R, H>::call( tup, ei, std::forward<H>(h), fn_mp_args<H>{ } );
|
||||
}
|
||||
|
||||
template <class R, class Tup, class CarF, class... CdrF>
|
||||
LEAF_CONSTEXPR inline R handle_error_using_handlers_list_( Tup & e_objects, error_info const & ei, CarF && car_f, CdrF && ... cdr_f )
|
||||
template <class R, class Tup, class H>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<is_tuple<H>::value, R>::type handle_error_( Tup &, error_info const &, H && );
|
||||
|
||||
template <class R, class Tup, class Car, class... Cdr>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<is_tuple<Car>::value, R>::type handle_error_( Tup &, error_info const &, Car &&, Cdr && ... );
|
||||
|
||||
template <class R, class Tup, class Car, class... Cdr>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<!is_tuple<Car>::value, R>::type handle_error_( Tup & tup, error_info const & ei, Car && car, Cdr && ... cdr )
|
||||
{
|
||||
if( handler_matches_any_error<fn_mp_args<CarF>>::value || check_handler_( e_objects, ei, fn_mp_args<CarF>{ } ) )
|
||||
return handler_caller<R, CarF>::call( e_objects, ei, std::forward<CarF>(car_f), fn_mp_args<CarF>{ } );
|
||||
if( handler_matches_any_error<fn_mp_args<Car>>::value || check_handler_( tup, ei, fn_mp_args<Car>{ } ) )
|
||||
return handler_caller<R, Car>::call( tup, ei, std::forward<Car>(car), fn_mp_args<Car>{ } );
|
||||
else
|
||||
return handle_error_using_handlers_list_<R>( e_objects, ei, std::forward<CdrF>(cdr_f)...);
|
||||
return handle_error_<R>( tup, ei, std::forward<Cdr>(cdr)...);
|
||||
}
|
||||
|
||||
template <class R, class Tup, class HandlersTuple, size_t ... I>
|
||||
LEAF_CONSTEXPR inline R handle_error_using_handlers_tuple_helper_( Tup & e_objects, error_info const & ei, HandlersTuple && handlers, leaf_detail_mp11::index_sequence<I...>)
|
||||
template <class R, class Tup, class HTup, size_t ... I>
|
||||
LEAF_CONSTEXPR inline R handle_error_tuple_( Tup & tup, error_info const & ei, leaf_detail_mp11::index_sequence<I...>, HTup && htup )
|
||||
{
|
||||
return handle_error_using_handlers_list_<R>(e_objects, ei, std::get<I>(std::forward<HandlersTuple>(handlers))...);
|
||||
return handle_error_<R>(tup, ei, std::get<I>(std::forward<HTup>(htup))...);
|
||||
}
|
||||
|
||||
template <class R, class Tup, class... H>
|
||||
LEAF_CONSTEXPR inline R handle_error_using_handlers_tuple_( Tup & e_objects, error_info const & ei, std::tuple<H...> && handlers )
|
||||
template <class R, class Tup, class HTup, class... Cdr, size_t ... I>
|
||||
LEAF_CONSTEXPR inline R handle_error_tuple_( Tup & tup, error_info const & ei, leaf_detail_mp11::index_sequence<I...>, HTup && htup, Cdr && ... cdr )
|
||||
{
|
||||
return handle_error_using_handlers_tuple_helper_<R>(
|
||||
e_objects,
|
||||
return handle_error_<R>(tup, ei, std::get<I>(std::forward<HTup>(htup))..., std::forward<Cdr>(cdr)...);
|
||||
}
|
||||
|
||||
template <class R, class Tup, class H>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<is_tuple<H>::value, R>::type handle_error_( Tup & tup, error_info const & ei, H && h )
|
||||
{
|
||||
return handle_error_tuple_<R>(
|
||||
tup,
|
||||
ei,
|
||||
std::forward<std::tuple<H...>>(handlers),
|
||||
leaf_detail_mp11::make_index_sequence<sizeof...(H)>());
|
||||
leaf_detail_mp11::make_index_sequence<std::tuple_size<typename std::decay<H>::type>::value>(),
|
||||
std::forward<H>(h));
|
||||
}
|
||||
|
||||
template <class T> struct is_tuple: std::false_type { };
|
||||
template <class... T> struct is_tuple<std::tuple<T...>>: std::true_type { };
|
||||
|
||||
template <class H>
|
||||
constexpr std::tuple<H> inline tuplefy( H h ) noexcept
|
||||
template <class R, class Tup, class Car, class... Cdr>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<is_tuple<Car>::value, R>::type handle_error_( Tup & tup, error_info const & ei, Car && car, Cdr && ... cdr )
|
||||
{
|
||||
return std::make_tuple(h);
|
||||
}
|
||||
|
||||
template <class... H>
|
||||
constexpr std::tuple<H...> inline tuplefy( std::tuple<H...> h ) noexcept
|
||||
{
|
||||
return h;
|
||||
}
|
||||
|
||||
template <class... H>
|
||||
constexpr decltype(std::tuple_cat(tuplefy(std::declval<typename std::decay<H>::type>())...)) flatten_tuple( H && ... h ) noexcept
|
||||
{
|
||||
return std::tuple_cat(tuplefy(std::forward<H>(h))...);
|
||||
}
|
||||
|
||||
template <class R, class Tup, class... H>
|
||||
LEAF_CONSTEXPR inline R handle_error_( Tup & e_objects, error_info const & ei, H && ... h )
|
||||
{
|
||||
return handle_error_using_handlers_tuple_<R>(
|
||||
e_objects,
|
||||
return handle_error_tuple_<R>(
|
||||
tup,
|
||||
ei,
|
||||
flatten_tuple(std::forward<H>(h)...));
|
||||
leaf_detail_mp11::make_index_sequence<std::tuple_size<typename std::decay<Car>::type>::value>(),
|
||||
std::forward<Car>(car),
|
||||
std::forward<Cdr>(cdr)...);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -663,66 +663,68 @@ namespace boost { namespace leaf {
|
||||
}
|
||||
};
|
||||
|
||||
template <class R, class Tup, class F>
|
||||
LEAF_CONSTEXPR inline R handle_error_using_handlers_list_( Tup & e_objects, error_info const & ei, F && f )
|
||||
template <class T>
|
||||
struct is_tuple: std::false_type { };
|
||||
|
||||
template <class T>
|
||||
struct is_tuple<T &>: is_tuple<T> { };
|
||||
|
||||
template <class... T>
|
||||
struct is_tuple<std::tuple<T...>>: std::true_type { };
|
||||
|
||||
template <class R, class Tup, class H>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<!is_tuple<H>::value, R>::type handle_error_( Tup & tup, error_info const & ei, H && h )
|
||||
{
|
||||
static_assert( handler_matches_any_error<fn_mp_args<F>>::value, "The last handler passed to handle_all must match any error." );
|
||||
return handler_caller<R, F>::call( e_objects, ei, std::forward<F>(f), fn_mp_args<F>{ } );
|
||||
static_assert( handler_matches_any_error<fn_mp_args<H>>::value, "The last handler passed to handle_all must match any error." );
|
||||
return handler_caller<R, H>::call( tup, ei, std::forward<H>(h), fn_mp_args<H>{ } );
|
||||
}
|
||||
|
||||
template <class R, class Tup, class CarF, class... CdrF>
|
||||
LEAF_CONSTEXPR inline R handle_error_using_handlers_list_( Tup & e_objects, error_info const & ei, CarF && car_f, CdrF && ... cdr_f )
|
||||
template <class R, class Tup, class H>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<is_tuple<H>::value, R>::type handle_error_( Tup &, error_info const &, H && );
|
||||
|
||||
template <class R, class Tup, class Car, class... Cdr>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<is_tuple<Car>::value, R>::type handle_error_( Tup &, error_info const &, Car &&, Cdr && ... );
|
||||
|
||||
template <class R, class Tup, class Car, class... Cdr>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<!is_tuple<Car>::value, R>::type handle_error_( Tup & tup, error_info const & ei, Car && car, Cdr && ... cdr )
|
||||
{
|
||||
if( handler_matches_any_error<fn_mp_args<CarF>>::value || check_handler_( e_objects, ei, fn_mp_args<CarF>{ } ) )
|
||||
return handler_caller<R, CarF>::call( e_objects, ei, std::forward<CarF>(car_f), fn_mp_args<CarF>{ } );
|
||||
if( handler_matches_any_error<fn_mp_args<Car>>::value || check_handler_( tup, ei, fn_mp_args<Car>{ } ) )
|
||||
return handler_caller<R, Car>::call( tup, ei, std::forward<Car>(car), fn_mp_args<Car>{ } );
|
||||
else
|
||||
return handle_error_using_handlers_list_<R>( e_objects, ei, std::forward<CdrF>(cdr_f)...);
|
||||
return handle_error_<R>( tup, ei, std::forward<Cdr>(cdr)...);
|
||||
}
|
||||
|
||||
template <class R, class Tup, class HandlersTuple, size_t ... I>
|
||||
LEAF_CONSTEXPR inline R handle_error_using_handlers_tuple_helper_( Tup & e_objects, error_info const & ei, HandlersTuple && handlers, leaf_detail_mp11::index_sequence<I...>)
|
||||
template <class R, class Tup, class HTup, size_t ... I>
|
||||
LEAF_CONSTEXPR inline R handle_error_tuple_( Tup & tup, error_info const & ei, leaf_detail_mp11::index_sequence<I...>, HTup && htup )
|
||||
{
|
||||
return handle_error_using_handlers_list_<R>(e_objects, ei, std::get<I>(std::forward<HandlersTuple>(handlers))...);
|
||||
return handle_error_<R>(tup, ei, std::get<I>(std::forward<HTup>(htup))...);
|
||||
}
|
||||
|
||||
template <class R, class Tup, class... H>
|
||||
LEAF_CONSTEXPR inline R handle_error_using_handlers_tuple_( Tup & e_objects, error_info const & ei, std::tuple<H...> && handlers )
|
||||
template <class R, class Tup, class HTup, class... Cdr, size_t ... I>
|
||||
LEAF_CONSTEXPR inline R handle_error_tuple_( Tup & tup, error_info const & ei, leaf_detail_mp11::index_sequence<I...>, HTup && htup, Cdr && ... cdr )
|
||||
{
|
||||
return handle_error_using_handlers_tuple_helper_<R>(
|
||||
e_objects,
|
||||
return handle_error_<R>(tup, ei, std::get<I>(std::forward<HTup>(htup))..., std::forward<Cdr>(cdr)...);
|
||||
}
|
||||
|
||||
template <class R, class Tup, class H>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<is_tuple<H>::value, R>::type handle_error_( Tup & tup, error_info const & ei, H && h )
|
||||
{
|
||||
return handle_error_tuple_<R>(
|
||||
tup,
|
||||
ei,
|
||||
std::forward<std::tuple<H...>>(handlers),
|
||||
leaf_detail_mp11::make_index_sequence<sizeof...(H)>());
|
||||
leaf_detail_mp11::make_index_sequence<std::tuple_size<typename std::decay<H>::type>::value>(),
|
||||
std::forward<H>(h));
|
||||
}
|
||||
|
||||
template <class T> struct is_tuple: std::false_type { };
|
||||
template <class... T> struct is_tuple<std::tuple<T...>>: std::true_type { };
|
||||
|
||||
template <class H>
|
||||
constexpr std::tuple<H> inline tuplefy( H h ) noexcept
|
||||
template <class R, class Tup, class Car, class... Cdr>
|
||||
LEAF_CONSTEXPR inline typename std::enable_if<is_tuple<Car>::value, R>::type handle_error_( Tup & tup, error_info const & ei, Car && car, Cdr && ... cdr )
|
||||
{
|
||||
return std::make_tuple(h);
|
||||
}
|
||||
|
||||
template <class... H>
|
||||
constexpr std::tuple<H...> inline tuplefy( std::tuple<H...> h ) noexcept
|
||||
{
|
||||
return h;
|
||||
}
|
||||
|
||||
template <class... H>
|
||||
constexpr decltype(std::tuple_cat(tuplefy(std::declval<typename std::decay<H>::type>())...)) flatten_tuple( H && ... h ) noexcept
|
||||
{
|
||||
return std::tuple_cat(tuplefy(std::forward<H>(h))...);
|
||||
}
|
||||
|
||||
template <class R, class Tup, class... H>
|
||||
LEAF_CONSTEXPR inline R handle_error_( Tup & e_objects, error_info const & ei, H && ... h )
|
||||
{
|
||||
return handle_error_using_handlers_tuple_<R>(
|
||||
e_objects,
|
||||
return handle_error_tuple_<R>(
|
||||
tup,
|
||||
ei,
|
||||
flatten_tuple(std::forward<H>(h)...));
|
||||
leaf_detail_mp11::make_index_sequence<std::tuple_size<typename std::decay<Car>::type>::value>(),
|
||||
std::forward<Car>(car),
|
||||
std::forward<Cdr>(cdr)...);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,6 @@ tests = [
|
||||
'error_id_test',
|
||||
'exception_test',
|
||||
'exception_to_result_test',
|
||||
'flatten_tuple_test',
|
||||
'function_traits_test',
|
||||
'handle_all_other_result_test',
|
||||
'handle_all_test',
|
||||
|
||||
@@ -61,7 +61,6 @@ run error_code_test.cpp ;
|
||||
run error_id_test.cpp ;
|
||||
run exception_test.cpp ;
|
||||
run exception_to_result_test.cpp ;
|
||||
run flatten_tuple_test.cpp ;
|
||||
run function_traits_test.cpp ;
|
||||
run handle_all_other_result_test.cpp ;
|
||||
run handle_all_test.cpp ;
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
// Copyright (c) 2018-2020 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/handle_error.hpp>
|
||||
#include "lightweight_test.hpp"
|
||||
|
||||
using boost::leaf::leaf_detail::flatten_tuple;
|
||||
|
||||
static_assert(std::is_same<
|
||||
decltype(flatten_tuple(int{}, float{})),
|
||||
std::tuple<int, float>>
|
||||
::value, "flatten_tuple_failure");
|
||||
|
||||
static_assert(std::is_same<
|
||||
decltype(flatten_tuple(std::tuple<int,float>{}, std::tuple<short,long>{})),
|
||||
std::tuple<int, float, short, long>>
|
||||
::value, "flatten_tuple_failure");
|
||||
|
||||
static_assert(std::is_same<
|
||||
decltype(flatten_tuple(std::tuple<int,float>{}, short{}, long{})),
|
||||
std::tuple<int, float, short, long>>
|
||||
::value, "flatten_tuple_failure");
|
||||
|
||||
static_assert(std::is_same<
|
||||
decltype(flatten_tuple(int{}, std::tuple<float, short>{}, long{})),
|
||||
std::tuple<int, float, short, long>>
|
||||
::value, "flatten_tuple_failure");
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST(
|
||||
flatten_tuple(int{1}, float{2}, std::make_tuple(short{3},long{4}))
|
||||
==
|
||||
std::make_tuple(int{1}, float{2}, short{3}, long{4}));
|
||||
|
||||
BOOST_TEST(
|
||||
flatten_tuple(std::make_tuple(int{1}, float{2}), std::make_tuple(short{3},long{4}))
|
||||
==
|
||||
std::make_tuple(int{1}, float{2}, short{3}, long{4}));
|
||||
|
||||
BOOST_TEST(
|
||||
flatten_tuple(std::make_tuple(int{1}, float{2}), short{3}, long{4})
|
||||
==
|
||||
std::make_tuple(int{1}, float{2}, short{3}, long{4}));
|
||||
|
||||
BOOST_TEST(
|
||||
flatten_tuple(int{1}, std::make_tuple(float{2}, short{3}), long{4})
|
||||
==
|
||||
std::make_tuple(int{1}, float{2}, short{3}, long{4}));
|
||||
|
||||
{
|
||||
int i = 1;
|
||||
float f = 2;
|
||||
auto t = std::make_tuple(short{3},long{4});
|
||||
BOOST_TEST(
|
||||
flatten_tuple(i, f, t)
|
||||
==
|
||||
std::make_tuple(int{1}, float{2}, short{3}, long{4}));
|
||||
}
|
||||
|
||||
{
|
||||
int const i = 1;
|
||||
float const f = 2;
|
||||
auto const t = std::make_tuple(short{3},long{4});
|
||||
BOOST_TEST(
|
||||
flatten_tuple(i, f, t)
|
||||
==
|
||||
std::make_tuple(int{1}, float{2}, short{3}, long{4}));
|
||||
}
|
||||
|
||||
{
|
||||
int const & i = 1;
|
||||
float const & f = 2;
|
||||
auto const & t = std::make_tuple(short{3},long{4});
|
||||
BOOST_TEST(
|
||||
flatten_tuple(i, f, t)
|
||||
==
|
||||
std::make_tuple(int{1}, float{2}, short{3}, long{4}));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
Reference in New Issue
Block a user