template <typename F>
typename std::result_of<F()>::type
FiberManager::runInMainContext(F&& func) {
- return runInMainContextHelper(std::forward<F>(func));
-}
-
-template <typename F>
-inline typename std::enable_if<
- !std::is_same<typename std::result_of<F()>::type, void>::value,
- typename std::result_of<F()>::type>::type
-FiberManager::runInMainContextHelper(F&& func) {
if (UNLIKELY(activeFiber_ == nullptr)) {
return func();
}
immediateFunc_ = std::ref(f);
activeFiber_->preempt(Fiber::AWAITING_IMMEDIATE);
- return std::move(result.value());
-}
-
-template <typename F>
-inline typename std::enable_if<
- std::is_same<typename std::result_of<F()>::type, void>::value,
- void>::type
-FiberManager::runInMainContextHelper(F&& func) {
- if (UNLIKELY(activeFiber_ == nullptr)) {
- func();
- return;
- }
-
- immediateFunc_ = std::ref(func);
- activeFiber_->preempt(Fiber::AWAITING_IMMEDIATE);
+ return std::move(result).value();
}
inline FiberManager& FiberManager::getFiberManager() {
*/
static FOLLY_TLS FiberManager* currentFiberManager_;
- /**
- * runInMainContext implementation for non-void functions.
- */
- template <typename F>
- typename std::enable_if<
- !std::is_same<typename std::result_of<F()>::type, void>::value,
- typename std::result_of<F()>::type>::type
- runInMainContextHelper(F&& func);
-
- /**
- * runInMainContext implementation for void functions
- */
- template <typename F>
- typename std::enable_if<
- std::is_same<typename std::result_of<F()>::type, void>::value,
- void>::type
- runInMainContextHelper(F&& func);
-
/**
* Allocator used to allocate stack for Fibers in the pool.
* Allocates stack on the stack of the main context.
checkRan = false;
- manager.addTask(
- [&]() {
- int stackLocation;
- runInMainContext(
- [&]() {
- expectMainContext(checkRan, &mainLocation, &stackLocation);
- });
- EXPECT_TRUE(checkRan);
- }
- );
+ manager.addTask([&]() {
+ struct A {
+ explicit A(int value_) : value(value_) {}
+ A(const A&) = delete;
+ A(A&&) = default;
+
+ int value;
+ };
+ int stackLocation;
+ auto ret = runInMainContext([&]() {
+ expectMainContext(checkRan, &mainLocation, &stackLocation);
+ return A(42);
+ });
+ EXPECT_TRUE(checkRan);
+ EXPECT_EQ(42, ret.value);
+ });
loopController.loop(
[&]() {
}
template <class T>
-T& Try<T>::value() {
+T& Try<T>::value() & {
throwIfFailed();
return value_;
}
template <class T>
-const T& Try<T>::value() const {
+T&& Try<T>::value() && {
+ throwIfFailed();
+ return std::move(value_);
+}
+
+template <class T>
+const T& Try<T>::value() const & {
throwIfFailed();
return value_;
}
*
* @returns mutable reference to the contained value
*/
- T& value();
+ T& value()&;
+ /*
+ * Get a rvalue reference to the contained value. If the Try contains an
+ * exception it will be rethrown.
+ *
+ * @returns rvalue reference to the contained value
+ */
+ T&& value()&&;
/*
* Get a const reference to the contained value. If the Try contains an
* exception it will be rethrown.
*
* @returns const reference to the contained value
*/
- const T& value() const;
+ const T& value() const&;
/*
* If the Try contains an exception, rethrow it. Otherwise do nothing.