waitFor race workaround
[folly.git] / folly / wangle / Try.h
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <type_traits>
20 #include <exception>
21 #include <algorithm>
22
23 namespace folly { namespace wangle {
24
25 template <class T>
26 class Try {
27   static_assert(!std::is_reference<T>::value,
28                 "Try may not be used with reference types");
29
30   enum class Contains {
31     VALUE,
32     EXCEPTION,
33     NOTHING,
34   };
35
36  public:
37   typedef T element_type;
38
39   Try() : contains_(Contains::NOTHING) {}
40   explicit Try(const T& v) : contains_(Contains::VALUE), value_(v) {}
41   explicit Try(T&& v) : contains_(Contains::VALUE), value_(std::move(v)) {}
42   explicit Try(std::exception_ptr e) : contains_(Contains::EXCEPTION), e_(e) {}
43
44   // move
45   Try(Try<T>&& t);
46   Try& operator=(Try<T>&& t);
47
48   // no copy
49   Try(const Try<T>& t) = delete;
50   Try& operator=(const Try<T>& t) = delete;
51
52   ~Try();
53
54   T& value();
55   const T& value() const;
56
57   void throwIfFailed() const;
58
59   const T& operator*() const { return value(); }
60         T& operator*()       { return value(); }
61
62   const T* operator->() const { return &value(); }
63         T* operator->()       { return &value(); }
64
65   bool hasValue() const { return contains_ == Contains::VALUE; }
66   bool hasException() const { return contains_ == Contains::EXCEPTION; }
67
68  private:
69   Contains contains_;
70   union {
71     T value_;
72     std::exception_ptr e_;
73   };
74 };
75
76 template <>
77 class Try<void> {
78  public:
79   Try() : hasValue_(true) {}
80   explicit Try(std::exception_ptr e) : hasValue_(false), e_(e) {}
81
82   void value() const { throwIfFailed(); }
83   void operator*() const { return value(); }
84
85   inline void throwIfFailed() const;
86
87   bool hasValue() const { return hasValue_; }
88   bool hasException() const { return !hasValue_; }
89
90  private:
91   bool hasValue_;
92   std::exception_ptr e_;
93 };
94
95 /**
96  * Extracts value from try and returns it. Throws if try contained an exception.
97  */
98 template <typename T>
99 T moveFromTry(wangle::Try<T>&& t);
100
101 /**
102  * Throws if try contained an exception.
103  */
104 void moveFromTry(wangle::Try<void>&& t);
105
106 /**
107  * Constructs Try based on the result of execution of function f (e.g. result
108  * or exception).
109  */
110 template <typename F>
111 typename std::enable_if<
112   !std::is_same<typename std::result_of<F()>::type, void>::value,
113   Try<typename std::result_of<F()>::type>>::type
114 makeTryFunction(F&& f);
115
116 /**
117  * makeTryFunction specialization for void functions.
118  */
119 template <typename F>
120 typename std::enable_if<
121   std::is_same<typename std::result_of<F()>::type, void>::value,
122   Try<void>>::type
123 makeTryFunction(F&& f);
124
125
126 }}
127
128 #include <folly/wangle/Try-inl.h>