diff options
Diffstat (limited to 'src/boost/libs/context/test/test_invoke.cpp')
-rw-r--r-- | src/boost/libs/context/test/test_invoke.cpp | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/src/boost/libs/context/test/test_invoke.cpp b/src/boost/libs/context/test/test_invoke.cpp new file mode 100644 index 000000000..362d83917 --- /dev/null +++ b/src/boost/libs/context/test/test_invoke.cpp @@ -0,0 +1,242 @@ + +// Copyright Oliver Kowalke 2009. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <iostream> +#include <memory> +#include <sstream> +#include <stdexcept> +#include <string> +#include <tuple> +#include <utility> + +#include <boost/config.hpp> +#include <boost/assert.hpp> +#include <boost/test/unit_test.hpp> + +#if defined(BOOST_NO_CXX17_STD_INVOKE) +#include <boost/context/detail/invoke.hpp> +#include <boost/context/detail/config.hpp> + +namespace ctx = boost::context; + +struct callable { + int k{ 0 }; + + callable() = default; + + callable( int k_) : + k{ k_ } { + } + + int foo( int i, int j) const { + return i + j + k; + } + + int operator()( int i, int j) const { + return foo( i, j); + } +}; + +struct movable { + int k{ 0 }; + + movable() = default; + + movable( int k_) : + k{ k_ } { + } + + movable( movable const&) = delete; + movable & operator=( movable const&) = delete; + + movable( movable && other) : + k{ other.k } { + other.k = -1; + } + + movable & operator=( movable && other) { + if ( this == & other) return * this; + k = other.k; + other.k = -1; + return * this; + } + + int foo( int i, int j) const { + return i + j + k; + } + + int operator()( int i, int j) const { + return foo( i, j); + } +}; + +int fn1( int i, int j) { + return i + j; +} + +int * fn2( int * ip) { + return ip; +} + +int * fn3( int & ir) { + return & ir; +} + +int & fn4( int & ir) { + return ir; +} + +template< typename T > +int fn5( int i, T && t_) { + T t = std::forward< T >( t_); + return i + t.k; +} + +void test1() { + int result = ctx::detail::invoke( fn1, 1, 2); + BOOST_CHECK_EQUAL( result, 3); +} + +void test2() { + { + int i = 3; + int * ip = & i; + int * result = ctx::detail::invoke( fn2, ip); + BOOST_CHECK_EQUAL( result, ip); + BOOST_CHECK_EQUAL( * result, i); + } + { + int i = 3; + int * result = ctx::detail::invoke( fn2, & i); + BOOST_CHECK_EQUAL( result, & i); + BOOST_CHECK_EQUAL( * result, i); + } +} + +void test3() { + { + int i = 3; + int & ir = i; + int * result = ctx::detail::invoke( fn3, ir); + BOOST_CHECK_EQUAL( result, & ir); + BOOST_CHECK_EQUAL( * result, i); + } + { + int i = 3; + int * result = ctx::detail::invoke( fn3, i); + BOOST_CHECK_EQUAL( result, & i); + BOOST_CHECK_EQUAL( * result, i); + } +} + +void test4() { + { + int i = 3; + int & ir = i; + int & result = ctx::detail::invoke( fn4, ir); + BOOST_CHECK_EQUAL( result, ir); + BOOST_CHECK_EQUAL( & result, & ir); + BOOST_CHECK_EQUAL( result, i); + } + { + int i = 3; + int & result = ctx::detail::invoke( fn4, i); + BOOST_CHECK_EQUAL( & result, & i); + BOOST_CHECK_EQUAL( result, i); + } +} + +void test5() { + { + callable c( 5); + int result = ctx::detail::invoke( fn5< callable >, 1, std::move( c) ); + BOOST_CHECK_EQUAL( result, 6); + BOOST_CHECK_EQUAL( c.k, 5); + } + { + movable m( 5); + int result = ctx::detail::invoke( fn5< movable >, 1, std::move( m) ); + BOOST_CHECK_EQUAL( result, 6); + BOOST_CHECK_EQUAL( m.k, -1); + } +} + +void test6() { + { + callable c; + int result = ctx::detail::invoke( c, 1, 2); + BOOST_CHECK_EQUAL( result, 3); + BOOST_CHECK_EQUAL( c.k, 0); + } + { + callable c; + int result = ctx::detail::invoke( & callable::foo, c, 1, 2); + BOOST_CHECK_EQUAL( result, 3); + BOOST_CHECK_EQUAL( c.k, 0); + } +} + +void test7() { + { + int result = ctx::detail::invoke( movable{}, 1, 2); + BOOST_CHECK_EQUAL( result, 3); + } + { + int result = ctx::detail::invoke( & movable::foo, movable{}, 1, 2); + BOOST_CHECK_EQUAL( result, 3); + } +} + +template< typename R, typename Fn, typename ... Args > +R apply( Fn && fn, Args && ... args) { + return ctx::detail::invoke( + std::forward< Fn >( fn), + std::forward< Args >( args) ... ); +} + +void test8() { + { + int result = apply< int >( fn1, 1, 2); + BOOST_CHECK_EQUAL( result, 3); + } + { + int i = 3; + int & ir = i; + int * result = apply< int * >( fn3, ir); + BOOST_CHECK_EQUAL( result, & ir); + BOOST_CHECK_EQUAL( * result, i); + } + { + movable m( 5); + int result = apply< int >( fn5< movable >, 1, std::move( m) ); + BOOST_CHECK_EQUAL( result, 6); + BOOST_CHECK_EQUAL( m.k, -1); + } +} +#else +void dummy() {} +#endif + +boost::unit_test::test_suite * init_unit_test_suite( int, char* []) +{ + boost::unit_test::test_suite * test = + BOOST_TEST_SUITE("Boost.Context: invoke test suite"); + +#if defined(BOOST_NO_CXX17_STD_INVOKE) + test->add( BOOST_TEST_CASE( & test1) ); + test->add( BOOST_TEST_CASE( & test2) ); + test->add( BOOST_TEST_CASE( & test3) ); + test->add( BOOST_TEST_CASE( & test4) ); + test->add( BOOST_TEST_CASE( & test5) ); + test->add( BOOST_TEST_CASE( & test6) ); + test->add( BOOST_TEST_CASE( & test7) ); + test->add( BOOST_TEST_CASE( & test8) ); +#else + test->add( BOOST_TEST_CASE( & dummy) ); +#endif + + return test; +} |