]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/context/test/test_execution_context_v2.cpp
Add patch for failing prerm scripts
[ceph.git] / ceph / src / boost / libs / context / test / test_execution_context_v2.cpp
CommitLineData
7c673cae
FG
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 <thread>
13#include <utility>
14
15#include <boost/array.hpp>
16#include <boost/assert.hpp>
17#include <boost/lexical_cast.hpp>
18#include <boost/test/unit_test.hpp>
19#include <boost/utility.hpp>
20#include <boost/variant.hpp>
21
b32b8144 22#include <boost/context/execution_context.hpp>
7c673cae
FG
23#include <boost/context/detail/config.hpp>
24
b32b8144
FG
25#ifdef BOOST_WINDOWS
26#include <windows.h>
27#endif
28
29#if defined(BOOST_MSVC)
30# pragma warning(push)
31# pragma warning(disable: 4723)
32#endif
33
7c673cae
FG
34typedef boost::variant<int,std::string> variant_t;
35
36namespace ctx = boost::context;
37
38int value1 = 0;
39std::string value2;
40double value3 = 0.;
41
42struct X {
b32b8144 43 ctx::execution_context< void > foo( int i, ctx::execution_context< void > && ctx) {
7c673cae 44 value1 = i;
b32b8144 45 return std::move( ctx);
7c673cae
FG
46 }
47};
48
49struct Y {
50 Y() {
51 value1 = 3;
52 }
53
54 Y( Y const&) = delete;
55 Y & operator=( Y const&) = delete;
56
57 ~Y() {
58 value1 = 7;
59 }
60};
61
62class moveable {
63public:
64 bool state;
65 int value;
66
67 moveable() :
68 state( false),
69 value( -1) {
70 }
71
72 moveable( int v) :
73 state( true),
74 value( v) {
75 }
76
77 moveable( moveable && other) :
78 state( other.state),
79 value( other.value) {
80 other.state = false;
81 other.value = -1;
82 }
83
84 moveable & operator=( moveable && other) {
85 if ( this == & other) return * this;
86 state = other.state;
87 value = other.value;
88 other.state = false;
89 other.value = -1;
90 return * this;
91 }
92
93 moveable( moveable const& other) = delete;
94 moveable & operator=( moveable const& other) = delete;
95
96 void operator()() {
97 value1 = value;
98 }
99};
100
101struct my_exception : public std::runtime_error {
b32b8144
FG
102 my_exception( char const* what) :
103 std::runtime_error( what) {
7c673cae
FG
104 }
105};
106
b32b8144
FG
107#ifdef BOOST_MSVC
108// Optimizations can remove the integer-divide-by-zero here.
109#pragma optimize("", off)
7c673cae
FG
110void seh( bool & catched) {
111 __try {
112 int i = 1;
113 i /= 0;
114 } __except( EXCEPTION_EXECUTE_HANDLER) {
115 catched = true;
116 }
117}
b32b8144 118#pragma optimize("", on)
7c673cae
FG
119#endif
120
b32b8144 121ctx::execution_context< void > fn1( int i, ctx::execution_context< void > && ctx) {
7c673cae 122 value1 = i;
b32b8144 123 return std::move( ctx);
7c673cae
FG
124}
125
b32b8144 126ctx::execution_context< void > fn2( const char * what, ctx::execution_context< void > && ctx) {
7c673cae
FG
127 try {
128 throw std::runtime_error( what);
129 } catch ( std::runtime_error const& e) {
130 value2 = e.what();
131 }
b32b8144 132 return std::move( ctx);
7c673cae
FG
133}
134
b32b8144 135ctx::execution_context< void > fn3( double d, ctx::execution_context< void > && ctx) {
7c673cae
FG
136 d += 3.45;
137 value3 = d;
b32b8144 138 return std::move( ctx);
7c673cae
FG
139}
140
b32b8144 141ctx::execution_context< void > fn5( ctx::execution_context< void > && ctx) {
7c673cae 142 value1 = 3;
b32b8144 143 return std::move( ctx);
7c673cae
FG
144}
145
b32b8144 146ctx::execution_context< void > fn4( ctx::execution_context< void > && ctx) {
7c673cae
FG
147 ctx::execution_context< void > ctx1( fn5);
148 ctx1();
149 value3 = 3.14;
b32b8144 150 return std::move( ctx);
7c673cae
FG
151}
152
b32b8144 153ctx::execution_context< void > fn6( ctx::execution_context< void > && ctx) {
7c673cae
FG
154 try {
155 value1 = 3;
156 ctx = ctx();
157 value1 = 7;
158 ctx = ctx();
159 } catch ( my_exception & e) {
160 value2 = e.what();
7c673cae 161 }
b32b8144 162 return std::move( ctx);
7c673cae
FG
163}
164
b32b8144 165ctx::execution_context< void > fn7( ctx::execution_context< void > && ctx) {
7c673cae
FG
166 Y y;
167 return ctx();
168}
169
b32b8144 170ctx::execution_context< int > fn8( ctx::execution_context< int > && ctx, int i) {
7c673cae 171 value1 = i;
b32b8144 172 return std::move( ctx);
7c673cae
FG
173}
174
b32b8144 175ctx::execution_context< int > fn9( ctx::execution_context< int > && ctx, int i) {
7c673cae
FG
176 value1 = i;
177 std::tie( ctx, i) = ctx( i);
178 value1 = i;
b32b8144 179 return std::move( ctx);
7c673cae
FG
180}
181
b32b8144 182ctx::execution_context< int & > fn10( ctx::execution_context< int & > && ctx, int & i) {
7c673cae 183 std::tie( ctx, i) = ctx( i);
b32b8144 184 return std::move( ctx);
7c673cae
FG
185}
186
b32b8144 187ctx::execution_context< moveable > fn11( ctx::execution_context< moveable > && ctx, moveable m) {
7c673cae 188 std::tie( ctx, m) = ctx( std::move( m) );
b32b8144 189 return std::move( ctx);
7c673cae
FG
190}
191
b32b8144 192ctx::execution_context< int, std::string > fn12( ctx::execution_context< int, std::string > && ctx, int i, std::string str) {
7c673cae 193 std::tie( ctx, i, str) = ctx( i, str);
b32b8144 194 return std::move( ctx);
7c673cae
FG
195}
196
b32b8144 197ctx::execution_context< int, moveable > fn13( ctx::execution_context< int, moveable > && ctx, int i, moveable m) {
7c673cae 198 std::tie( ctx, i, m) = ctx( i, std::move( m) );
b32b8144 199 return std::move( ctx);
7c673cae
FG
200}
201
b32b8144 202ctx::execution_context< variant_t > fn14( ctx::execution_context< variant_t > && ctx, variant_t data) {
7c673cae
FG
203 int i = boost::get< int >( data);
204 data = boost::lexical_cast< std::string >( i);
205 std::tie( ctx, data) = ctx( data);
b32b8144 206 return std::move( ctx);
7c673cae
FG
207}
208
b32b8144 209ctx::execution_context< Y * > fn15( ctx::execution_context< Y * > && ctx, Y * py) {
7c673cae 210 ctx( py);
b32b8144 211 return std::move( ctx);
7c673cae
FG
212}
213
b32b8144 214ctx::execution_context< int > fn16( ctx::execution_context< int > && ctx, int i) {
7c673cae
FG
215 value1 = i;
216 std::tie( ctx, i) = ctx( i);
217 value1 = i;
b32b8144
FG
218 return std::move( ctx);
219}
220
221ctx::execution_context< int, int > fn17( ctx::execution_context< int, int > && ctx, int i, int j) {
222 for (;;) {
223 std::tie( ctx, i, j) = ctx( i, j);
224 }
225 return std::move( ctx);
7c673cae
FG
226}
227
228
229void test_move() {
230 value1 = 0;
231 ctx::execution_context< void > ctx;
232 BOOST_CHECK( ! ctx);
233 ctx::execution_context< void > ctx1( fn1, 1);
234 ctx::execution_context< void > ctx2( fn1, 3);
235 BOOST_CHECK( ctx1);
236 BOOST_CHECK( ctx2);
237 ctx1 = std::move( ctx2);
238 BOOST_CHECK( ctx1);
239 BOOST_CHECK( ! ctx2);
240 BOOST_CHECK_EQUAL( 0, value1);
241 ctx1();
242 BOOST_CHECK_EQUAL( 3, value1);
243 BOOST_CHECK( ! ctx1);
244 BOOST_CHECK( ! ctx2);
245}
246
247void test_memfn() {
248 value1 = 0;
249 X x;
250 ctx::execution_context< void > ctx( & X::foo, x, 7);
251 ctx();
252 BOOST_CHECK_EQUAL( 7, value1);
253}
254
255void test_exception() {
256 {
257 const char * what = "hello world";
258 ctx::execution_context< void > ctx( fn2, what);
259 BOOST_CHECK( ctx);
260 ctx();
261 BOOST_CHECK_EQUAL( std::string( what), value2);
262 BOOST_CHECK( ! ctx);
263 }
b32b8144 264#ifdef BOOST_MSVC
7c673cae
FG
265 {
266 bool catched = false;
b32b8144
FG
267 std::thread([&catched](){
268 ctx::execution_context< void > ctx([&catched](ctx::execution_context< void > && ctx){
269 seh( catched);
270 return std::move( ctx);
271 });
7c673cae
FG
272 BOOST_CHECK( ctx);
273 ctx();
274 }).join();
275 BOOST_CHECK( catched);
276 }
277#endif
278}
279
280void test_fp() {
281 double d = 7.13;
282 ctx::execution_context< void > ctx( fn3, d);
283 BOOST_CHECK( ctx);
284 ctx();
285 BOOST_CHECK_EQUAL( 10.58, value3);
286 BOOST_CHECK( ! ctx);
287}
288
289void test_stacked() {
290 value1 = 0;
291 value3 = 0.;
292 ctx::execution_context< void > ctx( fn4);
293 BOOST_CHECK( ctx);
294 ctx();
295 BOOST_CHECK_EQUAL( 3, value1);
296 BOOST_CHECK_EQUAL( 3.14, value3);
297 BOOST_CHECK( ! ctx);
298}
299
300void test_prealloc() {
301 value1 = 0;
302 ctx::default_stack alloc;
303 ctx::stack_context sctx( alloc.allocate() );
304 void * sp = static_cast< char * >( sctx.sp) - 10;
305 std::size_t size = sctx.size - 10;
306 ctx::execution_context< void > ctx( std::allocator_arg, ctx::preallocated( sp, size, sctx), alloc, fn1, 7);
307 BOOST_CHECK( ctx);
308 ctx();
309 BOOST_CHECK_EQUAL( 7, value1);
310 BOOST_CHECK( ! ctx);
311}
312
313void test_ontop() {
314 {
7c673cae 315 int i = 3, j = 0;
b32b8144
FG
316 ctx::execution_context< int > ctx([]( ctx::execution_context< int > && ctx, int x) {
317 for (;;) {
318 std::tie( ctx, x) = ctx( x*10);
319 }
320 return std::move( ctx);
321 });
7c673cae 322 std::tie( ctx, j) = ctx( ctx::exec_ontop_arg,
b32b8144
FG
323 []( int x){
324 return x-10;
7c673cae
FG
325 },
326 i);
327 BOOST_CHECK( ctx);
b32b8144 328 BOOST_CHECK_EQUAL( j, -70);
7c673cae
FG
329 }
330 {
b32b8144
FG
331 int i = 3, j = 1;
332 ctx::execution_context< int, int > ctx( fn17);
333 std::tie( ctx, i, j) = ctx( i, j);
334 std::tie( ctx, i, j) = ctx( ctx::exec_ontop_arg,
335 []( int x, int y) {
336 return std::make_tuple( x - y, x + y);
7c673cae 337 },
b32b8144
FG
338 i, j);
339 BOOST_CHECK_EQUAL( i, 2);
340 BOOST_CHECK_EQUAL( j, 4);
7c673cae
FG
341 }
342 {
343 moveable m1( 7), m2;
344 BOOST_CHECK( 7 == m1.value);
345 BOOST_CHECK( m1.state);
346 BOOST_CHECK( -1 == m2.value);
347 BOOST_CHECK( ! m2.state);
348 ctx::execution_context< moveable > ctx( fn11);
349 std::tie( ctx, m2) = ctx( ctx::exec_ontop_arg,
11fdf7f2 350 []( moveable&& m){
b32b8144 351 return std::move( m);
7c673cae
FG
352 },
353 std::move( m1) );
354 BOOST_CHECK( -1 == m1.value);
355 BOOST_CHECK( ! m1.state);
356 BOOST_CHECK( 7 == m2.value);
357 BOOST_CHECK( m2.state);
358 }
359}
360
361void test_ontop_exception() {
b32b8144
FG
362 {
363 value1 = 0;
364 value2 = "";
365 ctx::execution_context< void > ctx([](ctx::execution_context< void > && ctx){
366 for (;;) {
367 value1 = 3;
368 try {
369 ctx = ctx();
370 } catch ( ctx::ontop_error const& e) {
371 try {
372 std::rethrow_if_nested( e);
373 } catch ( my_exception const& ex) {
374 value2 = ex.what();
375 }
376 return e.get_context< void >();
377 }
378 }
379 return std::move( ctx);
380 });
381 ctx = ctx();
382 BOOST_CHECK_EQUAL( 3, value1);
383 const char * what = "hello world";
384 ctx( ctx::exec_ontop_arg,
385 [what](){
386 throw my_exception( what);
387 });
388 BOOST_CHECK_EQUAL( 3, value1);
389 BOOST_CHECK_EQUAL( std::string( what), value2);
390 }
391 {
392 value2 = "";
393 int i = 3, j = 1;
394 ctx::execution_context< int, int > ctx([]( ctx::execution_context< int, int > && ctx, int x, int y) {
395 for (;;) {
396 try {
397 std::tie( ctx, x, y) = ctx( x+y,x-y);
11fdf7f2 398 } catch ( ctx::ontop_error const& e) {
b32b8144
FG
399 try {
400 std::rethrow_if_nested( e);
401 } catch ( my_exception const& ex) {
402 value2 = ex.what();
403 }
404 return e.get_context< int, int >();
405 }
406 }
407 return std::move( ctx);
408 });
409 std::tie( ctx, i, j) = ctx( i, j);
410 BOOST_CHECK( ctx);
411 BOOST_CHECK_EQUAL( i, 4);
412 BOOST_CHECK_EQUAL( j, 2);
413 const char * what = "hello world";
414 std::tie( ctx, i, j) = ctx( ctx::exec_ontop_arg,
415 [what](int x, int y) {
416 throw my_exception(what);
417 return std::make_tuple( x*y, x/y);
418 },
419 i, j);
420 BOOST_CHECK_EQUAL( i, 4);
421 BOOST_CHECK_EQUAL( j, 2);
422 BOOST_CHECK_EQUAL( std::string( what), value2);
423 }
7c673cae
FG
424}
425
426void test_termination() {
427 {
428 value1 = 0;
429 ctx::execution_context< void > ctx( fn7);
430 BOOST_CHECK_EQUAL( 0, value1);
431 ctx = ctx();
432 BOOST_CHECK_EQUAL( 3, value1);
433 }
434 BOOST_CHECK_EQUAL( 7, value1);
435 {
436 value1 = 0;
437 BOOST_CHECK_EQUAL( 0, value1);
438 ctx::execution_context< void > ctx( fn5);
439 BOOST_CHECK( ctx);
440 ctx();
441 BOOST_CHECK_EQUAL( 3, value1);
442 BOOST_CHECK( ! ctx);
443 }
444 {
445 value1 = 0;
446 BOOST_CHECK_EQUAL( 0, value1);
447 int i = 3, j = 0;
448 ctx::execution_context< int > ctx( fn9);
449 BOOST_CHECK( ctx);
450 std::tie( ctx, j) = ctx( i);
451 BOOST_CHECK_EQUAL( i, value1);
452 BOOST_CHECK( ctx);
453 BOOST_CHECK_EQUAL( i, j);
454 i = 7;
455 std::tie( ctx, j) = ctx( i);
456 BOOST_CHECK_EQUAL( i, value1);
457 BOOST_CHECK( ! ctx);
458 BOOST_CHECK_EQUAL( i, j);
459 }
460}
461
462void test_one_arg() {
463 {
464 value1 = 0;
465 ctx::execution_context< int > ctx( fn8);
466 ctx( 7);
467 BOOST_CHECK_EQUAL( 7, value1);
468 }
469 {
470 int i = 3, j = 0;
471 ctx::execution_context< int > ctx( fn9);
472 std::tie( ctx, j) = ctx( i);
473 BOOST_CHECK_EQUAL( i, j);
474 }
475 {
476 int i = 3, j = 0;
477 int & k = j;
478 BOOST_CHECK( & i != & k);
479 BOOST_CHECK( & j == & k);
480 ctx::execution_context< int & > ctx( fn10);
481 std::tie( ctx, k) = ctx( i);
482 BOOST_CHECK( & i != & k);
483 }
484 {
485 Y y;
486 Y * py = nullptr;
487 ctx::execution_context< Y * > ctx( fn15);
488 std::tie( ctx, py) = ctx( & y);
489 BOOST_CHECK( py == & y);
490 }
491 {
492 moveable m1( 7), m2;
493 BOOST_CHECK( 7 == m1.value);
494 BOOST_CHECK( m1.state);
495 BOOST_CHECK( -1 == m2.value);
496 BOOST_CHECK( ! m2.state);
497 ctx::execution_context< moveable > ctx( fn11);
498 std::tie( ctx, m2) = ctx( std::move( m1) );
499 BOOST_CHECK( -1 == m1.value);
500 BOOST_CHECK( ! m1.state);
501 BOOST_CHECK( 7 == m2.value);
502 BOOST_CHECK( m2.state);
503 }
504}
505
506void test_two_args() {
507 {
508 int i1 = 3, i2 = 0;
509 std::string str1("abc"), str2;
510 ctx::execution_context< int, std::string > ctx( fn12);
511 std::tie( ctx, i2, str2) = ctx( i1, str1);
512 BOOST_CHECK_EQUAL( i1, i2);
513 BOOST_CHECK_EQUAL( str1, str2);
514 }
515 {
516 int i1 = 3, i2 = 0;
517 moveable m1( 7), m2;
518 BOOST_CHECK( 7 == m1.value);
519 BOOST_CHECK( m1.state);
520 BOOST_CHECK( -1 == m2.value);
521 BOOST_CHECK( ! m2.state);
522 ctx::execution_context< int, moveable > ctx( fn13);
523 std::tie( ctx, i2, m2) = ctx( i1, std::move( m1) );
524 BOOST_CHECK_EQUAL( i1, i2);
525 BOOST_CHECK( -1 == m1.value);
526 BOOST_CHECK( ! m1.state);
527 BOOST_CHECK( 7 == m2.value);
528 BOOST_CHECK( m2.state);
529 }
530}
531
532void test_variant() {
533 {
534 int i = 7;
535 variant_t data1 = i, data2;
536 ctx::execution_context< variant_t > ctx( fn14);
537 std::tie( ctx, data2) = ctx( data1);
538 std::string str = boost::get< std::string >( data2);
539 BOOST_CHECK_EQUAL( std::string("7"), str);
540 }
541}
542
543#ifdef BOOST_WINDOWS
544void test_bug12215() {
545 ctx::execution_context< void > ctx(
b32b8144 546 [](ctx::execution_context< void > && ctx) {
7c673cae
FG
547 char buffer[MAX_PATH];
548 GetModuleFileName( nullptr, buffer, MAX_PATH);
b32b8144 549 return std::move( ctx);
7c673cae
FG
550 });
551 ctx();
552
553}
554#endif
555
556boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
557{
558 boost::unit_test::test_suite * test =
559 BOOST_TEST_SUITE("Boost.Context: execution_context v2 test suite");
560
561 test->add( BOOST_TEST_CASE( & test_move) );
562 test->add( BOOST_TEST_CASE( & test_memfn) );
563 test->add( BOOST_TEST_CASE( & test_exception) );
564 test->add( BOOST_TEST_CASE( & test_fp) );
565 test->add( BOOST_TEST_CASE( & test_stacked) );
7c673cae
FG
566 test->add( BOOST_TEST_CASE( & test_prealloc) );
567 test->add( BOOST_TEST_CASE( & test_ontop) );
568 test->add( BOOST_TEST_CASE( & test_ontop_exception) );
569 test->add( BOOST_TEST_CASE( & test_termination) );
570 test->add( BOOST_TEST_CASE( & test_one_arg) );
571 test->add( BOOST_TEST_CASE( & test_two_args) );
572 test->add( BOOST_TEST_CASE( & test_variant) );
573#ifdef BOOST_WINDOWS
574 test->add( BOOST_TEST_CASE( & test_bug12215) );
575#endif
576
577 return test;
578}
b32b8144
FG
579
580#if defined(BOOST_MSVC)
581# pragma warning(pop)
582#endif