Commit 6e0964d9 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Move Thrower into exception_wrapper

Summary:
[Folly] Move `Thrower` into `exception_wrapper`.

It is only used by `exception_wrapper`, so it might as well be a member type.

Also, make it private. That means we need to tweak `try_and_catch`.

Since we are tweaking `try_and_catch`, tweak all similar cases.

Reviewed By: luciang

Differential Revision: D4361815

fbshipit-source-id: c5025894465a2c7760bd79dbbd272079fd34dd79
parent c60d131b
......@@ -22,7 +22,7 @@ namespace folly {
[[noreturn]] void exception_wrapper::throwException() const {
if (throwfn_) {
throwfn_(item_.get());
throwfn_(*item_);
} else if (eptr_) {
std::rethrow_exception(eptr_);
}
......
......@@ -24,7 +24,6 @@
#include <folly/ExceptionString.h>
#include <folly/FBString.h>
#include <folly/detail/ExceptionWrapper.h>
namespace folly {
......@@ -118,8 +117,7 @@ class exception_wrapper {
::type>
/* implicit */ exception_wrapper(Ex&& exn) {
typedef typename std::decay<Ex>::type DEx;
item_ = std::make_shared<DEx>(std::forward<Ex>(exn));
throwfn_ = folly::detail::Thrower<DEx>::doThrow;
assign_sptr(std::make_shared<DEx>(std::forward<Ex>(exn)));
}
// The following two constructors are meant to emulate the behavior of
......@@ -269,7 +267,7 @@ class exception_wrapper {
return std::exception_ptr();
}
protected:
protected:
template <typename Ex>
struct optimize {
static const bool value =
......@@ -278,6 +276,12 @@ protected:
!std::is_abstract<Ex>::value;
};
template <typename Ex>
void assign_sptr(std::shared_ptr<Ex> sptr) {
this->item_ = std::move(sptr);
this->throwfn_ = Thrower<Ex>::doThrow;
}
template <typename Ex>
void assign_eptr(std::exception_ptr eptr, Ex& e) {
this->eptr_ = eptr;
......@@ -293,7 +297,7 @@ protected:
// store a copy of the concrete type, and a helper function so we
// can rethrow it.
std::shared_ptr<std::exception> item_;
void (*throwfn_)(std::exception*){nullptr};
void (*throwfn_)(std::exception&){nullptr};
// Fallback case: store the library wrapper, which is less efficient
// but gets the job done. Also store exceptionPtr() the name of the
// exception type, so we can at least get those back out without
......@@ -305,7 +309,7 @@ protected:
template <class T, class... Args>
friend exception_wrapper make_exception_wrapper(Args&&... args);
private:
private:
template <typename F>
struct functor_traits {
template <typename T>
......@@ -320,6 +324,14 @@ private:
using arg_type_decayed = typename std::decay<arg_type>::type;
};
template <class T>
class Thrower {
public:
static void doThrow(std::exception& obj) {
throw static_cast<T&>(obj);
}
};
// What makes this useful is that T can be exception_wrapper* or
// const exception_wrapper*, and the compiler will use the
// instantiation which works with F.
......@@ -347,8 +359,7 @@ private:
template <class T, class... Args>
exception_wrapper make_exception_wrapper(Args&&... args) {
exception_wrapper ew;
ew.item_ = std::make_shared<T>(std::forward<Args>(args)...);
ew.throwfn_ = folly::detail::Thrower<T>::doThrow;
ew.assign_sptr(std::make_shared<T>(std::forward<Args>(args)...));
return ew;
}
......@@ -423,8 +434,7 @@ class try_and_catch<LastException, Exceptions...> :
template <typename Ex>
typename std::enable_if<exception_wrapper::optimize<Ex>::value>::type
assign_exception(Ex& e, std::exception_ptr /*eptr*/) {
this->item_ = std::make_shared<Ex>(e);
this->throwfn_ = folly::detail::Thrower<Ex>::doThrow;
exception_wrapper::assign_sptr(std::make_shared<Ex>(e));
}
template <typename F>
......
......@@ -60,7 +60,6 @@ nobase_follyinclude_HEADERS = \
detail/CachelinePaddedImpl.h \
detail/ChecksumDetail.h \
detail/DiscriminatedPtrDetail.h \
detail/ExceptionWrapper.h \
detail/FileUtilDetail.h \
detail/FingerprintPolynomial.h \
detail/Futex.h \
......
/*
* Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
namespace folly { namespace detail {
template <class T>
class Thrower {
public:
static void doThrow(std::exception* obj) {
throw *static_cast<T*>(obj);
}
};
}}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment