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/apply.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
fn5(int i,callable && c)90 int fn5( int i, callable && c) {
91 return i + c.k;
92 }
93
fn6(int i,movable && m)94 int fn6( int i, movable && m) {
95 return i + m.k;
96 }
97
test1()98 void test1() {
99 int result = ctx::detail::apply( fn1, std::make_tuple( 1, 2) );
100 BOOST_CHECK_EQUAL( result, 3);
101 }
102
test2()103 void test2() {
104 {
105 int i = 3;
106 int * ip = & i;
107 int * result = ctx::detail::apply( fn2, std::make_tuple( ip) );
108 BOOST_CHECK_EQUAL( result, ip);
109 BOOST_CHECK_EQUAL( * result, i);
110 }
111 {
112 int i = 3;
113 int * result = ctx::detail::apply( fn2, std::make_tuple( & i) );
114 BOOST_CHECK_EQUAL( result, & i);
115 BOOST_CHECK_EQUAL( * result, i);
116 }
117 }
118
test3()119 void test3() {
120 {
121 int i = 'c';
122 int & ir = i;
123 int * result = ctx::detail::apply( fn3, std::make_tuple( std::ref( ir) ) );
124 BOOST_CHECK_EQUAL( result, & ir);
125 BOOST_CHECK_EQUAL( * result, i);
126 }
127 {
128 int i = 'c';
129 int * result = ctx::detail::apply( fn3, std::make_tuple( std::ref( i) ) );
130 BOOST_CHECK_EQUAL( result, & i);
131 BOOST_CHECK_EQUAL( * result, i);
132 }
133 }
134
test4()135 void test4() {
136 {
137 int i = 3;
138 int & ir = i;
139 int & result = ctx::detail::apply( fn4, std::make_tuple( std::ref( ir) ) );
140 BOOST_CHECK_EQUAL( result, ir);
141 BOOST_CHECK_EQUAL( & result, & ir);
142 BOOST_CHECK_EQUAL( result, i);
143 }
144 {
145 int i = 3;
146 int & result = ctx::detail::apply( fn4, std::make_tuple( std::ref( i) ) );
147 BOOST_CHECK_EQUAL( & result, & i);
148 BOOST_CHECK_EQUAL( result, i);
149 }
150 }
151
test5()152 void test5() {
153 {
154 callable c( 5);
155 int result = ctx::detail::apply( fn5, std::make_tuple( 1, std::move( c) ) );
156 BOOST_CHECK_EQUAL( result, 6);
157 BOOST_CHECK_EQUAL( c.k, 5);
158 }
159 {
160 movable m( 5);
161 int result = ctx::detail::apply( fn6, std::make_tuple( 1, std::move( m) ) );
162 BOOST_CHECK_EQUAL( result, 6);
163 BOOST_CHECK_EQUAL( m.k, -1);
164 }
165 }
166
test6()167 void test6() {
168 {
169 callable c;
170 int result = ctx::detail::apply( c, std::make_tuple( 1, 2) );
171 BOOST_CHECK_EQUAL( result, 3);
172 BOOST_CHECK_EQUAL( c.k, 0);
173 }
174 {
175 callable c;
176 int result = ctx::detail::apply( & callable::foo, std::make_tuple( c, 1, 2) );
177 BOOST_CHECK_EQUAL( result, 3);
178 BOOST_CHECK_EQUAL( c.k, 0);
179 }
180 }
181
test7()182 void test7() {
183 {
184 movable m;
185 int result = ctx::detail::apply( std::move( m), std::make_tuple( 1, 2) );
186 BOOST_CHECK_EQUAL( result, 3);
187 }
188 {
189 movable m;
190 int result = ctx::detail::apply( & movable::foo, std::make_tuple( std::move( m), 1, 2) );
191 BOOST_CHECK_EQUAL( result, 3);
192 }
193 }
194
init_unit_test_suite(int,char * [])195 boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
196 {
197 boost::unit_test::test_suite * test =
198 BOOST_TEST_SUITE("Boost.Context: apply test suite");
199
200 test->add( BOOST_TEST_CASE( & test1) );
201 test->add( BOOST_TEST_CASE( & test2) );
202 test->add( BOOST_TEST_CASE( & test3) );
203 test->add( BOOST_TEST_CASE( & test4) );
204 test->add( BOOST_TEST_CASE( & test5) );
205 test->add( BOOST_TEST_CASE( & test6) );
206 test->add( BOOST_TEST_CASE( & test7) );
207
208 return test;
209 }
210