+ private:
+ template <typename F>
+ struct functor_traits {
+ template <typename T>
+ struct impl;
+ template <typename C, typename R, typename A>
+ struct impl<R(C::*)(A)> { using arg_type = A; };
+ template <typename C, typename R, typename A>
+ struct impl<R(C::*)(A) const> { using arg_type = A; };
+ using functor_op = decltype(&_t<std::decay<F>>::operator());
+ using arg_type = typename impl<functor_op>::arg_type;
+ };
+
+ template <class T>
+ class Thrower {
+ public:
+ static void doThrow(std::exception& obj) {
+ throw static_cast<T&>(obj);
+ }
+ };
+
+ template <typename T, typename F>
+ static _t<std::enable_if<is_exception_<T>::value, T*>>
+ try_dynamic_cast_exception(F* from) {
+ return dynamic_cast<T*>(from);
+ }
+ template <typename T, typename F>
+ static _t<std::enable_if<!is_exception_<T>::value, T*>>
+ try_dynamic_cast_exception(F*) {
+ return nullptr;
+ }
+