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/core/lightweight_test.hpp>
17
18#include <boost/context/detail/apply.hpp>
19#include <boost/context/detail/config.hpp>
20
21#define BOOST_CHECK_EQUAL(a, b) BOOST_TEST_EQ(a, b)
22
23namespace ctx = boost::context;
24
25struct callable {
26 int k{ 0 };
27
28 callable() = default;
29
30 callable( int k_) :
31 k{ k_ } {
32 }
33
34 int foo( int i, int j) const {
35 return i + j + k;
36 }
37
38 int operator()( int i, int j) const {
39 return foo( i, j);
40 }
41};
42
43struct movable {
44 int k{ 0 };
45
46 movable() = default;
47
48 movable( int k_) :
49 k{ k_ } {
50 }
51
52 movable( movable const&) = delete;
53 movable & operator=( movable const&) = delete;
54
55 movable( movable && other) :
56 k{ other.k } {
57 other.k = -1;
58 }
59
60 movable & operator=( movable && other) {
61 if ( this == & other) return * this;
62 k = other.k;
63 other.k = -1;
64 return * this;
65 }
66
67 int foo( int i, int j) const {
68 return i + j + k;
69 }
70
71 int operator()( int i, int j) const {
72 return foo( i, j);
73 }
74};
75
76int fn1( int i, int j) {
77 return i + j;
78}
79
80int * fn2( int * ip) {
81 return ip;
82}
83
84int * fn3( int & ir) {
85 return & ir;
86}
87
88int & fn4( int & ir) {
89 return ir;
90}
91
92int fn5( int i, callable && c) {
93 return i + c.k;
94}
95
96int fn6( int i, movable && m) {
97 return i + m.k;
98}
99
100void test1() {
101 int result = ctx::detail::apply( fn&: fn1, tpl: std::make_tuple( args: 1, args: 2) );
102 BOOST_CHECK_EQUAL( result, 3);
103}
104
105void test2() {
106 {
107 int i = 3;
108 int * ip = & i;
109 int * result = ctx::detail::apply( fn&: fn2, tpl: std::make_tuple( args&: ip) );
110 BOOST_CHECK_EQUAL( result, ip);
111 BOOST_CHECK_EQUAL( * result, i);
112 }
113 {
114 int i = 3;
115 int * result = ctx::detail::apply( fn&: fn2, tpl: std::make_tuple( args: & i) );
116 BOOST_CHECK_EQUAL( result, & i);
117 BOOST_CHECK_EQUAL( * result, i);
118 }
119}
120
121void test3() {
122 {
123 int i = 'c';
124 int & ir = i;
125 int * result = ctx::detail::apply( fn&: fn3, tpl: std::make_tuple( args: std::ref( t&: ir) ) );
126 BOOST_CHECK_EQUAL( result, & ir);
127 BOOST_CHECK_EQUAL( * result, i);
128 }
129 {
130 int i = 'c';
131 int * result = ctx::detail::apply( fn&: fn3, tpl: std::make_tuple( args: std::ref( t&: i) ) );
132 BOOST_CHECK_EQUAL( result, & i);
133 BOOST_CHECK_EQUAL( * result, i);
134 }
135}
136
137void test4() {
138 {
139 int i = 3;
140 int & ir = i;
141 int & result = ctx::detail::apply( fn&: fn4, tpl: std::make_tuple( args: std::ref( t&: ir) ) );
142 BOOST_CHECK_EQUAL( result, ir);
143 BOOST_CHECK_EQUAL( & result, & ir);
144 BOOST_CHECK_EQUAL( result, i);
145 }
146 {
147 int i = 3;
148 int & result = ctx::detail::apply( fn&: fn4, tpl: std::make_tuple( args: std::ref( t&: i) ) );
149 BOOST_CHECK_EQUAL( & result, & i);
150 BOOST_CHECK_EQUAL( result, i);
151 }
152}
153
154void test5() {
155 {
156 callable c( 5);
157 int result = ctx::detail::apply( fn&: fn5, tpl: std::make_tuple( args: 1, args: std::move( c) ) );
158 BOOST_CHECK_EQUAL( result, 6);
159 BOOST_CHECK_EQUAL( c.k, 5);
160 }
161 {
162 movable m( 5);
163 int result = ctx::detail::apply( fn&: fn6, tpl: std::make_tuple( args: 1, args: std::move( m) ) );
164 BOOST_CHECK_EQUAL( result, 6);
165 BOOST_CHECK_EQUAL( m.k, -1);
166 }
167}
168
169void test6() {
170 {
171 callable c;
172 int result = ctx::detail::apply( fn&: c, tpl: std::make_tuple( args: 1, args: 2) );
173 BOOST_CHECK_EQUAL( result, 3);
174 BOOST_CHECK_EQUAL( c.k, 0);
175 }
176 {
177 callable c;
178 int result = ctx::detail::apply( fn: & callable::foo, tpl: std::make_tuple( args&: c, args: 1, args: 2) );
179 BOOST_CHECK_EQUAL( result, 3);
180 BOOST_CHECK_EQUAL( c.k, 0);
181 }
182}
183
184void test7() {
185 {
186 movable m;
187 int result = ctx::detail::apply( fn: std::move( m), tpl: std::make_tuple( args: 1, args: 2) );
188 BOOST_CHECK_EQUAL( result, 3);
189 }
190 {
191 movable m;
192 int result = ctx::detail::apply( fn: & movable::foo, tpl: std::make_tuple( args: std::move( m), args: 1, args: 2) );
193 BOOST_CHECK_EQUAL( result, 3);
194 }
195}
196
197int main()
198{
199 test1();
200 test2();
201 test3();
202 test4();
203 test5();
204 test6();
205 test7();
206
207 return boost::report_errors();
208}
209

source code of boost/libs/context/test/test_apply.cpp