From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/boost/libs/function/test/function_test.cpp | 813 +++++++++++++++++++++++++ 1 file changed, 813 insertions(+) create mode 100644 src/boost/libs/function/test/function_test.cpp (limited to 'src/boost/libs/function/test/function_test.cpp') diff --git a/src/boost/libs/function/test/function_test.cpp b/src/boost/libs/function/test/function_test.cpp new file mode 100644 index 000000000..88747e01a --- /dev/null +++ b/src/boost/libs/function/test/function_test.cpp @@ -0,0 +1,813 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2003. Use, modification and +// distribution is subject to 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) + +// For more information, see http://www.boost.org + +#include +#include +#include +#include +#include + +#define BOOST_CHECK BOOST_TEST + +using boost::function; +using std::string; + +int global_int; + +struct write_five_obj { void operator()() const { global_int = 5; } }; +struct write_three_obj { int operator()() const { global_int = 3; return 7; }}; +static void write_five() { global_int = 5; } +static void write_three() { global_int = 3; } +struct generate_five_obj { int operator()() const { return 5; } }; +struct generate_three_obj { int operator()() const { return 3; } }; +static int generate_five() { return 5; } +static int generate_three() { return 3; } +static string identity_str(const string& s) { return s; } +static string string_cat(const string& s1, const string& s2) { return s1+s2; } +static int sum_ints(int x, int y) { return x+y; } + +struct write_const_1_nonconst_2 +{ + void operator()() { global_int = 2; } + void operator()() const { global_int = 1; } +}; + +struct add_to_obj +{ + add_to_obj(int v) : value(v) {} + + int operator()(int x) const { return value + x; } + + int value; +}; + +static void +test_zero_args() +{ + typedef function func_void_type; + + write_five_obj five; + write_three_obj three; + + // Default construction + func_void_type v1; + BOOST_CHECK(v1.empty()); + + // Assignment to an empty function + v1 = five; + BOOST_CHECK(v1 != 0); + + // Invocation of a function + global_int = 0; + v1(); + BOOST_CHECK(global_int == 5); + + // clear() method + v1.clear(); + BOOST_CHECK(v1 == 0); + + // Assignment to an empty function + v1 = three; + BOOST_CHECK(!v1.empty()); + + // Invocation and self-assignment + global_int = 0; + v1 = v1; + v1(); + BOOST_CHECK(global_int == 3); + + // Assignment to a non-empty function + v1 = five; + + // Invocation and self-assignment + global_int = 0; + v1 = (v1); + v1(); + BOOST_CHECK(global_int == 5); + + // clear + v1 = 0; + BOOST_CHECK(0 == v1); + + // Assignment to an empty function from a free function + v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five; + BOOST_CHECK(0 != v1); + + // Invocation + global_int = 0; + v1(); + BOOST_CHECK(global_int == 5); + + // Assignment to a non-empty function from a free function + v1 = BOOST_FUNCTION_TARGET_FIX(&) write_three; + BOOST_CHECK(!v1.empty()); + + // Invocation + global_int = 0; + v1(); + BOOST_CHECK(global_int == 3); + + // Assignment + v1 = five; + BOOST_CHECK(!v1.empty()); + + // Invocation + global_int = 0; + v1(); + BOOST_CHECK(global_int == 5); + + // Assignment to a non-empty function from a free function + v1 = &write_three; + BOOST_CHECK(!v1.empty()); + + // Invocation + global_int = 0; + v1(); + BOOST_CHECK(global_int == 3); + + // Construction from another function (that is empty) + v1.clear(); + func_void_type v2(v1); + BOOST_CHECK(!v2? true : false); + + // Assignment to an empty function + v2 = three; + BOOST_CHECK(!v2.empty()); + + // Invocation + global_int = 0; + v2(); + BOOST_CHECK(global_int == 3); + + // Assignment to a non-empty function + v2 = (five); + + // Invocation + global_int = 0; + v2(); + BOOST_CHECK(global_int == 5); + + v2.clear(); + BOOST_CHECK(v2.empty()); + + // Assignment to an empty function from a free function + v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five); + BOOST_CHECK(v2? true : false); + + // Invocation + global_int = 0; + v2(); + BOOST_CHECK(global_int == 5); + + // Assignment to a non-empty function from a free function + v2 = BOOST_FUNCTION_TARGET_FIX(&) write_three; + BOOST_CHECK(!v2.empty()); + + // Invocation + global_int = 0; + v2(); + BOOST_CHECK(global_int == 3); + + // Swapping + v1 = five; + swap(v1, v2); + v2(); + BOOST_CHECK(global_int == 5); + v1(); + BOOST_CHECK(global_int == 3); + swap(v1, v2); + v1.clear(); + + // Assignment + v2 = five; + BOOST_CHECK(!v2.empty()); + + // Invocation + global_int = 0; + v2(); + BOOST_CHECK(global_int == 5); + + // Assignment to a non-empty function from a free function + v2 = &write_three; + BOOST_CHECK(!v2.empty()); + + // Invocation + global_int = 0; + v2(); + BOOST_CHECK(global_int == 3); + + // Assignment to a function from an empty function + v2 = v1; + BOOST_CHECK(v2.empty()); + + // Assignment to a function from a function with a functor + v1 = three; + v2 = v1; + BOOST_CHECK(!v1.empty()); + BOOST_CHECK(!v2.empty()); + + // Invocation + global_int = 0; + v1(); + BOOST_CHECK(global_int == 3); + global_int = 0; + v2(); + BOOST_CHECK(global_int == 3); + + // Assign to a function from a function with a function + v2 = BOOST_FUNCTION_TARGET_FIX(&) write_five; + v1 = v2; + BOOST_CHECK(!v1.empty()); + BOOST_CHECK(!v2.empty()); + global_int = 0; + v1(); + BOOST_CHECK(global_int == 5); + global_int = 0; + v2(); + BOOST_CHECK(global_int == 5); + + // Construct a function given another function containing a function + func_void_type v3(v1); + + // Invocation of a function + global_int = 0; + v3(); + BOOST_CHECK(global_int == 5); + + // clear() method + v3.clear(); + BOOST_CHECK(!v3? true : false); + + // Assignment to an empty function + v3 = three; + BOOST_CHECK(!v3.empty()); + + // Invocation + global_int = 0; + v3(); + BOOST_CHECK(global_int == 3); + + // Assignment to a non-empty function + v3 = five; + + // Invocation + global_int = 0; + v3(); + BOOST_CHECK(global_int == 5); + + // clear() + v3.clear(); + BOOST_CHECK(v3.empty()); + + // Assignment to an empty function from a free function + v3 = &write_five; + BOOST_CHECK(!v3.empty()); + + // Invocation + global_int = 0; + v3(); + BOOST_CHECK(global_int == 5); + + // Assignment to a non-empty function from a free function + v3 = &write_three; + BOOST_CHECK(!v3.empty()); + + // Invocation + global_int = 0; + v3(); + BOOST_CHECK(global_int == 3); + + // Assignment + v3 = five; + BOOST_CHECK(!v3.empty()); + + // Invocation + global_int = 0; + v3(); + BOOST_CHECK(global_int == 5); + + // Construction of a function from a function containing a functor + func_void_type v4(v3); + + // Invocation of a function + global_int = 0; + v4(); + BOOST_CHECK(global_int == 5); + + // clear() method + v4.clear(); + BOOST_CHECK(v4.empty()); + + // Assignment to an empty function + v4 = three; + BOOST_CHECK(!v4.empty()); + + // Invocation + global_int = 0; + v4(); + BOOST_CHECK(global_int == 3); + + // Assignment to a non-empty function + v4 = five; + + // Invocation + global_int = 0; + v4(); + BOOST_CHECK(global_int == 5); + + // clear() + v4.clear(); + BOOST_CHECK(v4.empty()); + + // Assignment to an empty function from a free function + v4 = &write_five; + BOOST_CHECK(!v4.empty()); + + // Invocation + global_int = 0; + v4(); + BOOST_CHECK(global_int == 5); + + // Assignment to a non-empty function from a free function + v4 = &write_three; + BOOST_CHECK(!v4.empty()); + + // Invocation + global_int = 0; + v4(); + BOOST_CHECK(global_int == 3); + + // Assignment + v4 = five; + BOOST_CHECK(!v4.empty()); + + // Invocation + global_int = 0; + v4(); + BOOST_CHECK(global_int == 5); + + // Construction of a function from a functor + func_void_type v5(five); + + // Invocation of a function + global_int = 0; + v5(); + BOOST_CHECK(global_int == 5); + + // clear() method + v5.clear(); + BOOST_CHECK(v5.empty()); + + // Assignment to an empty function + v5 = three; + BOOST_CHECK(!v5.empty()); + + // Invocation + global_int = 0; + v5(); + BOOST_CHECK(global_int == 3); + + // Assignment to a non-empty function + v5 = five; + + // Invocation + global_int = 0; + v5(); + BOOST_CHECK(global_int == 5); + + // clear() + v5.clear(); + BOOST_CHECK(v5.empty()); + + // Assignment to an empty function from a free function + v5 = &write_five; + BOOST_CHECK(!v5.empty()); + + // Invocation + global_int = 0; + v5(); + BOOST_CHECK(global_int == 5); + + // Assignment to a non-empty function from a free function + v5 = &write_three; + BOOST_CHECK(!v5.empty()); + + // Invocation + global_int = 0; + v5(); + BOOST_CHECK(global_int == 3); + + // Assignment + v5 = five; + BOOST_CHECK(!v5.empty()); + + // Invocation + global_int = 0; + v5(); + BOOST_CHECK(global_int == 5); + + // Construction of a function from a function + func_void_type v6(&write_five); + + // Invocation of a function + global_int = 0; + v6(); + BOOST_CHECK(global_int == 5); + + // clear() method + v6.clear(); + BOOST_CHECK(v6.empty()); + + // Assignment to an empty function + v6 = three; + BOOST_CHECK(!v6.empty()); + + // Invocation + global_int = 0; + v6(); + BOOST_CHECK(global_int == 3); + + // Assignment to a non-empty function + v6 = five; + + // Invocation + global_int = 0; + v6(); + BOOST_CHECK(global_int == 5); + + // clear() + v6.clear(); + BOOST_CHECK(v6.empty()); + + // Assignment to an empty function from a free function + v6 = &write_five; + BOOST_CHECK(!v6.empty()); + + // Invocation + global_int = 0; + v6(); + BOOST_CHECK(global_int == 5); + + // Assignment to a non-empty function from a free function + v6 = &write_three; + BOOST_CHECK(!v6.empty()); + + // Invocation + global_int = 0; + v6(); + BOOST_CHECK(global_int == 3); + + // Assignment + v6 = five; + BOOST_CHECK(!v6.empty()); + + // Invocation + global_int = 0; + v6(); + BOOST_CHECK(global_int == 5); + + // Const vs. non-const + write_const_1_nonconst_2 one_or_two; + const function v7(one_or_two); + function v8(one_or_two); + + global_int = 0; + v7(); + BOOST_CHECK(global_int == 2); + + global_int = 0; + v8(); + BOOST_CHECK(global_int == 2); + + // Test construction from 0 and comparison to 0 + func_void_type v9(0); + BOOST_CHECK(v9 == 0); + BOOST_CHECK(0 == v9); + + // Test return values + typedef function func_int_type; + generate_five_obj gen_five; + generate_three_obj gen_three; + + func_int_type i0(gen_five); + + BOOST_CHECK(i0() == 5); + i0 = gen_three; + BOOST_CHECK(i0() == 3); + i0 = &generate_five; + BOOST_CHECK(i0() == 5); + i0 = &generate_three; + BOOST_CHECK(i0() == 3); + BOOST_CHECK(i0? true : false); + i0.clear(); + BOOST_CHECK(!i0? true : false); + + // Test return values with compatible types + typedef function func_long_type; + func_long_type i1(gen_five); + + BOOST_CHECK(i1() == 5); + i1 = gen_three; + BOOST_CHECK(i1() == 3); + i1 = &generate_five; + BOOST_CHECK(i1() == 5); + i1 = &generate_three; + BOOST_CHECK(i1() == 3); + BOOST_CHECK(i1? true : false); + i1.clear(); + BOOST_CHECK(!i1? true : false); +} + +static void +test_one_arg() +{ + std::negate neg; + + function f1(neg); + BOOST_CHECK(f1(5) == -5); + + function id(&identity_str); + BOOST_CHECK(id("str") == "str"); + + function id2(&identity_str); + BOOST_CHECK(id2("foo") == "foo"); + + add_to_obj add_to(5); + function f2(add_to); + BOOST_CHECK(f2(3) == 8); + + const function cf2(add_to); + BOOST_CHECK(cf2(3) == 8); +} + +static void +test_two_args() +{ + function cat(&string_cat); + BOOST_CHECK(cat("str", "ing") == "string"); + + function sum(&sum_ints); + BOOST_CHECK(sum(2, 3) == 5); +} + +static void +test_emptiness() +{ + function f1; + BOOST_CHECK(f1.empty()); + + function f2; + f2 = f1; + BOOST_CHECK(f2.empty()); + + function f3; + f3 = f2; + BOOST_CHECK(f3.empty()); +} + +struct X { + X(int v) : value(v) {} + + int twice() const { return 2*value; } + int plus(int v) { return value + v; } + + int value; +}; + +static void +test_member_functions() +{ + boost::function f1(&X::twice); + + X one(1); + X five(5); + + BOOST_CHECK(f1(&one) == 2); + BOOST_CHECK(f1(&five) == 10); + + boost::function f1_2; + f1_2 = &X::twice; + + BOOST_CHECK(f1_2(&one) == 2); + BOOST_CHECK(f1_2(&five) == 10); + + boost::function f2(&X::plus); + BOOST_CHECK(f2(one, 3) == 4); + BOOST_CHECK(f2(five, 4) == 9); +} + +struct add_with_throw_on_copy { + int operator()(int x, int y) const { return x+y; } + + add_with_throw_on_copy() {} + + add_with_throw_on_copy(const add_with_throw_on_copy&) + { + throw std::runtime_error("But this CAN'T throw"); + } + + add_with_throw_on_copy& operator=(const add_with_throw_on_copy&) + { + throw std::runtime_error("But this CAN'T throw"); + } +}; + +static void +test_ref() +{ + add_with_throw_on_copy atc; + try { + boost::function f(boost::ref(atc)); + BOOST_CHECK(f(1, 3) == 4); + } + catch(std::runtime_error const&) { + BOOST_ERROR("Nonthrowing constructor threw an exception"); + } +} + +#if BOOST_WORKAROUND(BOOST_GCC, >= 70000 && BOOST_GCC < 80000) && __cplusplus >= 201700 + +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81311 +#pragma message("Skipping test_empty_ref on g++ 7 -std=c++17") + +static void test_empty_ref() +{ +} + +#else + +static void dummy() {} + +static void test_empty_ref() +{ + boost::function f1; + boost::function f2(boost::ref(f1)); + + try { + f2(); + BOOST_ERROR("Exception didn't throw for reference to empty function."); + } + catch(std::runtime_error const&) {} + + f1 = dummy; + + try { + f2(); + } + catch(std::runtime_error const&) { + BOOST_ERROR("Error calling referenced function."); + } +} + +#endif + + +static void test_exception() +{ + boost::function f; + try { + f(5, 4); + BOOST_CHECK(false); + } + catch(boost::bad_function_call const&) { + // okay + } +} + +typedef boost::function< void * (void * reader) > reader_type; +typedef std::pair mapped_type; + +static void test_implicit() +{ + mapped_type m; + m = mapped_type(); +} + +static void test_call_obj(boost::function f) +{ + BOOST_CHECK(!f.empty()); +} + +static void test_call_cref(const boost::function& f) +{ + BOOST_CHECK(!f.empty()); +} + +static void test_call() +{ + test_call_obj(std::plus()); + test_call_cref(std::plus()); +} + +struct big_aggregating_structure { + int disable_small_objects_optimizations[32]; + + big_aggregating_structure() + { + ++ global_int; + } + + big_aggregating_structure(const big_aggregating_structure&) + { + ++ global_int; + } + + ~big_aggregating_structure() + { + -- global_int; + } + + void operator()() + { + ++ global_int; + } + + void operator()(int) + { + ++ global_int; + } +}; + +template +static void test_move_semantics() +{ + typedef FunctionT f1_type; + + big_aggregating_structure obj; + + f1_type f1 = obj; + global_int = 0; + f1(); + + BOOST_CHECK(!f1.empty()); + BOOST_CHECK(global_int == 1); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Testing rvalue constructors + f1_type f2(static_cast(f1)); + BOOST_CHECK(f1.empty()); + BOOST_CHECK(!f2.empty()); + BOOST_CHECK(global_int == 1); + f2(); + BOOST_CHECK(global_int == 2); + + f1_type f3(static_cast(f2)); + BOOST_CHECK(f1.empty()); + BOOST_CHECK(f2.empty()); + BOOST_CHECK(!f3.empty()); + BOOST_CHECK(global_int == 2); + f3(); + BOOST_CHECK(global_int == 3); + + // Testing move assignment + f1_type f4; + BOOST_CHECK(f4.empty()); + f4 = static_cast(f3); + BOOST_CHECK(f1.empty()); + BOOST_CHECK(f2.empty()); + BOOST_CHECK(f3.empty()); + BOOST_CHECK(!f4.empty()); + BOOST_CHECK(global_int == 3); + f4(); + BOOST_CHECK(global_int == 4); + + // Testing self move assignment + f4 = static_cast(f4); + BOOST_CHECK(!f4.empty()); + BOOST_CHECK(global_int == 4); + + // Testing, that no memory leaked when assigning to nonempty function + f4 = obj; + BOOST_CHECK(!f4.empty()); + BOOST_CHECK(global_int == 4); + f1_type f5 = obj; + BOOST_CHECK(global_int == 5); + f4 = static_cast(f5); + BOOST_CHECK(global_int == 4); + +#endif +} + +int main() +{ + test_zero_args(); + test_one_arg(); + test_two_args(); + test_emptiness(); + test_member_functions(); + test_ref(); + test_empty_ref(); + test_exception(); + test_implicit(); + test_call(); + test_move_semantics >(); + test_move_semantics >(); + + return boost::report_errors(); +} -- cgit v1.2.3