]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/exception/test/exception_ptr_test.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / exception / test / exception_ptr_test.cpp
CommitLineData
7c673cae
FG
1//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
2
3//Distributed under the Boost Software License, Version 1.0. (See accompanying
4//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
1e59de90
TL
6#include <boost/config.hpp>
7
8#if defined( BOOST_NO_EXCEPTIONS )
9# error This program requires exception handling.
10#endif
11
7c673cae
FG
12#include <boost/exception_ptr.hpp>
13#include <boost/exception/info.hpp>
14#include <boost/exception/get_error_info.hpp>
15#include <boost/exception/diagnostic_information.hpp>
16#include <boost/function.hpp>
17#include <boost/bind.hpp>
18#include <boost/thread.hpp>
19#include <boost/detail/atomic_count.hpp>
20#include <boost/detail/lightweight_test.hpp>
21#include <iostream>
22
23class thread_handle;
24boost::shared_ptr<thread_handle> create_thread( boost::function<void()> const & f );
25void join( thread_handle & t );
26
27class
28thread_handle
29 {
30 thread_handle( thread_handle const & );
31 thread_handle & operator=( thread_handle const & );
32
33 boost::exception_ptr err_;
34 boost::thread t_;
35
36 static
37 void
38 thread_wrapper( boost::function<void()> const & f, boost::exception_ptr & ep )
39 {
40 BOOST_ASSERT(!ep);
41 try
42 {
43 f();
44 }
45 catch(...)
46 {
47 ep = boost::current_exception();
48 }
49 }
50
51 explicit
52 thread_handle( boost::function<void()> const & f ):
53 t_(boost::bind(thread_wrapper,f,boost::ref(err_)))
54 {
55 }
56
57 friend boost::shared_ptr<thread_handle> create_thread( boost::function<void()> const & f );
58 friend void join( thread_handle & t );
59 };
60
61boost::shared_ptr<thread_handle>
62create_thread( boost::function<void()> const & f )
63 {
64 boost::shared_ptr<thread_handle> t( new thread_handle(f) );
65 return t;
66 }
67
68void
69join( thread_handle & t )
70 {
71 t.t_.join();
72 assert(t.err_);
73 rethrow_exception(t.err_);
74 }
75
76boost::detail::atomic_count exc_count(0);
77
78struct
79exc:
80 virtual boost::exception,
81 virtual std::exception
82 {
83 exc()
84 {
85 ++exc_count;
86 }
87
88 exc( exc const & e ):
89 boost::exception(e),
90 std::exception(e)
91 {
92 ++exc_count;
93 }
94
95 virtual
92f5a8d4 96 ~exc() BOOST_NOEXCEPT_OR_NOTHROW
7c673cae
FG
97 {
98 --exc_count;
99 }
100
101 private:
102
103 exc & operator=( exc const & );
104 };
105
106typedef boost::error_info<struct answer_,int> answer;
107
108void
109thread_func()
110 {
111 BOOST_THROW_EXCEPTION(exc() << answer(42));
112 }
113
114void
115check( boost::shared_ptr<thread_handle> const & t )
116 {
117 try
118 {
119 join(*t);
120 BOOST_TEST(false);
121 }
122 catch(
123 exc & e )
124 {
125 int const * a = boost::get_error_info<answer>(e);
126 BOOST_TEST(a && *a==42);
127 }
128 }
129
b32b8144
FG
130void
131test_deep_copy()
132 {
133 int const * p1=0;
134 boost::exception_ptr p;
135 try
136 {
137 BOOST_THROW_EXCEPTION(exc() << answer(42));
138 BOOST_ERROR("BOOST_THROW_EXCEPTION didn't throw");
139 }
140 catch(
141 exc & e )
142 {
143 p1=boost::get_error_info<answer>(e);
144 p=boost::current_exception();
145 }
146 BOOST_TEST(p1!=0);
147 BOOST_TEST(p);
148 try
149 {
150 boost::rethrow_exception(p);
151 BOOST_ERROR("rethrow_exception didn't throw");
152 }
153 catch(
154 exc & e )
155 {
156 int const * p2=boost::get_error_info<answer>(e);
157 BOOST_TEST(p2!=0 && *p2==42);
158 BOOST_TEST(p2!=p1);
159 }
160 }
161
7c673cae
FG
162int
163main()
164 {
b32b8144 165 test_deep_copy();
7c673cae
FG
166 BOOST_TEST(++exc_count==1);
167 try
168 {
169 std::vector< boost::shared_ptr<thread_handle> > threads;
170 std::generate_n(std::inserter(threads,threads.end()),1,boost::bind(create_thread,thread_func));
171 std::for_each(threads.begin(),threads.end(),check);
172 return boost::report_errors();
173 }
174 catch(
175 ... )
176 {
177 std::cerr <<
178 "Caught unexpected exception.\n"
179 "Output from current_exception_diagnostic_information:\n" <<
180 boost::current_exception_diagnostic_information() << std::endl;
181 return 42;
182 }
183 BOOST_TEST(!--exc_count);
184 }