diff options
Diffstat (limited to 'src/boost/libs/function')
43 files changed, 3228 insertions, 0 deletions
diff --git a/src/boost/libs/function/CMakeLists.txt b/src/boost/libs/function/CMakeLists.txt new file mode 100644 index 00000000..01de5f5a --- /dev/null +++ b/src/boost/libs/function/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright 2019 Peter Dimov +# 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 + +# Partial (add_subdirectory only) and experimental CMake support +# Subject to change; please do not rely on the contents of this file yet + +cmake_minimum_required(VERSION 3.5) +project(BoostFunction LANGUAGES CXX) + +add_library(boost_function INTERFACE) +add_library(Boost::function ALIAS boost_function) + +target_include_directories(boost_function INTERFACE include) + +target_link_libraries(boost_function + INTERFACE + Boost::assert + Boost::bind + Boost::config + Boost::core + Boost::integer + Boost::preprocessor + Boost::throw_exception + Boost::type_index + Boost::type_traits + Boost::typeof +) diff --git a/src/boost/libs/function/README.md b/src/boost/libs/function/README.md new file mode 100644 index 00000000..749d5ed8 --- /dev/null +++ b/src/boost/libs/function/README.md @@ -0,0 +1,18 @@ +# Boost.Function, a polymorphic function wrapper + +[Boost.Function](http://boost.org/libs/function), part of the +[Boost C++ Libraries](http://boost.org), is the original implementation of the +polymorphic function wrapper `boost::function`, which was eventually accepted +into the C++11 standard as [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function). + +## Currently supported compilers + +* g++ 4.4 or later +* clang++ 3.3 or later +* Visual Studio 2005-2017 + +Tested on [Travis](https://travis-ci.org/boostorg/function/) and [Appveyor](https://ci.appveyor.com/project/pdimov/function/). + +## License + +Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt). diff --git a/src/boost/libs/function/example/Jamfile b/src/boost/libs/function/example/Jamfile new file mode 100644 index 00000000..671cc1da --- /dev/null +++ b/src/boost/libs/function/example/Jamfile @@ -0,0 +1,14 @@ +# Boost.Function Library example Jamfile +# +# Copyright (c) 2008 James E. King III +# +# 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 + +import ../../config/checks/config : requires ; +import testing ; + +run bind1st.cpp : : : [ requires cxx98_binders ] ; +run int_div.cpp ; +run sum_avg.cpp ; diff --git a/src/boost/libs/function/example/bind1st.cpp b/src/boost/libs/function/example/bind1st.cpp new file mode 100644 index 00000000..b9622c7f --- /dev/null +++ b/src/boost/libs/function/example/bind1st.cpp @@ -0,0 +1,32 @@ +// Boost.Function library examples + +// 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 <iostream> +#include <boost/function.hpp> +#include <functional> + +struct X { + X(int val) : value(val) {} + + int foo(int x) { return x * value; } + + int value; +}; + + +int +main() +{ + boost::function<int (int)> f; + X x(7); + f = std::bind1st(std::mem_fun(&X::foo), &x); + + std::cout << f(5) << std::endl; // Call x.foo(5) + return 0; +} diff --git a/src/boost/libs/function/example/int_div.cpp b/src/boost/libs/function/example/int_div.cpp new file mode 100644 index 00000000..7218bd03 --- /dev/null +++ b/src/boost/libs/function/example/int_div.cpp @@ -0,0 +1,26 @@ +// Boost.Function library examples + +// 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 <iostream> +#include <boost/function.hpp> + +struct int_div { + float operator()(int x, int y) const { return ((float)x)/y; }; +}; + +int +main() +{ + boost::function<float (int, int)> f; + f = int_div(); + + std::cout << f(5, 3) << std::endl; // 1.66667 + + return 0; +} diff --git a/src/boost/libs/function/example/sum_avg.cpp b/src/boost/libs/function/example/sum_avg.cpp new file mode 100644 index 00000000..8831ef11 --- /dev/null +++ b/src/boost/libs/function/example/sum_avg.cpp @@ -0,0 +1,38 @@ +// Boost.Function library examples + +// 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 <iostream> +#include <boost/function.hpp> + +void do_sum_avg(int values[], int n, int& sum, float& avg) +{ + sum = 0; + for (int i = 0; i < n; i++) + sum += values[i]; + avg = (float)sum / n; +} + +int +main() +{ + // The second parameter should be int[], but some compilers (e.g., GCC) + // complain about this + boost::function<void (int*, int, int&, float&)> sum_avg; + + sum_avg = &do_sum_avg; + + int values[5] = { 1, 1, 2, 3, 5 }; + int sum; + float avg; + sum_avg(values, 5, sum, avg); + + std::cout << "sum = " << sum << std::endl; + std::cout << "avg = " << avg << std::endl; + return 0; +} diff --git a/src/boost/libs/function/index.html b/src/boost/libs/function/index.html new file mode 100644 index 00000000..b7d40d20 --- /dev/null +++ b/src/boost/libs/function/index.html @@ -0,0 +1,20 @@ +<html> +<!-- + Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com> + + 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) + --> +<head> +<meta http-equiv="refresh" content="0; URL=../../doc/html/function.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="../../doc/html/function.html">../../doc/html/function.html</a> <hr> +<p>© Copyright Beman Dawes, 2001</p> +<p>Distributed under the Boost Software License, Version 1.0. (See accompanying +file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy +at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p> +</body> +</html>
\ No newline at end of file diff --git a/src/boost/libs/function/meta/libraries.json b/src/boost/libs/function/meta/libraries.json new file mode 100644 index 00000000..f25a9820 --- /dev/null +++ b/src/boost/libs/function/meta/libraries.json @@ -0,0 +1,18 @@ +{ + "key": "function", + "name": "Function", + "authors": [ + "Doug Gregor" + ], + "description": "Function object wrappers for deferred calls or callbacks.", + "std": [ + "tr1" + ], + "category": [ + "Function-objects", + "Programming" + ], + "maintainers": [ + "Peter Dimov <pdimov -at- pdimov.com>" + ] +} diff --git a/src/boost/libs/function/test/Jamfile.v2 b/src/boost/libs/function/test/Jamfile.v2 new file mode 100644 index 00000000..b072b5e6 --- /dev/null +++ b/src/boost/libs/function/test/Jamfile.v2 @@ -0,0 +1,75 @@ +# 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/ + +import testing ; + +run function_test.cpp ; +# /usr/include/c++/4.4/bits/shared_ptr.h:146: error: cannot use typeid with -fno-rtti +run function_test.cpp : : : <rtti>off <toolset>gcc-4.4.7,<cxxstd>0x:<build>no : function_test_no_rtti ; +run function_n_test.cpp ; +run allocator_test.cpp ; +run stateless_test.cpp ; +run lambda_test.cpp ; +compile-fail function_test_fail1.cpp ; +compile-fail function_test_fail2.cpp ; +compile function_30.cpp ; +compile function_30_repeat.cpp ; +run function_arith_cxx98.cpp ; +run function_arith_portable.cpp ; +run sum_avg_cxx98.cpp ; +run sum_avg_portable.cpp ; +run mem_fun_cxx98.cpp ; +run mem_fun_portable.cpp ; +run std_bind_cxx98.cpp ; +run std_bind_portable.cpp ; +run function_ref_cxx98.cpp ; +run function_ref_portable.cpp ; +run contains_test.cpp ; +run contains2_test.cpp ; +run nothrow_swap.cpp ; +run rvalues_test.cpp ; +compile function_typeof_test.cpp ; +run result_arg_types_test.cpp ; + +lib throw_bad_function_call : throw_bad_function_call.cpp : <link>shared:<define>THROW_BAD_FUNCTION_CALL_DYN_LINK=1 ; + +run test_bad_function_call.cpp throw_bad_function_call : : : <link>shared : test_bad_function_call_shared ; +run test_bad_function_call.cpp throw_bad_function_call : : : <link>static : test_bad_function_call_static ; + +lib mixed_cxxstd : mixed_cxxstd.cpp : <link>shared:<define>MIXED_CXXSTD_DYN_LINK=1 ; + +run test_mixed_cxxstd.cpp mixed_cxxstd : : : <link>shared : mixed_cxxstd_shared ; +run test_mixed_cxxstd.cpp mixed_cxxstd : : : <link>static : mixed_cxxstd_static ; + +run test_mixed_cxxstd.cpp mixed_cxxstd/<cxxstd>98 : : : <link>shared : mixed_cxxstd_shared_98 ; +run test_mixed_cxxstd.cpp mixed_cxxstd/<cxxstd>98 : : : <link>static : mixed_cxxstd_static_98 ; + +run test_mixed_cxxstd.cpp mixed_cxxstd/<cxxstd>0x : : : <link>shared : mixed_cxxstd_shared_0x ; +run test_mixed_cxxstd.cpp mixed_cxxstd/<cxxstd>0x : : : <link>static : mixed_cxxstd_static_0x ; + +local check14 = [ check-target-builds mixed_cxxstd/<cxxstd>14 : : <build>no ] ; + +run test_mixed_cxxstd.cpp mixed_cxxstd/<cxxstd>14 : : : <link>shared $(check14) : mixed_cxxstd_shared_14 ; +run test_mixed_cxxstd.cpp mixed_cxxstd/<cxxstd>14 : : : <link>static $(check14) : mixed_cxxstd_static_14 ; + +lib return_function : return_function.cpp : <link>shared:<define>RETURN_FUNCTION_DYN_LINK=1 ; + +run test_return_function.cpp return_function : : : <link>shared : return_function_shared ; +run test_return_function.cpp return_function : : : <link>static : return_function_static ; + +run test_return_function.cpp return_function/<cxxstd>98 : : : <link>shared : return_function_shared_98 ; +run test_return_function.cpp return_function/<cxxstd>98 : : : <link>static : return_function_static_98 ; + +run test_return_function.cpp return_function/<cxxstd>0x : : : <link>shared : return_function_shared_0x ; +run test_return_function.cpp return_function/<cxxstd>0x : : : <link>static : return_function_static_0x ; + +run test_return_function.cpp return_function/<cxxstd>14 : : : <link>shared $(check14) : return_function_shared_14 ; +run test_return_function.cpp return_function/<cxxstd>14 : : : <link>static $(check14) : return_function_static_14 ; + +run quick.cpp ; diff --git a/src/boost/libs/function/test/allocator_test.cpp b/src/boost/libs/function/test/allocator_test.cpp new file mode 100644 index 00000000..a09f067c --- /dev/null +++ b/src/boost/libs/function/test/allocator_test.cpp @@ -0,0 +1,136 @@ +// 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 <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> +#include <cassert> +#include <functional> + +using namespace std; +using namespace boost; + +static int alloc_count = 0; +static int dealloc_count = 0; + +template<typename T> +struct counting_allocator : public std::allocator<T> +{ + template<typename U> + struct rebind + { + typedef counting_allocator<U> other; + }; + + counting_allocator() + { + } + + template<typename U> + counting_allocator( counting_allocator<U> ) + { + } + + T* allocate(std::size_t n) + { + alloc_count++; + return std::allocator<T>::allocate(n); + } + + void deallocate(T* p, std::size_t n) + { + dealloc_count++; + std::allocator<T>::deallocate(p, n); + } +}; + +struct enable_small_object_optimization +{ +}; + +struct disable_small_object_optimization +{ + int unused_state_data[32]; +}; + +template <typename base> +struct plus_int: base +{ + int operator()(int x, int y) const { return x + y; } +}; + +static int do_minus(int x, int y) { return x-y; } + +template <typename base> +struct DoNothing: base +{ + void operator()() const {} +}; + +static void do_nothing() {} + +int main() +{ + function2<int, int, int> f; + f.assign( plus_int<disable_small_object_optimization>(), counting_allocator<int>() ); + f.clear(); + BOOST_TEST_EQ( alloc_count, 1 ); + BOOST_TEST_EQ( dealloc_count, 1 ); + alloc_count = 0; + dealloc_count = 0; + f.assign( plus_int<enable_small_object_optimization>(), counting_allocator<int>() ); + f.clear(); + BOOST_TEST_EQ( alloc_count, 0 ); + BOOST_TEST_EQ( dealloc_count, 0 ); + f.assign( plus_int<disable_small_object_optimization>(), std::allocator<int>() ); + f.clear(); + f.assign( plus_int<enable_small_object_optimization>(), std::allocator<int>() ); + f.clear(); + + alloc_count = 0; + dealloc_count = 0; + f.assign( &do_minus, counting_allocator<int>() ); + f.clear(); + BOOST_TEST_EQ( alloc_count, 0 ); + BOOST_TEST_EQ( dealloc_count, 0 ); + f.assign( &do_minus, std::allocator<int>() ); + f.clear(); + + function0<void> fv; + alloc_count = 0; + dealloc_count = 0; + fv.assign( DoNothing<disable_small_object_optimization>(), counting_allocator<int>() ); + fv.clear(); + BOOST_TEST_EQ( alloc_count, 1 ); + BOOST_TEST_EQ( dealloc_count, 1 ); + alloc_count = 0; + dealloc_count = 0; + fv.assign( DoNothing<enable_small_object_optimization>(), counting_allocator<int>() ); + fv.clear(); + BOOST_TEST_EQ( alloc_count, 0 ); + BOOST_TEST_EQ( dealloc_count, 0 ); + fv.assign( DoNothing<disable_small_object_optimization>(), std::allocator<int>() ); + fv.clear(); + fv.assign( DoNothing<enable_small_object_optimization>(), std::allocator<int>() ); + fv.clear(); + + alloc_count = 0; + dealloc_count = 0; + fv.assign( &do_nothing, counting_allocator<int>() ); + fv.clear(); + BOOST_TEST_EQ( alloc_count, 0 ); + BOOST_TEST_EQ( dealloc_count, 0 ); + fv.assign( &do_nothing, std::allocator<int>() ); + fv.clear(); + + function0<void> fv2; + fv.assign(&do_nothing, std::allocator<int>() ); + fv2.assign(fv, std::allocator<int>() ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/cmake_subdir_test/CMakeLists.txt b/src/boost/libs/function/test/cmake_subdir_test/CMakeLists.txt new file mode 100644 index 00000000..e27bcb22 --- /dev/null +++ b/src/boost/libs/function/test/cmake_subdir_test/CMakeLists.txt @@ -0,0 +1,49 @@ +# Copyright 2018, 2019 Peter Dimov +# 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 + +cmake_minimum_required(VERSION 3.5) + +project(cmake_subdir_test LANGUAGES CXX) + +add_subdirectory(../.. boostorg/function) + +# boost_add_subdir + +function(boost_add_subdir name) + + add_subdirectory(../../../${name} boostorg/${name}) + +endfunction() + +# primary dependencies + +boost_add_subdir(assert) +boost_add_subdir(bind) +boost_add_subdir(config) +boost_add_subdir(core) +boost_add_subdir(integer) +boost_add_subdir(preprocessor) +boost_add_subdir(throw_exception) +boost_add_subdir(type_index) +boost_add_subdir(type_traits) +boost_add_subdir(typeof) + +# secondary dependencies + +boost_add_subdir(static_assert) +boost_add_subdir(container_hash) +boost_add_subdir(smart_ptr) +boost_add_subdir(detail) +boost_add_subdir(move) +boost_add_subdir(predef) + +# --target check + +add_executable(quick ../quick.cpp) +target_link_libraries(quick Boost::function Boost::core) + +enable_testing() +add_test(quick quick) + +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>) diff --git a/src/boost/libs/function/test/contains2_test.cpp b/src/boost/libs/function/test/contains2_test.cpp new file mode 100644 index 00000000..9cfa5c34 --- /dev/null +++ b/src/boost/libs/function/test/contains2_test.cpp @@ -0,0 +1,88 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2004. +// Copyright 2005 Peter Dimov + +// 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) + +#include <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> + +static int forty_two() +{ + return 42; +} + +struct Seventeen +{ + int operator()() const + { + return 17; + } +}; + +bool operator==(const Seventeen&, const Seventeen&) +{ + return true; +} + +struct ReturnInt +{ + explicit ReturnInt(int value) : value(value) + { + } + + int operator()() const + { + return value; + } + + int value; +}; + +bool operator==(const ReturnInt& x, const ReturnInt& y) +{ + return x.value == y.value; +} + +bool operator!=(const ReturnInt& x, const ReturnInt& y) +{ + return x.value != y.value; +} + +int main() +{ + boost::function0<int> fn; + + fn = &forty_two; + + BOOST_TEST( fn() == 42 ); + + BOOST_TEST( fn.contains(&forty_two) ); + BOOST_TEST( !fn.contains( Seventeen() ) ); + BOOST_TEST( !fn.contains( ReturnInt(0) ) ); + BOOST_TEST( !fn.contains( ReturnInt(12) ) ); + + fn = Seventeen(); + + BOOST_TEST( fn() == 17 ); + + BOOST_TEST( !fn.contains( &forty_two ) ); + BOOST_TEST( fn.contains( Seventeen() ) ); + BOOST_TEST( !fn.contains( ReturnInt(0) ) ); + BOOST_TEST( !fn.contains( ReturnInt(12) ) ); + + fn = ReturnInt(12); + + BOOST_TEST( fn() == 12 ); + + BOOST_TEST( !fn.contains( &forty_two ) ); + BOOST_TEST( !fn.contains( Seventeen() ) ); + BOOST_TEST( !fn.contains( ReturnInt(0) ) ); + BOOST_TEST( fn.contains( ReturnInt(12) ) ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/contains_test.cpp b/src/boost/libs/function/test/contains_test.cpp new file mode 100644 index 00000000..91e10ab7 --- /dev/null +++ b/src/boost/libs/function/test/contains_test.cpp @@ -0,0 +1,237 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2004. 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) + +#include <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/ref.hpp> + +#define BOOST_CHECK BOOST_TEST + +static int forty_two() { return 42; } + +struct Seventeen +{ + int operator()() const { return 17; } +}; + +struct ReturnInt +{ + explicit ReturnInt(int value) : value(value) {} + + int operator()() const { return value; } + + int value; +}; + +bool operator==(const ReturnInt& x, const ReturnInt& y) +{ return x.value == y.value; } + +bool operator!=(const ReturnInt& x, const ReturnInt& y) +{ return x.value != y.value; } + +namespace contain_test { + +struct ReturnIntFE +{ + explicit ReturnIntFE(int value) : value(value) {} + + int operator()() const { return value; } + + int value; +}; + +} + +#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +namespace contain_test { +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +bool function_equal(const ReturnIntFE& x, const ReturnIntFE& y) +{ return x.value == y.value; } +# else +bool function_equal_impl(const ReturnIntFE& x, const ReturnIntFE& y, int) +{ return x.value == y.value; } +# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +} +#else // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +namespace boost { +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +bool +function_equal(const contain_test::ReturnIntFE& x, + const contain_test::ReturnIntFE& y) +{ return x.value == y.value; } +# else +bool +function_equal_impl(const contain_test::ReturnIntFE& x, + const contain_test::ReturnIntFE& y, int) +{ return x.value == y.value; } +# endif +} +#endif + +static void target_test() +{ + boost::function0<int> f; + + f = &forty_two; + BOOST_CHECK(*f.target<int (*)()>() == &forty_two); + BOOST_CHECK(!f.target<Seventeen>()); + + f = Seventeen(); + BOOST_CHECK(!f.target<int (*)()>()); + BOOST_CHECK(f.target<Seventeen>()); + + Seventeen this_seventeen; + f = boost::ref(this_seventeen); + BOOST_CHECK(!f.target<int (*)()>()); + BOOST_CHECK(f.target<Seventeen>()); + BOOST_CHECK(f.target<Seventeen>() == &this_seventeen); + + const Seventeen const_seventeen = this_seventeen; + f = boost::ref(const_seventeen); + BOOST_CHECK(!f.target<int (*)()>()); + BOOST_CHECK(f.target<const Seventeen>()); + BOOST_CHECK(f.target<const Seventeen>() == &const_seventeen); + BOOST_CHECK(f.target<const volatile Seventeen>()); + BOOST_CHECK(!f.target<Seventeen>()); + BOOST_CHECK(!f.target<volatile Seventeen>()); +} + +static void equal_test() +{ + boost::function0<int> f; + + f = &forty_two; + BOOST_CHECK(f == &forty_two); + BOOST_CHECK(f != ReturnInt(17)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(&forty_two == f); + BOOST_CHECK(ReturnInt(17) != f); +#endif + + BOOST_CHECK(f.contains(&forty_two)); + + f = ReturnInt(17); + BOOST_CHECK(f != &forty_two); + BOOST_CHECK(f == ReturnInt(17)); + BOOST_CHECK(f != ReturnInt(16)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(&forty_two != f); + BOOST_CHECK(ReturnInt(17) == f); + BOOST_CHECK(ReturnInt(16) != f); +#endif + + BOOST_CHECK(f.contains(ReturnInt(17))); + + f = contain_test::ReturnIntFE(17); + BOOST_CHECK(f != &forty_two); + BOOST_CHECK(f == contain_test::ReturnIntFE(17)); + BOOST_CHECK(f != contain_test::ReturnIntFE(16)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(&forty_two != f); + BOOST_CHECK(contain_test::ReturnIntFE(17) == f); + BOOST_CHECK(contain_test::ReturnIntFE(16) != f); +#endif + + BOOST_CHECK(f.contains(contain_test::ReturnIntFE(17))); + +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) + boost::function<int(void)> g; + + g = &forty_two; + BOOST_CHECK(g == &forty_two); + BOOST_CHECK(g != ReturnInt(17)); +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(&forty_two == g); + BOOST_CHECK(ReturnInt(17) != g); +# endif + + g = ReturnInt(17); + BOOST_CHECK(g != &forty_two); + BOOST_CHECK(g == ReturnInt(17)); + BOOST_CHECK(g != ReturnInt(16)); +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(&forty_two != g); + BOOST_CHECK(ReturnInt(17) == g); + BOOST_CHECK(ReturnInt(16) != g); +# endif +#endif +} + +static void ref_equal_test() +{ + { + ReturnInt ri(17); + boost::function0<int> f = boost::ref(ri); + + // References and values are equal + BOOST_CHECK(f == boost::ref(ri)); + BOOST_CHECK(f == ri); + BOOST_CHECK(boost::ref(ri) == f); + BOOST_CHECK(!(f != boost::ref(ri))); + BOOST_CHECK(!(f != ri)); + BOOST_CHECK(!(boost::ref(ri) != f)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(ri == f); + BOOST_CHECK(!(ri != f)); +#endif + + // Values equal, references inequal + ReturnInt ri2(17); + BOOST_CHECK(f == ri2); + BOOST_CHECK(f != boost::ref(ri2)); + BOOST_CHECK(boost::ref(ri2) != f); + BOOST_CHECK(!(f != ri2)); + BOOST_CHECK(!(f == boost::ref(ri2))); + BOOST_CHECK(!(boost::ref(ri2) == f)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(ri2 == f); + BOOST_CHECK(!(ri2 != f)); +#endif + } + +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) + { + ReturnInt ri(17); + boost::function<int(void)> f = boost::ref(ri); + + // References and values are equal + BOOST_CHECK(f == boost::ref(ri)); + BOOST_CHECK(f == ri); + BOOST_CHECK(boost::ref(ri) == f); + BOOST_CHECK(!(f != boost::ref(ri))); + BOOST_CHECK(!(f != ri)); + BOOST_CHECK(!(boost::ref(ri) != f)); +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(ri == f); + BOOST_CHECK(!(ri != f)); +# endif + + // Values equal, references inequal + ReturnInt ri2(17); + BOOST_CHECK(f == ri2); + BOOST_CHECK(f != boost::ref(ri2)); + BOOST_CHECK(boost::ref(ri2) != f); + BOOST_CHECK(!(f != ri2)); + BOOST_CHECK(!(f == boost::ref(ri2))); + BOOST_CHECK(!(boost::ref(ri2) == f)); +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_CHECK(ri2 == f); + BOOST_CHECK(!(ri2 != f)); +# endif + } +#endif +} + +int main() +{ + target_test(); + equal_test(); + ref_equal_test(); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/function_30.cpp b/src/boost/libs/function/test/function_30.cpp new file mode 100644 index 00000000..0b91b75b --- /dev/null +++ b/src/boost/libs/function/test/function_30.cpp @@ -0,0 +1,25 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-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 + +// Make sure we don't try to redefine function2 +#include <boost/function/function2.hpp> + +// Define all Boost.Function class templates up to 30 arguments +#define BOOST_FUNCTION_MAX_ARGS 30 +#include <boost/function.hpp> + +int main() +{ + boost::function0<float> f0; + + boost::function30<float, int, int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, int> f30; + return 0; +} diff --git a/src/boost/libs/function/test/function_30_repeat.cpp b/src/boost/libs/function/test/function_30_repeat.cpp new file mode 100644 index 00000000..b8107063 --- /dev/null +++ b/src/boost/libs/function/test/function_30_repeat.cpp @@ -0,0 +1,35 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-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 + +// Make sure we don't try to redefine function2 +#include <boost/function/function2.hpp> + +// Define all Boost.Function class templates up to 30 arguments +#define BOOST_FUNCTION_MAX_ARGS 20 +#include <boost/function.hpp> +#undef BOOST_FUNCTION_MAX_ARGS +#define BOOST_FUNCTION_MAX_ARGS 40 +#include <boost/function.hpp> +#undef BOOST_FUNCTION_MAX_ARGS +#define BOOST_FUNCTION_MAX_ARGS 25 +#include <boost/function.hpp> +#undef BOOST_FUNCTION_MAX_ARGS +#define BOOST_FUNCTION_MAX_ARGS 30 +#include <boost/function.hpp> +#include <boost/function.hpp> + +int main() +{ + boost::function0<float> f0; + + boost::function30<float, int, int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, int> f30; + return 0; +} diff --git a/src/boost/libs/function/test/function_arith_cxx98.cpp b/src/boost/libs/function/test/function_arith_cxx98.cpp new file mode 100644 index 00000000..40297643 --- /dev/null +++ b/src/boost/libs/function/test/function_arith_cxx98.cpp @@ -0,0 +1,34 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <iostream> + + +float mul_ints(int x, int y) { return ((float)x) * y; } +struct int_div { + float operator()(int x, int y) const { return ((float)x)/y; }; +}; + +int main() +{ + boost::function<float (int x, int y)> f; + f = int_div(); + std::cout << f(5, 3) << std::endl; + if (f) + std::cout << f(5, 3) << std::endl; +else + std::cout << "f has no target, so it is unsafe to call" << std::endl; + f = 0; + f = &mul_ints; + + return 0; +} diff --git a/src/boost/libs/function/test/function_arith_portable.cpp b/src/boost/libs/function/test/function_arith_portable.cpp new file mode 100644 index 00000000..24af62c9 --- /dev/null +++ b/src/boost/libs/function/test/function_arith_portable.cpp @@ -0,0 +1,32 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <iostream> + +float mul_ints(int x, int y) { return ((float)x) * y; } +struct int_div { + float operator()(int x, int y) const { return ((float)x)/y; }; +}; +int main() +{ + boost::function2<float, int, int> f; + f = int_div(); + std::cout << f(5, 3) << std::endl; + if (f) + std::cout << f(5, 3) << std::endl; +else + std::cout << "f has no target, so it is unsafe to call" << std::endl; + f = 0; + f = &mul_ints; + + return 0; +} diff --git a/src/boost/libs/function/test/function_n_test.cpp b/src/boost/libs/function/test/function_n_test.cpp new file mode 100644 index 00000000..418c46fd --- /dev/null +++ b/src/boost/libs/function/test/function_n_test.cpp @@ -0,0 +1,699 @@ +// 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 <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> +#include <functional> +#include <cassert> +#include <string> + +#define BOOST_CHECK BOOST_TEST + +using namespace boost; +using std::string; +using std::negate; + +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 function0<void> func_void_type; + + write_five_obj five = write_five_obj(); // Initialization for Borland C++ 5.5 + write_three_obj three = write_three_obj(); // Ditto + + // Default construction + func_void_type v1; + BOOST_CHECK(v1.empty()); + + // Assignment to an empty function + v1 = five; + BOOST_CHECK(!v1.empty()); + + // Invocation of a function + global_int = 0; + v1(); + BOOST_CHECK(global_int == 5); + + // clear() method + v1.clear(); + BOOST_CHECK(!v1); + + // 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(v1.empty()); + + // Assignment to an empty function from a free function + v1 = &write_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); + + // 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 = (&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 = &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 = &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 + // Initialization for Borland C++ 5.5 + write_const_1_nonconst_2 one_or_two = write_const_1_nonconst_2(); + const function0<void> v7(one_or_two); + function0<void> 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); +# if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540 || defined(BOOST_STRICT_CONFIG) + BOOST_CHECK(0 == v9); +#else + BOOST_CHECK(v9.empty()); +#endif + + // Test return values + typedef function0<int> func_int_type; + // Initialization for Borland C++ 5.5 + generate_five_obj gen_five = generate_five_obj(); + generate_three_obj gen_three = generate_three_obj(); + 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 function0<long> 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() +{ + negate<int> neg = negate<int>(); // Initialization for Borland C++ 5.5 + + function1<int, int> f1(neg); + BOOST_CHECK(f1(5) == -5); + + function1<string, string> id(&identity_str); + BOOST_CHECK(id("str") == "str"); + + function1<std::string, const char*> id2(&identity_str); + BOOST_CHECK(id2("foo") == "foo"); + + add_to_obj add_to(5); + function1<int, int> f2(add_to); + BOOST_CHECK(f2(3) == 8); + + const function1<int, int> cf2(add_to); + BOOST_CHECK(cf2(3) == 8); +} + +static void +test_two_args() +{ + function2<string, const string&, const string&> cat(&string_cat); + BOOST_CHECK(cat("str", "ing") == "string"); + + function2<int, short, short> sum(&sum_ints); + BOOST_CHECK(sum(2, 3) == 5); +} + +static void +test_emptiness() +{ + function0<float> f1; + BOOST_CHECK(f1.empty()); + + function0<float> f2; + f2 = f1; + BOOST_CHECK(f2.empty()); + + function0<double> 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::function1<int, X*> f1(&X::twice); + + X one(1); + X five(5); + + BOOST_CHECK(f1(&one) == 2); + BOOST_CHECK(f1(&five) == 10); + + boost::function1<int, X*> f1_2; + f1_2 = &X::twice; + + BOOST_CHECK(f1_2(&one) == 2); + BOOST_CHECK(f1_2(&five) == 10); + + boost::function2<int, X&, int> 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::function2<int, int, int> f(ref(atc)); + BOOST_CHECK(f(1, 3) == 4); + } + catch(std::runtime_error const&) { + BOOST_ERROR("Nonthrowing constructor threw an exception"); + } +} + +static unsigned construction_count = 0; +static unsigned destruction_count = 0; + +struct MySmallFunctor { + MySmallFunctor() { ++construction_count; } + MySmallFunctor(const MySmallFunctor &) { ++construction_count; } + ~MySmallFunctor() { ++destruction_count; } + int operator()() { return 0; } + }; + +struct MyLargeFunctor { + MyLargeFunctor() { ++construction_count; } + MyLargeFunctor(const MyLargeFunctor &) { ++construction_count; } + ~MyLargeFunctor() { ++destruction_count; } + int operator()() { return 0; } + + float data[128]; + }; + +void test_construct_destroy_count() +{ + { + boost::function0<int> f; + boost::function0<int> g; + f = MySmallFunctor(); + g = MySmallFunctor(); + f.swap(g); + } + + // MySmallFunctor objects should be constructed as many times as + // they are destroyed. + BOOST_CHECK(construction_count == destruction_count); + + construction_count = 0; + destruction_count = 0; + { + boost::function0<int> f; + boost::function0<int> g; + f = MyLargeFunctor(); + g = MyLargeFunctor(); + f.swap(g); + } + + // MyLargeFunctor objects should be constructed as many times as + // they are destroyed. + BOOST_CHECK(construction_count == destruction_count); +} + +int main() +{ + test_zero_args(); + test_one_arg(); + test_two_args(); + test_emptiness(); + test_member_functions(); + test_ref(); + test_construct_destroy_count(); + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/function_ref_cxx98.cpp b/src/boost/libs/function/test/function_ref_cxx98.cpp new file mode 100644 index 00000000..94f5ec34 --- /dev/null +++ b/src/boost/libs/function/test/function_ref_cxx98.cpp @@ -0,0 +1,27 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <iostream> + + +struct stateful_type { int operator()(int) const { return 0; } }; + +int main() +{ + stateful_type a_function_object; + boost::function<int (int)> f; + f = boost::ref(a_function_object); + + boost::function<int (int)> f2(f); + + return 0; +} diff --git a/src/boost/libs/function/test/function_ref_portable.cpp b/src/boost/libs/function/test/function_ref_portable.cpp new file mode 100644 index 00000000..35beb10a --- /dev/null +++ b/src/boost/libs/function/test/function_ref_portable.cpp @@ -0,0 +1,27 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <iostream> + + +struct stateful_type { int operator()(int) const { return 0; } }; + +int main() +{ + stateful_type a_function_object; + boost::function1<int, int> f; + f = boost::ref(a_function_object); + + boost::function1<int, int> f2(f); + + return 0; +} 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 00000000..88747e01 --- /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 <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> +#include <functional> +#include <string> +#include <utility> + +#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<void ()> 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<void ()> v7(one_or_two); + function<void ()> 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<int ()> 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<long ()> 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<int> neg; + + function<int (int)> f1(neg); + BOOST_CHECK(f1(5) == -5); + + function<string (string)> id(&identity_str); + BOOST_CHECK(id("str") == "str"); + + function<string (const char*)> id2(&identity_str); + BOOST_CHECK(id2("foo") == "foo"); + + add_to_obj add_to(5); + function<int (int)> f2(add_to); + BOOST_CHECK(f2(3) == 8); + + const function<int (int)> cf2(add_to); + BOOST_CHECK(cf2(3) == 8); +} + +static void +test_two_args() +{ + function<string (const string&, const string&)> cat(&string_cat); + BOOST_CHECK(cat("str", "ing") == "string"); + + function<int (short, short)> sum(&sum_ints); + BOOST_CHECK(sum(2, 3) == 5); +} + +static void +test_emptiness() +{ + function<float ()> f1; + BOOST_CHECK(f1.empty()); + + function<float ()> f2; + f2 = f1; + BOOST_CHECK(f2.empty()); + + function<double ()> 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<int (X*)> f1(&X::twice); + + X one(1); + X five(5); + + BOOST_CHECK(f1(&one) == 2); + BOOST_CHECK(f1(&five) == 10); + + boost::function<int (X*)> f1_2; + f1_2 = &X::twice; + + BOOST_CHECK(f1_2(&one) == 2); + BOOST_CHECK(f1_2(&five) == 10); + + boost::function<int (X&, int)> 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<int (int, int)> 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<void()> f1; + boost::function<void()> 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<int (int, int)> 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<int, reader_type> mapped_type; + +static void test_implicit() +{ + mapped_type m; + m = mapped_type(); +} + +static void test_call_obj(boost::function<int (int, int)> f) +{ + BOOST_CHECK(!f.empty()); +} + +static void test_call_cref(const boost::function<int (int, int)>& f) +{ + BOOST_CHECK(!f.empty()); +} + +static void test_call() +{ + test_call_obj(std::plus<int>()); + test_call_cref(std::plus<int>()); +} + +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 <class FunctionT> +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_type&&>(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<f1_type&&>(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<f1_type&&>(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<f1_type&&>(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<f1_type&&>(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<function<void()> >(); + test_move_semantics<boost::function0<void> >(); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/function_test_fail1.cpp b/src/boost/libs/function/test/function_test_fail1.cpp new file mode 100644 index 00000000..0b84cc7d --- /dev/null +++ b/src/boost/libs/function/test/function_test_fail1.cpp @@ -0,0 +1,18 @@ +// Boost.Function library + +// Copyright (C) Douglas Gregor 2001-2005. 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 <boost/function.hpp> + +void test() +{ + boost::function0<int> f1; + boost::function0<int> f2; + + if( f1 == f2 ) {} +} diff --git a/src/boost/libs/function/test/function_test_fail2.cpp b/src/boost/libs/function/test/function_test_fail2.cpp new file mode 100644 index 00000000..d113e457 --- /dev/null +++ b/src/boost/libs/function/test/function_test_fail2.cpp @@ -0,0 +1,18 @@ +// Boost.Function library + +// Copyright (C) Douglas Gregor 2001-2005. 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 <boost/function.hpp> + +static int bad_fn(float f) { return static_cast<int>(f); } + +void test() +{ + boost::function0<int> f1; + f1 = bad_fn; +} diff --git a/src/boost/libs/function/test/function_typeof_test.cpp b/src/boost/libs/function/test/function_typeof_test.cpp new file mode 100644 index 00000000..2d77cabf --- /dev/null +++ b/src/boost/libs/function/test/function_typeof_test.cpp @@ -0,0 +1,18 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2008. 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 <boost/function/function_typeof.hpp> +#include <boost/function.hpp> +#include <boost/typeof/typeof.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/static_assert.hpp> + +void f(boost::function0<void> f, boost::function0<void> g) +{ + BOOST_STATIC_ASSERT((boost::is_same<boost::function0<void>, BOOST_TYPEOF(f = g)>::value)); +} diff --git a/src/boost/libs/function/test/lambda_test.cpp b/src/boost/libs/function/test/lambda_test.cpp new file mode 100644 index 00000000..7def0fa5 --- /dev/null +++ b/src/boost/libs/function/test/lambda_test.cpp @@ -0,0 +1,40 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-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 <boost/function.hpp> +#include <boost/lambda/lambda.hpp> +#include <boost/lambda/bind.hpp> +#include <boost/core/lightweight_test.hpp> +#include <iostream> +#include <cstdlib> + + +static unsigned +func_impl(int arg1, bool arg2, double arg3) +{ + using namespace std; + return abs (static_cast<int>((arg2 ? arg1 : 2 * arg1) * arg3)); +} + +int main() +{ + using boost::function; + using namespace boost::lambda; + + function <unsigned(bool, double)> f1 = bind(func_impl, 15, _1, _2); + BOOST_TEST_EQ( f1(true, 2.0), 30 ); + + function <unsigned(double)> f2 = boost::lambda::bind(f1, false, _1); + BOOST_TEST_EQ( f2(2.0), 60 ); + + function <unsigned()> f3 = boost::lambda::bind(f2, 4.0); + BOOST_TEST_EQ( f3(), 120 ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/mem_fun_cxx98.cpp b/src/boost/libs/function/test/mem_fun_cxx98.cpp new file mode 100644 index 00000000..92740363 --- /dev/null +++ b/src/boost/libs/function/test/mem_fun_cxx98.cpp @@ -0,0 +1,45 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> +#include <iostream> +#include <functional> + +struct Y { + Y(int y = 0) : y_(y) {} + bool operator==(const Y& rhs) { return y_ == rhs.y_; } +private: + int y_; + }; + +struct X { + int foo(int); + Y& foo2(Y&) const; +}; +int X::foo(int x) { return -x; } +Y& X::foo2(Y& x) const { return x; } + +int main() +{ + boost::function<int (X*, int)> f; + boost::function<Y& (X*, Y&)> f2; + Y y1; + + f = &X::foo; + f2 = &X::foo2; + + X x; + BOOST_TEST(f(&x, 5) == -5); + BOOST_TEST(f2(&x, boost::ref(y1)) == y1); + + return ::boost::report_errors(); +} diff --git a/src/boost/libs/function/test/mem_fun_portable.cpp b/src/boost/libs/function/test/mem_fun_portable.cpp new file mode 100644 index 00000000..e12fd08a --- /dev/null +++ b/src/boost/libs/function/test/mem_fun_portable.cpp @@ -0,0 +1,45 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> +#include <iostream> +#include <functional> + +struct Y { + Y(int y = 0) : y_(y) {} + bool operator==(const Y& rhs) { return y_ == rhs.y_; } +private: + int y_; + }; + +struct X { + int foo(int); + Y& foo2(Y&) const; +}; +int X::foo(int x) { return -x; } +Y& X::foo2(Y& x) const { return x; } + +int main() +{ + boost::function2<int, X*, int> f; + boost::function2<Y&, X*, Y&> f2; + Y y1; + + f = &X::foo; + f2 = &X::foo2; + + X x; + BOOST_TEST(f(&x, 5) == -5); + BOOST_TEST(f2(&x, boost::ref(y1)) == y1); + + return ::boost::report_errors(); +} diff --git a/src/boost/libs/function/test/mixed_cxxstd.cpp b/src/boost/libs/function/test/mixed_cxxstd.cpp new file mode 100644 index 00000000..417037aa --- /dev/null +++ b/src/boost/libs/function/test/mixed_cxxstd.cpp @@ -0,0 +1,42 @@ + +// Copyright 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. + +#include <boost/function.hpp> +#include <boost/config.hpp> + +#if defined(MIXED_CXXSTD_DYN_LINK) +# define EXPORT BOOST_SYMBOL_EXPORT +#else +# define EXPORT +#endif + +EXPORT void call_fn_1( boost::function<void()> const & fn ) +{ + fn(); +} + +EXPORT void call_fn_2( boost::function<void(int)> const & fn ) +{ + fn( 1 ); +} + +EXPORT void call_fn_3( boost::function<void(int, int)> const & fn ) +{ + fn( 1, 2 ); +} + +EXPORT void call_fn_4( boost::function0<void> const & fn ) +{ + fn(); +} + +EXPORT void call_fn_5( boost::function1<void, int> const & fn ) +{ + fn( 1 ); +} + +EXPORT void call_fn_6( boost::function2<void, int, int> const & fn ) +{ + fn( 1, 2 ); +} diff --git a/src/boost/libs/function/test/nothrow_swap.cpp b/src/boost/libs/function/test/nothrow_swap.cpp new file mode 100644 index 00000000..8b1b6dc8 --- /dev/null +++ b/src/boost/libs/function/test/nothrow_swap.cpp @@ -0,0 +1,62 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2008. 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 <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> + +#define BOOST_CHECK BOOST_TEST + +struct tried_to_copy { }; + +struct MaybeThrowOnCopy { + MaybeThrowOnCopy(int value = 0) : value(value) { } + + MaybeThrowOnCopy(const MaybeThrowOnCopy& other) : value(other.value) { + if (throwOnCopy) + throw tried_to_copy(); + } + + MaybeThrowOnCopy& operator=(const MaybeThrowOnCopy& other) { + if (throwOnCopy) + throw tried_to_copy(); + value = other.value; + return *this; + } + + int operator()() { return value; } + + int value; + + // Make sure that this function object doesn't trigger the + // small-object optimization in Function. + float padding[100]; + + static bool throwOnCopy; +}; + +bool MaybeThrowOnCopy::throwOnCopy = false; + +int main() +{ + boost::function0<int> f; + boost::function0<int> g; + + MaybeThrowOnCopy::throwOnCopy = false; + f = MaybeThrowOnCopy(1); + g = MaybeThrowOnCopy(2); + BOOST_CHECK(f() == 1); + BOOST_CHECK(g() == 2); + + MaybeThrowOnCopy::throwOnCopy = true; + f.swap(g); + BOOST_CHECK(f() == 2); + BOOST_CHECK(g() == 1); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/quick.cpp b/src/boost/libs/function/test/quick.cpp new file mode 100644 index 00000000..d2d37d06 --- /dev/null +++ b/src/boost/libs/function/test/quick.cpp @@ -0,0 +1,21 @@ +// Copyright 2019 Peter Dimov + +// 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 + +#include <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> + +static int f( int x ) +{ + return x + 1; +} + +int main() +{ + boost::function<int(int)> fn( f ); + + BOOST_TEST_EQ( fn( 5 ), 6 ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/regression.cfg b/src/boost/libs/function/test/regression.cfg new file mode 100644 index 00000000..7e442538 --- /dev/null +++ b/src/boost/libs/function/test/regression.cfg @@ -0,0 +1,14 @@ +// Boost.Function regression test configuration file + +// From the boost/status directory, run +// ./regression --tests ../libs/function/test/regression.cfg -o function.html + + +run libs/function/test/allocator_test.cpp +run libs/function/test/function_n_test.cpp +run libs/function/test/function_test.cpp +compile-fail libs/function/test/function_test_fail1.cpp +compile-fail libs/function/test/function_test_fail2.cpp +run libs/function/test/mixin_test.cpp +run libs/function/test/policy_test.cpp +run libs/function/test/stateless_test.cpp diff --git a/src/boost/libs/function/test/result_arg_types_test.cpp b/src/boost/libs/function/test/result_arg_types_test.cpp new file mode 100644 index 00000000..33ccddcd --- /dev/null +++ b/src/boost/libs/function/test/result_arg_types_test.cpp @@ -0,0 +1,40 @@ +// Boost.Function library + +// Copyright 2016 Peter Dimov + +// 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) + +#include <boost/function.hpp> +#include <boost/core/is_same.hpp> +#include <boost/core/lightweight_test_trait.hpp> + +struct X +{ +}; + +struct Y +{ +}; + +struct Z +{ +}; + +int main() +{ + typedef boost::function<X(Y)> F1; + + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same<F1::result_type, X> )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same<F1::argument_type, Y> )); + + typedef boost::function<X(Y, Z)> F2; + + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same<F2::result_type, X> )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same<F2::first_argument_type, Y> )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same<F2::second_argument_type, Z> )); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/return_function.cpp b/src/boost/libs/function/test/return_function.cpp new file mode 100644 index 00000000..3fca7bbd --- /dev/null +++ b/src/boost/libs/function/test/return_function.cpp @@ -0,0 +1,27 @@ + +// Copyright 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. + +#include <boost/function.hpp> +#include <boost/config.hpp> + +#if defined(RETURN_FUNCTION_DYN_LINK) +# define EXPORT BOOST_SYMBOL_EXPORT +#else +# define EXPORT +#endif + +int f( int x, int y ) +{ + return x + y; +} + +EXPORT boost::function<int(int, int)> get_fn_1() +{ + return f; +} + +EXPORT boost::function2<int, int, int> get_fn_2() +{ + return f; +} diff --git a/src/boost/libs/function/test/rvalues_test.cpp b/src/boost/libs/function/test/rvalues_test.cpp new file mode 100644 index 00000000..28545d53 --- /dev/null +++ b/src/boost/libs/function/test/rvalues_test.cpp @@ -0,0 +1,107 @@ +// Copyright 2014 Antony Polukhin. +// +// 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) + +// For more information, see http://www.boost.org + +#include <boost/function.hpp> +#include <boost/move/move.hpp> +#include <boost/core/lightweight_test.hpp> +#include <iostream> +#include <cstdlib> + +#define BOOST_CHECK BOOST_TEST + +class only_movable { +private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(only_movable) + int value_; + bool moved_; + +public: + only_movable(BOOST_RV_REF(only_movable) x) + : value_(x.value_) + , moved_(false) + { + x.moved_ = true; + } + + only_movable& operator=(BOOST_RV_REF(only_movable) x) { + value_ = x.value_; + x.moved_ = true; + moved_ = false; + return *this; + } + + explicit only_movable(int value = 0) : value_(value), moved_(false) {} + int get_value() const { return value_; } + bool is_moved() const { return moved_; } +}; + + +int one(BOOST_RV_REF(only_movable) v) { return v.get_value(); } +only_movable two(BOOST_RV_REF(only_movable) t) { + only_movable t1 = boost::move(t); + return BOOST_MOVE_RET(only_movable, t1); +} + +only_movable two_sum(BOOST_RV_REF(only_movable) t1, BOOST_RV_REF(only_movable) t2) { + only_movable ret(t1.get_value() + t2.get_value()); + return BOOST_MOVE_RET(only_movable, ret); +} + +struct sum_struct { + only_movable operator()(BOOST_RV_REF(only_movable) t1, BOOST_RV_REF(only_movable) t2) const { + only_movable ret(t1.get_value() + t2.get_value()); + return BOOST_MOVE_RET(only_movable, ret); + } +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +int three(std::string&&) { return 1; } +std::string&& four(std::string&& s) { return boost::move(s); } +#endif + +int main() +{ + using boost::function; + + function <int(BOOST_RV_REF(only_movable))> f1 = one; + + only_movable om1(1); + BOOST_CHECK(f1(boost::move(om1)) == 1); + + function <only_movable(BOOST_RV_REF(only_movable))> f2 = two; + + only_movable om2(2); + only_movable om2_2 = f2(boost::move(om2)); + BOOST_CHECK(om2_2.get_value() == 2); + BOOST_CHECK(om2.is_moved()); + + { + function <only_movable(BOOST_RV_REF(only_movable), BOOST_RV_REF(only_movable))> f2_sum = two_sum; + only_movable om1_sum(1), om2_sum(2); + only_movable om2_sum_2 = f2_sum(boost::move(om1_sum), boost::move(om2_sum)); + BOOST_CHECK(om2_sum_2.get_value() == 3); + } + + { + sum_struct s; + function <only_movable(BOOST_RV_REF(only_movable), BOOST_RV_REF(only_movable))> f2_sum = s; + only_movable om1_sum(1), om2_sum(2); + only_movable om2_sum_2 = f2_sum(boost::move(om1_sum), boost::move(om2_sum)); + BOOST_CHECK(om2_sum_2.get_value() == 3); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + function <int(std::string&&)> f3 = three; + function <std::string&& (std::string&& s)> f4 = four; + + f3(std::string("Hello")); + BOOST_CHECK(f4(std::string("world")) == "world"); +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/stateless_test.cpp b/src/boost/libs/function/test/stateless_test.cpp new file mode 100644 index 00000000..5ec1b84c --- /dev/null +++ b/src/boost/libs/function/test/stateless_test.cpp @@ -0,0 +1,42 @@ +// 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 <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> +#include <stdexcept> +#include <new> + +struct stateless_integer_add { + int operator()(int x, int y) const { return x+y; } + + void* operator new(std::size_t n) + { + BOOST_ERROR( "stateless_integer_add incorrectly allocated" ); + return ::operator new( n ); + } + + void* operator new(std::size_t, void* p) + { + return p; + } + + void operator delete(void* p) throw() + { + BOOST_ERROR( "stateless_integer_add incorrectly deallocated" ); + return ::operator delete( p ); + } +}; + +int main() +{ + boost::function2<int, int, int> f; + f = stateless_integer_add(); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/std_bind_cxx98.cpp b/src/boost/libs/function/test/std_bind_cxx98.cpp new file mode 100644 index 00000000..d23fab1b --- /dev/null +++ b/src/boost/libs/function/test/std_bind_cxx98.cpp @@ -0,0 +1,31 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <iostream> +#include <functional> + +struct X { + int foo(int); +}; +int X::foo(int x) { return -x; } + +int main() +{ +#ifndef BOOST_NO_CXX98_BINDERS + boost::function<int (int)> f; + X x; + f = std::bind1st( + std::mem_fun(&X::foo), &x); + f(5); // Call x.foo(5) +#endif + return 0; +} diff --git a/src/boost/libs/function/test/std_bind_portable.cpp b/src/boost/libs/function/test/std_bind_portable.cpp new file mode 100644 index 00000000..1bfdbc2a --- /dev/null +++ b/src/boost/libs/function/test/std_bind_portable.cpp @@ -0,0 +1,31 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <iostream> +#include <functional> + +struct X { + int foo(int); +}; +int X::foo(int x) { return -x; } + +int main() +{ +#ifndef BOOST_NO_CXX98_BINDERS + boost::function1<int, int> f; + X x; + f = std::bind1st( + std::mem_fun(&X::foo), &x); + f(5); // Call x.foo(5) +#endif + return 0; +} diff --git a/src/boost/libs/function/test/sum_avg_cxx98.cpp b/src/boost/libs/function/test/sum_avg_cxx98.cpp new file mode 100644 index 00000000..1bf2dcb7 --- /dev/null +++ b/src/boost/libs/function/test/sum_avg_cxx98.cpp @@ -0,0 +1,28 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <iostream> + +void do_sum_avg(int values[], int n, int& sum, float& avg) +{ + sum = 0; + for (int i = 0; i < n; i++) + sum += values[i]; + avg = (float)sum / n; +} +int main() +{ + boost::function<void (int values[], int n, int& sum, float& avg)> sum_avg; + sum_avg = &do_sum_avg; + + return 0; +} diff --git a/src/boost/libs/function/test/sum_avg_portable.cpp b/src/boost/libs/function/test/sum_avg_portable.cpp new file mode 100644 index 00000000..d1687e30 --- /dev/null +++ b/src/boost/libs/function/test/sum_avg_portable.cpp @@ -0,0 +1,28 @@ +// Function library + +// Copyright (C) 2001-2003 Douglas Gregor + +// 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 <boost/function.hpp> +#include <iostream> + +void do_sum_avg(int values[], int n, int& sum, float& avg) +{ + sum = 0; + for (int i = 0; i < n; i++) + sum += values[i]; + avg = (float)sum / n; +} +int main() +{ + boost::function4<void, int*, int, int&, float&> sum_avg; + sum_avg = &do_sum_avg; + + return 0; +} diff --git a/src/boost/libs/function/test/test_bad_function_call.cpp b/src/boost/libs/function/test/test_bad_function_call.cpp new file mode 100644 index 00000000..3c88dd39 --- /dev/null +++ b/src/boost/libs/function/test/test_bad_function_call.cpp @@ -0,0 +1,14 @@ + +// Copyright 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. + +#include <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> + +void throw_bad_function_call(); + +int main() +{ + BOOST_TEST_THROWS( throw_bad_function_call(), boost::bad_function_call ); + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/test_mixed_cxxstd.cpp b/src/boost/libs/function/test/test_mixed_cxxstd.cpp new file mode 100644 index 00000000..6622ab37 --- /dev/null +++ b/src/boost/libs/function/test/test_mixed_cxxstd.cpp @@ -0,0 +1,48 @@ + +// Copyright 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. + +#include <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> + +// + +void call_fn_1( boost::function<void()> const & fn ); +void call_fn_2( boost::function<void(int)> const & fn ); +void call_fn_3( boost::function<void(int, int)> const & fn ); + +void call_fn_4( boost::function0<void> const & fn ); +void call_fn_5( boost::function1<void, int> const & fn ); +void call_fn_6( boost::function2<void, int, int> const & fn ); + +// + +static int v; + +void f0() +{ + v = -1; +} + +void f1( int x ) +{ + v = x; +} + +void f2( int x, int y ) +{ + v = x + y; +} + +int main() +{ + v = 0; call_fn_1( f0 ); BOOST_TEST_EQ( v, -1 ); + v = 0; call_fn_2( f1 ); BOOST_TEST_EQ( v, 1 ); + v = 0; call_fn_3( f2 ); BOOST_TEST_EQ( v, 3 ); + + v = 0; call_fn_4( f0 ); BOOST_TEST_EQ( v, -1 ); + v = 0; call_fn_5( f1 ); BOOST_TEST_EQ( v, 1 ); + v = 0; call_fn_6( f2 ); BOOST_TEST_EQ( v, 3 ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/test_return_function.cpp b/src/boost/libs/function/test/test_return_function.cpp new file mode 100644 index 00000000..05712ed2 --- /dev/null +++ b/src/boost/libs/function/test/test_return_function.cpp @@ -0,0 +1,21 @@ + +// Copyright 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. + +#include <boost/function.hpp> +#include <boost/core/lightweight_test.hpp> + +// + +boost::function<int(int, int)> get_fn_1(); +boost::function2<int, int, int> get_fn_2(); + +// + +int main() +{ + BOOST_TEST_EQ( get_fn_1()( 1, 2 ), 3 ); + BOOST_TEST_EQ( get_fn_2()( 1, 2 ), 3 ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/function/test/throw_bad_function_call.cpp b/src/boost/libs/function/test/throw_bad_function_call.cpp new file mode 100644 index 00000000..d6037592 --- /dev/null +++ b/src/boost/libs/function/test/throw_bad_function_call.cpp @@ -0,0 +1,17 @@ + +// Copyright 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. + +#include <boost/function.hpp> +#include <boost/config.hpp> + +#if defined(THROW_BAD_FUNCTION_CALL_DYN_LINK) +# define EXPORT BOOST_SYMBOL_EXPORT +#else +# define EXPORT +#endif + +EXPORT void throw_bad_function_call() +{ + throw boost::bad_function_call(); +} |