AimRT/_deps/boost-src/libs/leaf/test/handle_basic_test.cpp
2025-01-12 20:40:48 +08:00

402 lines
11 KiB
C++

// Copyright 2018-2022 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)
#ifdef BOOST_LEAF_TEST_SINGLE_HEADER
# include "leaf.hpp"
#else
# include <boost/leaf/config.hpp>
# include <boost/leaf/handle_errors.hpp>
# include <boost/leaf/pred.hpp>
# include <boost/leaf/result.hpp>
#endif
#include "lightweight_test.hpp"
namespace leaf = boost::leaf;
template <int Tag> struct info { int value;};
enum class error_code
{
error1=1,
error2,
error3
};
struct error1_tag { };
struct error2_tag { };
struct error3_tag { };
leaf::result<int> compute_answer( int what_to_do ) noexcept
{
switch( what_to_do )
{
case 0:
return 42;
case 1:
return leaf::new_error(error_code::error1);
case 2:
return leaf::new_error(error_code::error2);
case 3:
return leaf::new_error(error_code::error3);
case 4:
return leaf::new_error(error1_tag{}, error_code::error1);
case 5:
return leaf::new_error(error2_tag{}, error_code::error2);
default:
BOOST_LEAF_ASSERT(what_to_do==6);
return leaf::new_error(error3_tag{}, error_code::error3);
}
}
leaf::result<int> handle_some_errors( int what_to_do )
{
return leaf::try_handle_some(
[=]
{
return compute_answer(what_to_do);
},
[]( error1_tag, leaf::match<error_code, error_code::error1> )
{
return -1;
},
[]( leaf::match<error_code, error_code::error1> )
{
return -2;
} );
}
leaf::result<float> handle_some_errors_float( int what_to_do )
{
return leaf::try_handle_some(
[=]() -> leaf::result<float>
{
return compute_answer(what_to_do);
},
[]( error2_tag, leaf::match<error_code, error_code::error2> )
{
return -1.0f;
},
[]( leaf::match<error_code, error_code::error2> )
{
return -2.0f;
} );
}
leaf::result<void> handle_some_errors_void( int what_to_do )
{
return leaf::try_handle_some(
[=]() -> leaf::result<void>
{
BOOST_LEAF_AUTO(answer, compute_answer(what_to_do));
(void) answer;
return { };
},
[]( leaf::match<error_code, error_code::error3> )
{
} );
}
int main()
{
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
return leaf::try_handle_some(
[]() -> leaf::result<int>
{
return leaf::try_handle_some(
[]() -> leaf::result<int>
{
return leaf::new_error(40);
},
[]( leaf::error_info const & ei, int & v )
{
++v;
return ei.error();
});
},
[]( leaf::error_info const & ei, int & v )
{
++v;
return ei.error();
});
},
[]( int v )
{
BOOST_TEST_EQ(v, 42);
return 1;
},
[]
{
return 2;
});
BOOST_TEST_EQ(r, 1);
}
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
return leaf::try_handle_some(
[]() -> leaf::result<int>
{
return leaf::try_handle_some(
[]() -> leaf::result<int>
{
return leaf::new_error(40);
},
[]( leaf::error_info const & ei, int * v )
{
++*v;
return ei.error();
});
},
[]( leaf::error_info const & ei, int * v )
{
++*v;
return ei.error();
});
},
[]( int v )
{
BOOST_TEST_EQ(v, 42);
return 1;
},
[]
{
return 2;
});
BOOST_TEST_EQ(r, 1);
}
///////////////////////////
BOOST_TEST_EQ(handle_some_errors(0).value(), 42);
BOOST_TEST_EQ(handle_some_errors(1).value(), -2);
BOOST_TEST_EQ(handle_some_errors(4).value(), -1);
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
BOOST_LEAF_AUTO(answer, handle_some_errors(3));
(void) answer;
return 0;
},
[]( leaf::match<error_code, error_code::error3> )
{
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
///////////////////////////
BOOST_TEST_EQ(handle_some_errors_float(0).value(), 42.0f);
BOOST_TEST_EQ(handle_some_errors_float(2).value(), -2.0f);
BOOST_TEST_EQ(handle_some_errors_float(5).value(), -1.0f);
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
BOOST_LEAF_AUTO(answer, handle_some_errors_float(1));
(void) answer;
return 0;
},
[]( leaf::match<error_code, error_code::error1> )
{
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
///////////////////////////
BOOST_TEST(handle_some_errors_void(0));
BOOST_TEST(handle_some_errors_void(3));
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
BOOST_LEAF_CHECK(handle_some_errors_void(2));
return 0;
},
[]( leaf::match<error_code, error_code::error2> )
{
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
///////////////////////////
#ifndef BOOST_LEAF_NO_EXCEPTIONS
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
BOOST_LEAF_CHECK(handle_some_errors_void(2));
return 0;
},
[]( std::exception const & )
{
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 2);
}
#endif
///////////////////////////
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
return leaf::new_error( info<1>{42} );
},
[]( info<1> const & i1 )
{
BOOST_TEST_EQ(i1.value, 42);
int r1 = leaf::try_handle_all(
[]() -> leaf::result<int>
{
return leaf::new_error( info<1>{43} );
},
[]()
{
return -1;
} );
BOOST_TEST_EQ(r1, -1);
BOOST_TEST_EQ(i1.value, 42);
return 0;
},
[]()
{
return -1;
} );
BOOST_TEST_EQ(r, 0);
}
///////////////////////////
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
return leaf::new_error( info<1>{42} );
},
[]( info<1> const & i1 )
{
BOOST_TEST_EQ(i1.value, 42);
int r1 = leaf::try_handle_all(
[]() -> leaf::result<int>
{
return leaf::new_error( info<1>{43} );
},
[]( info<1> const & i1_ )
{
BOOST_TEST_EQ(i1_.value, 43);
return -1;
},
[]()
{
return -2;
} );
BOOST_TEST_EQ(r1, -1);
BOOST_TEST_EQ(i1.value, 42);
return 0;
},
[]()
{
return -1;
} );
BOOST_TEST_EQ(r, 0);
}
///////////////////////////
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
return leaf::try_handle_some(
[]() -> leaf::result<int>
{
return leaf::new_error( info<1>{1} );
},
[]( leaf::error_info const & err, info<1> const & i1, info<2> const * i2 )
{
//We have space for info<2> in the context but i2 is null.
BOOST_TEST_EQ(i1.value, 1);
BOOST_TEST(!i2);
return err.error().load(info<2>{2});
} );
},
[]( info<1> const & i1, info<2> const & i2 )
{
BOOST_TEST_EQ(i1.value, 1);
BOOST_TEST_EQ(i2.value, 2);
return 0;
},
[]()
{
return -1;
} );
BOOST_TEST_EQ(r, 0);
}
///////////////////////////
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
return leaf::try_handle_some(
[]() -> leaf::result<int>
{
return leaf::new_error( info<1>{1}, info<2>{-2} );
},
[]( leaf::error_info const & err, info<1> const & i1, info<2> & i2 )
{
BOOST_TEST_EQ(i1.value, 1);
BOOST_TEST_EQ(i2.value, -2);
i2 = info<2>{2};
return err.error();
} );
},
[]( info<1> const & i1, info<2> const & i2 )
{
BOOST_TEST_EQ(i1.value, 1);
BOOST_TEST_EQ(i2.value, 2);
return 0;
},
[]()
{
return -1;
} );
BOOST_TEST_EQ(r, 0);
}
///////////////////////////
return boost::report_errors();
}