2
0
mirror of https://github.com/boostorg/leaf.git synced 2026-01-19 16:32:08 +00:00
Files
leaf/test/on_error_alloc_fail_test.cpp
2025-12-24 22:18:09 -05:00

240 lines
6.5 KiB
C++

// Copyright 2018-2025 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/error.hpp>
# include <boost/leaf/on_error.hpp>
# include <boost/leaf/handle_errors.hpp>
# include <boost/leaf/result.hpp>
# include <boost/leaf/diagnostics.hpp>
# include <boost/leaf/exception.hpp>
#endif
#if !BOOST_LEAF_CFG_CAPTURE || defined(BOOST_LEAF_NO_EXCEPTIONS)
int main()
{
return 0;
}
#else
#include <sstream>
#include <stdexcept>
#include <string>
namespace leaf = boost::leaf;
struct alloc_fail_info
{
int value;
};
namespace boost { namespace leaf { namespace detail {
template <>
struct capturing_slot_node_allocator<alloc_fail_info>
{
template <class... A>
static dynamic_allocator::capturing_slot_node<alloc_fail_info> * new_( A && ... )
{
throw std::bad_alloc();
}
static void delete_( dynamic_allocator::capturing_slot_node<alloc_fail_info> * p ) noexcept
{
delete p;
}
};
} } } // namespace boost::leaf::detail
#include "lightweight_test.hpp"
template <int N>
struct other_info
{
int value;
};
leaf::result<void> f()
{
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
return leaf::new_error();
}
int main()
{
{
auto captured = leaf::try_capture_all(
[]() -> leaf::result<void>
{
return f();
} );
int r = leaf::try_handle_all(
[&]() -> leaf::result<int>
{
(void) captured.value();
return 0;
},
[]( std::bad_alloc const &, other_info<1> const & oi1, other_info<2> const * oi2, alloc_fail_info const * afi )
{
BOOST_TEST_EQ(oi1.value, 1);
BOOST_TEST_EQ(oi2, nullptr);
BOOST_TEST_EQ(afi, nullptr);
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
#if BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_STD_STRING
{
int r = leaf::try_handle_all(
[]() -> leaf::result<int>
{
BOOST_LEAF_CHECK(f());
return 0;
},
[]( std::bad_alloc const &, leaf::diagnostic_details const & dd )
{
std::ostringstream s;
s << dd;
std::string str = s.str();
BOOST_TEST(str.find("other_info<1>") != std::string::npos);
BOOST_TEST(str.find("other_info<2>") == std::string::npos);
BOOST_TEST(str.find("alloc_fail_info") == std::string::npos);
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
#endif
////////////////////////////////////////
{
auto captured = leaf::try_capture_all(
[]() -> leaf::result<void>
{
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
throw std::runtime_error("test");
} );
int r = leaf::try_handle_all(
[&]() -> leaf::result<int>
{
(void) captured.value();
return 0;
},
[]( other_info<1> const & oi1, other_info<2> const * oi2, alloc_fail_info const * afi )
{
BOOST_TEST_EQ(oi1.value, 1);
BOOST_TEST_EQ(oi2, nullptr);
BOOST_TEST_EQ(afi, nullptr);
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
#if BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_STD_STRING
{
int r = leaf::try_catch(
[]() -> int
{
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
throw std::runtime_error("test");
},
[]( leaf::diagnostic_details const & dd )
{
std::ostringstream s;
s << dd;
std::string str = s.str();
BOOST_TEST(str.find("other_info<1>") != std::string::npos);
BOOST_TEST(str.find("other_info<2>") == std::string::npos);
BOOST_TEST(str.find("alloc_fail_info") == std::string::npos);
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
#endif
////////////////////////////////////////
{
auto captured = leaf::try_capture_all(
[]() -> leaf::result<void>
{
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
leaf::throw_exception(std::runtime_error("test"));
} );
int r = leaf::try_handle_all(
[&]() -> leaf::result<int>
{
(void) captured.value();
return 0;
},
[]( std::bad_alloc const &, other_info<1> const & oi1, other_info<2> const * oi2, alloc_fail_info const * afi )
{
BOOST_TEST_EQ(oi1.value, 1);
BOOST_TEST_EQ(oi2, nullptr);
BOOST_TEST_EQ(afi, nullptr);
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
#if BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_STD_STRING
{
int r = leaf::try_catch(
[]() -> int
{
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
leaf::throw_exception(std::runtime_error("test"));
},
[]( std::bad_alloc const &, leaf::diagnostic_details const & dd )
{
std::ostringstream s;
s << dd;
std::string str = s.str();
BOOST_TEST(str.find("other_info<1>") != std::string::npos);
BOOST_TEST(str.find("other_info<2>") == std::string::npos);
BOOST_TEST(str.find("alloc_fail_info") == std::string::npos);
return 1;
},
[]
{
return 2;
} );
BOOST_TEST_EQ(r, 1);
}
#endif
return boost::report_errors();
}
#endif