• 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/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