summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/context/test/test_invoke.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/context/test/test_invoke.cpp')
-rw-r--r--src/boost/libs/context/test/test_invoke.cpp242
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;
+}