1
dnl Copyright 2002, The libsigc++ Development Team
3
dnl This library is free software; you can redistribute it and/or
4
dnl modify it under the terms of the GNU Lesser General Public
5
dnl License as published by the Free Software Foundation; either
6
dnl version 2.1 of the License, or (at your option) any later version.
8
dnl This library is distributed in the hope that it will be useful,
9
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
10
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
dnl Lesser General Public License for more details.
13
dnl You should have received a copy of the GNU Lesser General Public
14
dnl License along with this library; if not, write to the Free Software
15
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
include(template.macros.m4)
21
define([EXCEPTION_CATCH_OPERATOR],[dnl
22
template <LOOP(class T_arg%1, $1)>
23
typename deduce_result_type<LOOP(T_arg%1,$1)>::type
24
operator()(LOOP(T_arg%1 _A_a%1, $1))
28
return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP(_P_(T_arg%1), $1)>
32
{ return catcher_(); }
39
#include <sigc++/adaptors/adaptor_trait.h>
44
functor adaptor: exception_catch(functor, catcher)
50
The catcher should be told what type of return it needs to
51
return for multiple type functors, to do this the user
52
will need to derive from catcher_base.
54
/** @defgroup exception_catch exception_catch()
55
* sigc::exception_catch() catches an exception thrown from within
56
* the wrapped functor and directs it to a catcher functor.
57
* This catcher can then rethrow the exception and catch it with the proper type.
59
* Note that the catcher is expected to return the same type
60
* as the wrapped functor so that normal flow can continue.
62
* Catchers can be cascaded to catch multiple types because uncaught
63
* rethrown exceptions proceed to the next catcher adaptor.
72
* catch (std::range_error e) // catch what types we know
73
* { std::cerr << "caught " << e.what() << std::endl; }
77
* int foo(); // throws std::range_error
78
* sigc::exception_catch(&foo, my_catch())();
81
* The functor sigc::execption_catch() returns can be passed into
82
* sigc::signal::connect() directly.
86
* sigc::signal<int> some_signal;
87
* some_signal.connect(sigc::exception_catch(&foo, my_catch));
93
template <class T_functor, class T_catcher, class T_return = typename adapts<T_functor>::result_type>
94
struct exception_catch_functor : public adapts<T_functor>
96
typedef typename adapts<T_functor>::adaptor_type adaptor_type;
98
template <LOOP(class T_arg%1=void, CALL_SIZE)>
99
struct deduce_result_type
100
{ typedef typename adaptor_type::template deduce_result_type<LOOP(_P_(T_arg%1),CALL_SIZE)>::type type; };
101
typedef T_return result_type;
106
FOR(1,CALL_SIZE,[[EXCEPTION_CATCH_OPERATOR(%1)]])dnl
107
exception_catch_functor(const T_functor& _A_func,
108
const T_catcher& _A_catcher)
109
: adapts<T_functor>(_A_func), catcher_(_A_catcher)
115
template <class T_functor, class T_catcher, class T_return>
116
typename exception_catch_functor<T_functor, T_catcher, T_return>::result_type
117
exception_catch_functor<T_functor, T_catcher, T_return>::operator()()
120
{ return this->functor_(); }
122
{ return catcher_(); }
125
// void specialization
126
template <class T_functor, class T_catcher>
127
struct exception_catch_functor<T_functor, T_catcher, void> : public adapts<T_functor>
129
typedef void result_type;
130
typedef typename adapts<T_functor>::adaptor_type adaptor_type;
135
FOR(1,CALL_SIZE,[[EXCEPTION_CATCH_OPERATOR(%1)]])dnl
136
exception_catch_functor() {}
137
exception_catch_functor(const T_functor& _A_func,
138
const T_catcher& _A_catcher)
139
: adapts<T_functor>(_A_func), catcher_(_A_catcher)
141
~exception_catch_functor() {}
146
template <class T_functor, class T_catcher>
147
void exception_catch_functor<T_functor, T_catcher, void>::operator()()
150
{ this->functor_(); } // I don't understand why void return doesn't work here (Martin)
152
{ this->catcher_(); }
156
//template specialization of visit_each<>(action, functor):
157
template <class T_action, class T_functor, class T_catcher, class T_return>
158
void visit_each(const T_action& _A_action,
159
const exception_catch_functor<T_functor, T_catcher, T_return>& _A_target)
161
visit_each(_A_action, _A_target.functor_);
162
visit_each(_A_action, _A_target.catcher_);
166
template <class T_functor, class T_catcher>
167
inline exception_catch_functor<T_functor, T_catcher>
168
exception_catch(const T_functor& _A_func, const T_catcher& _A_catcher)
169
{ return exception_catch_functor<T_functor, T_catcher>(_A_func, _A_catcher); }
171
} /* namespace sigc */