• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 //          Copyright Oliver Kowalke 2009.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 
7 #include <iostream>
8 #include <memory>
9 #include <sstream>
10 #include <stdexcept>
11 #include <string>
12 #include <tuple>
13 #include <utility>
14 
15 #include <boost/assert.hpp>
16 #include <boost/test/unit_test.hpp>
17 
18 #include <boost/context/detail/invoke.hpp>
19 #include <boost/context/detail/config.hpp>
20 
21 namespace ctx = boost::context;
22 
23 struct callable {
24     int k{ 0 };
25 
26     callable() = default;
27 
callablecallable28     callable( int k_) :
29         k{ k_ } {
30     }
31 
foocallable32     int foo( int i, int j) const {
33         return i + j + k;
34     }
35 
operator ()callable36     int operator()( int i, int j) const {
37         return foo( i, j);
38     }
39 };
40 
41 struct movable {
42     int k{ 0 };
43 
44     movable() = default;
45 
movablemovable46     movable( int k_) :
47         k{ k_ } {
48     }
49 
50     movable( movable const&) = delete;
51     movable & operator=( movable const&) = delete;
52 
movablemovable53     movable( movable && other) :
54         k{ other.k } {
55         other.k = -1;
56     }
57 
operator =movable58     movable & operator=( movable && other) {
59         if ( this == & other) return * this;
60         k = other.k;
61         other.k = -1;
62         return * this;
63     }
64 
foomovable65     int foo( int i, int j) const {
66         return i + j + k;
67     }
68 
operator ()movable69     int operator()( int i, int j) const {
70         return foo( i, j);
71     }
72 };
73 
fn1(int i,int j)74 int fn1( int i, int j) {
75     return i + j;
76 }
77 
fn2(int * ip)78 int * fn2( int * ip) {
79     return ip;
80 }
81 
fn3(int & ir)82 int * fn3( int & ir) {
83     return & ir;
84 }
85 
fn4(int & ir)86 int & fn4( int & ir) {
87     return ir;
88 }
89 
90 template< typename T >
fn5(int i,T && t_)91 int fn5( int i, T && t_) {
92     T t = std::forward< T >( t_);
93     return i + t.k;
94 }
95 
test1()96 void test1() {
97     int result = ctx::detail::invoke( fn1, 1, 2);
98     BOOST_CHECK_EQUAL( result, 3);
99 }
100 
test2()101 void test2() {
102     {
103         int i = 3;
104         int * ip = & i;
105         int * result = ctx::detail::invoke( fn2, ip);
106         BOOST_CHECK_EQUAL( result, ip);
107         BOOST_CHECK_EQUAL( * result, i);
108     }
109     {
110         int i = 3;
111         int * result = ctx::detail::invoke( fn2, & i);
112         BOOST_CHECK_EQUAL( result, & i);
113         BOOST_CHECK_EQUAL( * result, i);
114     }
115 }
116 
test3()117 void test3() {
118     {
119         int i = 3;
120         int & ir = i;
121         int * result = ctx::detail::invoke( fn3, ir);
122         BOOST_CHECK_EQUAL( result, & ir);
123         BOOST_CHECK_EQUAL( * result, i);
124     }
125     {
126         int i = 3;
127         int * result = ctx::detail::invoke( fn3, i);
128         BOOST_CHECK_EQUAL( result, & i);
129         BOOST_CHECK_EQUAL( * result, i);
130     }
131 }
132 
test4()133 void test4() {
134     {
135         int i = 3;
136         int & ir = i;
137         int & result = ctx::detail::invoke( fn4, ir);
138         BOOST_CHECK_EQUAL( result, ir);
139         BOOST_CHECK_EQUAL( & result, & ir);
140         BOOST_CHECK_EQUAL( result, i);
141     }
142     {
143         int i = 3;
144         int & result = ctx::detail::invoke( fn4, i);
145         BOOST_CHECK_EQUAL( & result, & i);
146         BOOST_CHECK_EQUAL( result, i);
147     }
148 }
149 
test5()150 void test5() {
151     {
152         callable c( 5);
153         int result = ctx::detail::invoke( fn5< callable >, 1, std::move( c) );
154         BOOST_CHECK_EQUAL( result, 6);
155         BOOST_CHECK_EQUAL( c.k, 5);
156     }
157     {
158         movable m( 5);
159         int result = ctx::detail::invoke( fn5< movable >, 1, std::move( m) );
160         BOOST_CHECK_EQUAL( result, 6);
161         BOOST_CHECK_EQUAL( m.k, -1);
162     }
163 }
164 
test6()165 void test6() {
166     {
167         callable c;
168         int result = ctx::detail::invoke( c, 1, 2);
169         BOOST_CHECK_EQUAL( result, 3);
170         BOOST_CHECK_EQUAL( c.k, 0);
171     }
172     {
173         callable c;
174         int result = ctx::detail::invoke( & callable::foo, c, 1, 2);
175         BOOST_CHECK_EQUAL( result, 3);
176         BOOST_CHECK_EQUAL( c.k, 0);
177     }
178 }
179 
test7()180 void test7() {
181     {
182         int result = ctx::detail::invoke( movable{}, 1, 2);
183         BOOST_CHECK_EQUAL( result, 3);
184     }
185     {
186         int result = ctx::detail::invoke( & movable::foo, movable{}, 1, 2);
187         BOOST_CHECK_EQUAL( result, 3);
188     }
189 }
190 
191 template< typename R, typename Fn, typename ... Args >
apply(Fn && fn,Args &&...args)192 R apply( Fn && fn, Args && ... args) {
193     return ctx::detail::invoke(
194             std::forward< Fn >( fn),
195             std::forward< Args >( args) ... );
196 }
197 
test8()198 void test8() {
199     {
200         int result = apply< int >( fn1, 1, 2);
201         BOOST_CHECK_EQUAL( result, 3);
202     }
203     {
204         int i = 3;
205         int & ir = i;
206         int * result = apply< int * >( fn3, ir);
207         BOOST_CHECK_EQUAL( result, & ir);
208         BOOST_CHECK_EQUAL( * result, i);
209     }
210     {
211         movable m( 5);
212         int result = apply< int >( fn5< movable >, 1, std::move( m) );
213         BOOST_CHECK_EQUAL( result, 6);
214         BOOST_CHECK_EQUAL( m.k, -1);
215     }
216 }
217 
init_unit_test_suite(int,char * [])218 boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
219 {
220     boost::unit_test::test_suite * test =
221         BOOST_TEST_SUITE("Boost.Context: invoke test suite");
222 
223     test->add( BOOST_TEST_CASE( & test1) );
224     test->add( BOOST_TEST_CASE( & test2) );
225     test->add( BOOST_TEST_CASE( & test3) );
226     test->add( BOOST_TEST_CASE( & test4) );
227     test->add( BOOST_TEST_CASE( & test5) );
228     test->add( BOOST_TEST_CASE( & test6) );
229     test->add( BOOST_TEST_CASE( & test7) );
230     test->add( BOOST_TEST_CASE( & test8) );
231 
232     return test;
233 }
234